From 0161f77c5d10f1a4c2f669951f6932a50f7e1140 Mon Sep 17 00:00:00 2001 From: zreszela Date: Tue, 4 Apr 2017 15:59:14 +0200 Subject: [PATCH] Apply autopep8 (first time, all default) Apply command: autopep8 -ir src test doc scripts sandbox sardanaConfig setup.py Reduce flake8 errors from 21106 to 4160. --- doc/buildmock.py | 69 +- doc/source/conf.py | 85 +- .../devel/examples/ControllerTemplate.py | 250 ++-- .../devel/howto_controllers/sf_ct_ctrl.py | 58 +- .../devel/howto_controllers/sf_motor_ctrl.py | 98 +- .../devel/howto_controllers/sf_tg_ctrl.py | 44 +- .../devel/howto_controllers/springfieldlib.py | 160 +-- .../sphinxext/ipython_console_highlighting.py | 45 +- doc/source/sphinxext/sardanaextension.py | 93 +- .../sphinxext/spock_console_highlighting.py | 45 +- sandbox/mntgrp_gui | 7 +- sandbox/mntgrp_gui.py | 294 +++-- sandbox/motgrp_gui | 114 +- sandbox/pool_gui | 117 +- sardanaConfig/doc/source/conf.py | 15 +- .../src/wizards/add_device_wizard.py | 266 ++-- sardanaConfig/src/wizards/add_new_hw.py | 6 +- sardanaConfig/src/wizards/ms_editor_UI.py | 75 +- .../src/wizards/new_sardana_wizard.py | 689 +++++++---- sardanaConfig/src/wizards/pool_editor_UI.py | 51 +- sardanaConfig/src/wizards/pool_page.py | 81 +- sardanaConfig/src/wizards/sardana_page.py | 61 +- sardanaConfig/src/wizards/settings_widget.py | 633 +++++----- .../src/wizards/simple_tree_model.py | 53 +- sardanaConfig/src/wizards/tango_host_page.py | 42 +- sardanaConfig/src/wizards/wiz.py | 51 +- scripts/h5toascii | 118 +- scripts/h5tospec | 178 +-- scripts/spectoascii | 66 +- scripts/upgrade/from_01_to_02.py | 325 +++-- scripts/upgrade/from_02_to_03.py | 234 ++-- scripts/upgrade/upgradeCLI.py | 32 +- scripts/upgrade/upgradeGUI.py | 176 +-- scripts/upgrade/upgrade_sardana.py | 4 +- scripts/upgrade/upgrade_utils.py | 76 +- setup.py | 64 +- src/sardana/__init__.py | 37 +- src/sardana/macroserver/__init__.py | 34 +- src/sardana/macroserver/basetypes.py | 77 +- src/sardana/macroserver/macro.py | 159 +-- src/sardana/macroserver/macros/__init__.py | 34 +- .../macroserver/macros/communication.py | 57 +- src/sardana/macroserver/macros/demo.py | 99 +- src/sardana/macroserver/macros/env.py | 99 +- .../macroserver/macros/examples/__init__.py | 33 +- .../macroserver/macros/examples/debug.py | 36 +- .../macroserver/macros/examples/funcs.py | 52 +- .../macroserver/macros/examples/hooks.py | 128 +- .../macroserver/macros/examples/motion.py | 28 +- .../macroserver/macros/examples/parameters.py | 204 +-- .../macroserver/macros/examples/plotting.py | 21 +- .../macroserver/macros/examples/scans.py | 486 ++++---- .../macros/examples/specific_experiments.py | 131 +- .../macroserver/macros/examples/submacros.py | 75 +- .../macroserver/macros/examples/user_input.py | 39 +- src/sardana/macroserver/macros/expert.py | 162 +-- src/sardana/macroserver/macros/hkl.py | 53 +- src/sardana/macroserver/macros/ioregister.py | 53 +- src/sardana/macroserver/macros/lists.py | 114 +- src/sardana/macroserver/macros/mca.py | 50 +- src/sardana/macroserver/macros/scan.py | 1101 +++++++++-------- src/sardana/macroserver/macros/sequence.py | 51 +- src/sardana/macroserver/macros/standard.py | 274 ++-- .../macroserver/macros/test/__init__.py | 26 +- src/sardana/macroserver/macros/test/base.py | 52 +- .../macroserver/macros/test/macroexecutor.py | 33 +- .../macroserver/macros/test/sardemoenv.py | 38 +- .../macroserver/macros/test/test_ascanct.py | 82 +- .../macroserver/macros/test/test_ct.py | 26 +- .../macroserver/macros/test/test_env.py | 31 +- .../macroserver/macros/test/test_expert.py | 33 +- .../macros/test/test_ioregister.py | 29 +- .../macroserver/macros/test/test_list.py | 28 +- .../macroserver/macros/test/test_scan.py | 37 +- .../macroserver/macros/test/test_standard.py | 30 +- .../macroserver/macros/test/test_wm.py | 29 +- src/sardana/macroserver/macroserver.py | 395 +++--- src/sardana/macroserver/msbase.py | 28 +- src/sardana/macroserver/mscontainer.py | 26 +- src/sardana/macroserver/msdoor.py | 40 +- src/sardana/macroserver/msenvmanager.py | 26 +- src/sardana/macroserver/msexception.py | 26 +- src/sardana/macroserver/msmacromanager.py | 167 +-- src/sardana/macroserver/msmanager.py | 26 +- src/sardana/macroserver/msmetamacro.py | 32 +- src/sardana/macroserver/msmetarecorder.py | 26 +- src/sardana/macroserver/msoptions.py | 34 +- src/sardana/macroserver/msparameter.py | 36 +- src/sardana/macroserver/msrecordermanager.py | 28 +- src/sardana/macroserver/mstypemanager.py | 28 +- src/sardana/macroserver/recorders/__init__.py | 34 +- .../recorders/examples/__init__.py | 32 +- .../macroserver/recorders/examples/dummy.py | 29 +- .../macroserver/recorders/examples/xas.py | 249 ++-- src/sardana/macroserver/recorders/output.py | 46 +- .../macroserver/recorders/sharedmemory.py | 154 +-- src/sardana/macroserver/recorders/storage.py | 562 +++++---- src/sardana/macroserver/scan/__init__.py | 34 +- src/sardana/macroserver/scan/gscan.py | 354 +++--- .../macroserver/scan/recorder/__init__.py | 34 +- .../macroserver/scan/recorder/datarecorder.py | 32 +- .../macroserver/scan/recorder/sharedmemory.py | 29 +- .../macroserver/scan/recorder/storage.py | 185 +-- src/sardana/macroserver/scan/scandata.py | 53 +- src/sardana/macroserver/scan/test/__init__.py | 26 +- src/sardana/macroserver/scan/test/helper.py | 29 +- .../macroserver/scan/test/test_gscan.py | 30 +- .../macroserver/scan/test/test_recorddata.py | 75 +- src/sardana/macroserver/test/__init__.py | 32 +- src/sardana/macroserver/test/res/__init__.py | 32 +- .../macroserver/test/res/fakerecorders.py | 33 +- .../test/res/recorders/path1/fakerecorders.py | 34 +- .../test/res/recorders/path2/fakerecorders.py | 34 +- .../test/res/recorders/path3/fakerecorders.py | 34 +- .../recorders/pathexternal/specrecorder.py | 33 +- .../macroserver/test/test_msparameter.py | 6 +- .../test/test_msrecordermanager.py | 38 +- src/sardana/pool/__init__.py | 32 +- src/sardana/pool/controller.py | 196 +-- src/sardana/pool/pool.py | 72 +- src/sardana/pool/poolacquisition.py | 86 +- src/sardana/pool/poolaction.py | 32 +- src/sardana/pool/poolbasechannel.py | 31 +- src/sardana/pool/poolbaseelement.py | 41 +- src/sardana/pool/poolbasegroup.py | 67 +- src/sardana/pool/poolbaseobject.py | 43 +- src/sardana/pool/poolcontainer.py | 42 +- src/sardana/pool/poolcontroller.py | 100 +- src/sardana/pool/poolcontrollermanager.py | 94 +- .../DiscretePseudoMotorController.py | 133 +- .../DummyCounterTimerController.py | 117 +- .../poolcontrollers/DummyIORController.py | 40 +- .../poolcontrollers/DummyMotorController.py | 198 +-- .../poolcontrollers/DummyOneDController.py | 129 +- .../DummyTriggerGateController.py | 29 +- .../poolcontrollers/DummyTwoDController.py | 129 +- .../poolcontrollers/DummyZeroDController.py | 61 +- .../HklPseudoMotorController.py | 198 +-- src/sardana/pool/poolcontrollers/IoverI0.py | 40 +- src/sardana/pool/poolcontrollers/Slit.py | 79 +- .../pool/poolcontrollers/TangoController.py | 47 +- src/sardana/pool/poolcontrollers/__init__.py | 34 +- .../pool/poolcontrollers/test/__init__.py | 2 +- src/sardana/pool/poolcontrollers/test/base.py | 51 +- .../test/test_DummyCounterTimerController.py | 27 +- .../test/test_DummyTriggerGateController.py | 9 +- src/sardana/pool/poolcountertimer.py | 26 +- src/sardana/pool/pooldefs.py | 39 +- src/sardana/pool/poolelement.py | 26 +- src/sardana/pool/poolexception.py | 26 +- src/sardana/pool/poolextension.py | 30 +- src/sardana/pool/poolexternal.py | 31 +- src/sardana/pool/poolgroupelement.py | 26 +- src/sardana/pool/poolinstrument.py | 28 +- src/sardana/pool/poolioregister.py | 26 +- src/sardana/pool/poolmeasurementgroup.py | 86 +- src/sardana/pool/poolmetacontroller.py | 93 +- src/sardana/pool/poolmonitor.py | 26 +- src/sardana/pool/poolmotion.py | 76 +- src/sardana/pool/poolmotor.py | 58 +- src/sardana/pool/poolmotorgroup.py | 46 +- src/sardana/pool/poolmoveable.py | 26 +- src/sardana/pool/poolobject.py | 26 +- src/sardana/pool/poolonedexpchannel.py | 26 +- src/sardana/pool/poolpseudocounter.py | 41 +- src/sardana/pool/poolpseudomotor.py | 70 +- src/sardana/pool/poolsynchronization.py | 39 +- src/sardana/pool/pooltriggergate.py | 28 +- src/sardana/pool/pooltwodexpchannel.py | 32 +- src/sardana/pool/poolutil.py | 26 +- src/sardana/pool/poolzerodexpchannel.py | 51 +- src/sardana/pool/test/__init__.py | 26 +- src/sardana/pool/test/base.py | 43 +- src/sardana/pool/test/dummyconfs.py | 295 +++-- src/sardana/pool/test/fake.py | 36 +- src/sardana/pool/test/helper.py | 148 +-- src/sardana/pool/test/test_acquisition.py | 76 +- src/sardana/pool/test/test_ctacquisition.py | 32 +- .../pool/test/test_measurementgroup.py | 121 +- src/sardana/pool/test/test_poolcontroller.py | 27 +- .../pool/test/test_poolcontrollermanager.py | 29 +- .../pool/test/test_poolcountertimer.py | 29 +- .../pool/test/test_poolsynchronization.py | 47 +- src/sardana/pool/test/test_synchronization.py | 62 +- src/sardana/release.py | 42 +- src/sardana/requirements.py | 38 +- src/sardana/sardanaattribute.py | 40 +- src/sardana/sardanabase.py | 58 +- src/sardana/sardanacontainer.py | 79 +- src/sardana/sardanacustomsettings.py | 40 +- src/sardana/sardanadefs.py | 269 ++-- src/sardana/sardanaevent.py | 36 +- src/sardana/sardanaexception.py | 32 +- src/sardana/sardanalock.py | 26 +- src/sardana/sardanamanager.py | 63 +- src/sardana/sardanameta.py | 50 +- src/sardana/sardanamodulemanager.py | 49 +- src/sardana/sardanathreadpool.py | 28 +- src/sardana/sardanautils.py | 75 +- src/sardana/sardanavalue.py | 26 +- src/sardana/spock/__init__.py | 35 +- src/sardana/spock/colors.py | 36 +- src/sardana/spock/config.py | 37 +- src/sardana/spock/exception.py | 37 +- src/sardana/spock/genutils.py | 39 +- src/sardana/spock/inputhandler.py | 48 +- src/sardana/spock/ipython_00_10/__init__.py | 34 +- src/sardana/spock/ipython_00_10/genutils.py | 447 ++++--- src/sardana/spock/ipython_00_11/__init__.py | 34 +- src/sardana/spock/ipython_00_11/genutils.py | 269 ++-- src/sardana/spock/ipython_01_00/__init__.py | 34 +- src/sardana/spock/ipython_01_00/genutils.py | 285 +++-- src/sardana/spock/magic.py | 49 +- src/sardana/spock/parameter.py | 129 +- src/sardana/spock/parser.py | 35 +- src/sardana/spock/release.py | 46 +- src/sardana/spock/spockms.py | 90 +- src/sardana/spock/test/__init__.py | 26 +- src/sardana/spock/test/test_parameter.py | 26 +- src/sardana/spock/test/test_parser.py | 27 +- src/sardana/tango/__init__.py | 35 +- src/sardana/tango/core/SardanaDevice.py | 68 +- src/sardana/tango/core/__init__.py | 80 +- src/sardana/tango/core/attributehandler.py | 26 +- src/sardana/tango/core/util.py | 284 +++-- src/sardana/tango/macroserver/Door.py | 261 ++-- src/sardana/tango/macroserver/MacroServer.py | 268 ++-- src/sardana/tango/macroserver/__init__.py | 39 +- .../tango/macroserver/test/__init__.py | 26 +- src/sardana/tango/macroserver/test/base.py | 33 +- .../tango/macroserver/test/macroexecutor.py | 36 +- src/sardana/tango/pool/CTExpChannel.py | 44 +- src/sardana/tango/pool/Controller.py | 72 +- src/sardana/tango/pool/IORegister.py | 44 +- src/sardana/tango/pool/MeasurementGroup.py | 88 +- src/sardana/tango/pool/Motor.py | 145 +-- src/sardana/tango/pool/MotorGroup.py | 30 +- src/sardana/tango/pool/OneDExpChannel.py | 45 +- src/sardana/tango/pool/Pool.py | 375 +++--- src/sardana/tango/pool/PoolDevice.py | 151 +-- src/sardana/tango/pool/PseudoCounter.py | 38 +- src/sardana/tango/pool/PseudoMotor.py | 57 +- src/sardana/tango/pool/TriggerGate.py | 36 +- src/sardana/tango/pool/TwoDExpChannel.py | 46 +- src/sardana/tango/pool/ZeroDExpChannel.py | 56 +- src/sardana/tango/pool/__init__.py | 33 +- src/sardana/tango/pool/test/__init__.py | 26 +- src/sardana/tango/pool/test/base.py | 50 +- src/sardana/tango/pool/test/base_sartest.py | 70 +- src/sardana/tango/pool/test/test_Motor.py | 30 +- .../tango/pool/test/test_measurementgroup.py | 69 +- .../tango/pool/test/test_persistence.py | 42 +- src/sardana/taurus/__init__.py | 26 +- src/sardana/taurus/core/__init__.py | 28 +- src/sardana/taurus/core/tango/__init__.py | 28 +- .../taurus/core/tango/sardana/__init__.py | 27 +- .../taurus/core/tango/sardana/macro.py | 156 +-- .../taurus/core/tango/sardana/macroserver.py | 169 +-- .../taurus/core/tango/sardana/motion.py | 132 +- src/sardana/taurus/core/tango/sardana/pool.py | 137 +- .../taurus/core/tango/sardana/sardana.py | 153 ++- .../core/tango/sardana/test/__init__.py | 26 +- .../core/tango/sardana/test/paramdef.py | 81 +- .../core/tango/sardana/test/test_macro.py | 67 +- src/sardana/taurus/qt/__init__.py | 28 +- src/sardana/taurus/qt/qtcore/__init__.py | 28 +- .../taurus/qt/qtcore/tango/__init__.py | 28 +- .../qt/qtcore/tango/sardana/__init__.py | 26 +- .../qt/qtcore/tango/sardana/macroserver.py | 49 +- .../taurus/qt/qtcore/tango/sardana/model.py | 80 +- .../taurus/qt/qtcore/tango/sardana/pool.py | 28 +- src/sardana/taurus/qt/qtgui/__init__.py | 28 +- .../taurus/qt/qtgui/extra_hkl/__init__.py | 26 +- .../taurus/qt/qtgui/extra_hkl/computeu.py | 26 +- .../extra_hkl/diffractometeralignment.py | 28 +- .../qt/qtgui/extra_hkl/displayscanangles.py | 26 +- .../taurus/qt/qtgui/extra_hkl/hklscan.py | 30 +- .../qt/qtgui/extra_hkl/reflectionseditor.py | 26 +- .../qt/qtgui/extra_hkl/reflectionslist.py | 26 +- .../taurus/qt/qtgui/extra_hkl/selectsignal.py | 29 +- .../taurus/qt/qtgui/extra_hkl/ubmatrix.py | 44 +- .../qt/qtgui/extra_macroexecutor/__init__.py | 26 +- .../qt/qtgui/extra_macroexecutor/common.py | 109 +- .../qtgui/extra_macroexecutor/dooroutput.py | 50 +- .../favouriteseditor/__init__.py | 26 +- .../favouriteseditor/favouriteseditor.py | 88 +- .../favouriteseditor/historyviewer.py | 57 +- .../favouriteseditor/model.py | 26 +- .../qt/qtgui/extra_macroexecutor/globals.py | 26 +- .../qtgui/extra_macroexecutor/macrobutton.py | 148 ++- .../macrodescriptionviewer.py | 41 +- .../qtgui/extra_macroexecutor/macroeditor.py | 75 +- .../extra_macroexecutor/macroexecutor.py | 312 +++-- .../macroparameterseditor/__init__.py | 26 +- .../customeditors/__init__.py | 26 +- .../customeditors/senv.py | 120 +- .../macroparameterseditor/delegate.py | 37 +- .../macroparameterseditor.py | 87 +- .../macroparameterseditor/model.py | 52 +- .../macroparameterseditor/parameditors.py | 68 +- .../qtgui/extra_macroexecutor/scanplotter.py | 51 +- .../sequenceeditor/__init__.py | 26 +- .../sequenceeditor/delegate.py | 41 +- .../sequenceeditor/model.py | 55 +- .../sequenceeditor/sequenceeditor.py | 255 ++-- .../taurus/qt/qtgui/extra_pool/__init__.py | 26 +- .../taurus/qt/qtgui/extra_pool/motor.py | 59 +- .../taurus/qt/qtgui/extra_pool/poolchannel.py | 63 +- .../qt/qtgui/extra_pool/poolioregister.py | 86 +- .../taurus/qt/qtgui/extra_pool/poolmotor.py | 568 +++++---- .../taurus/qt/qtgui/extra_sardana/__init__.py | 28 +- .../taurus/qt/qtgui/extra_sardana/cmdline.py | 35 +- .../qt/qtgui/extra_sardana/controllertree.py | 101 +- .../qt/qtgui/extra_sardana/elementtree.py | 40 +- .../qt/qtgui/extra_sardana/environment.py | 42 +- .../qt/qtgui/extra_sardana/expdescription.py | 231 ++-- .../qt/qtgui/extra_sardana/macrotree.py | 80 +- .../qtgui/extra_sardana/measurementgroup.py | 343 ++--- .../qtgui/extra_sardana/sardanabasewizard.py | 27 +- .../qt/qtgui/extra_sardana/sardanaeditor.py | 180 +-- .../taurus/qt/qtgui/extra_sardana/startup.py | 35 +- .../qt/qtgui/extra_sardana/ui/__init__.py | 26 +- src/sardana/test/__init__.py | 26 +- src/sardana/test/test_sardanavalue.py | 26 +- src/sardana/test/testsuite.py | 31 +- src/sardana/tools/config/fods_to_sar.py | 10 +- src/sardana/tools/config/get_pool_config.py | 234 ++-- src/sardana/tools/config/pexpect23.py | 479 ++++--- src/sardana/tools/config/sar_to_fods.py | 5 +- src/sardana/tools/config/sardana.py | 409 +++--- src/sardana/tools/config/to_sar.py | 11 +- src/sardana/tools/config/xls_to_sar.py | 8 +- src/sardana/util/__init__.py | 35 +- src/sardana/util/deepreload.py | 63 +- src/sardana/util/funcgenerator.py | 38 +- src/sardana/util/motion/__init__.py | 32 +- src/sardana/util/motion/motion.py | 83 +- src/sardana/util/test/test_funcgenerator.py | 54 +- src/sardana/util/test/test_thread.py | 28 +- src/sardana/util/thread.py | 27 +- src/sardana/util/tree.py | 12 +- src/sardana/util/wrap.py | 31 +- test/HTMLTestRunner.py | 162 ++- test/go.py | 15 +- test/pool.py | 684 +++++----- test/poolunittest.py | 731 +++++------ test/test_ctrl/ElecMeter.py | 82 +- test/test_ctrl/ElecMeter_init.py | 86 +- test/test_ctrl/ElecMeter_syn.py | 82 +- test/test_ctrl/FirePapCtrl.py | 113 +- test/test_ctrl/Vct6Ctrl.py | 132 +- test/test_ctrl/Vct6Ctrl_init.py | 100 +- test/test_ctrl/Vct6Ctrl_syn.py | 90 +- test/test_ctrl/WaterPapCtrl.py | 134 +- test/test_ctrl/WaterPapCtrl_init.py | 114 +- test/test_ctrl/WaterPapCtrl_mis.py | 109 +- test/test_ctrl/WaterPapCtrl_mis_extra.py | 118 +- test/test_ctrl/WaterPapCtrl_mis_feat.py | 124 +- test/test_ctrl/WaterPapCtrl_prop.py | 94 +- test/test_ctrl/WaterPapCtrl_stat1.py | 114 +- test/test_ctrl/WaterPapCtrl_stat2.py | 114 +- test/test_ctrl/WaterPapCtrl_syn.py | 115 +- 362 files changed, 17367 insertions(+), 14644 deletions(-) diff --git a/doc/buildmock.py b/doc/buildmock.py index 48327b473a..84a029bcef 100644 --- a/doc/buildmock.py +++ b/doc/buildmock.py @@ -3,24 +3,24 @@ ############################################################################# ## -## This file is part of Taurus +# This file is part of Taurus ## -## http://taurus-scada.org +# http://taurus-scada.org ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Taurus is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Taurus is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Taurus is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Taurus is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Taurus. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Taurus. If not, see . ## ########################################################################### @@ -105,10 +105,12 @@ def abspath(*path): this_dir = os.path.dirname(os.path.abspath(__file__)) return os.path.abspath(os.path.join(this_dir, *path)) + def _import(name): __import__(name) return sys.modules[name] + def _is_pseudo_enum(obj): if not isinstance(obj, int): return False @@ -118,16 +120,19 @@ def _is_pseudo_enum(obj): except: return True + def _is_special_float(obj): if not isinstance(obj, float): return False return repr(obj) in ('inf', 'nan', '-inf') + def _discard_element(name, exclude, include): if name in include: return False return name in exclude or name.startswith("__") + def build_class(k_name, k, exclude=(), include=()): '''return the source text for a mock class based on a given class''' methods = [] @@ -144,9 +149,9 @@ def build_class(k_name, k, exclude=(), include=()): members.append(specialfloats_template.format(name=element_name, value=element)) elif isinstance(element, (int, float, bool, str, unicode)): - try: # make sure that the repr makes sense + try: # make sure that the repr makes sense type(element)(repr(element)) - except: # skip it (the _Mock.__getattr__ will deal with it) + except: # skip it (the _Mock.__getattr__ will deal with it) continue members.append(member_template.format(name=element_name, value=element)) @@ -157,6 +162,7 @@ def build_class(k_name, k, exclude=(), include=()): members=members) return klass_str + def build_module(module_name, imports=(), out_prefix='mock', exclude=(), include=()): '''generate a mock package for a given module''' @@ -178,7 +184,7 @@ def build_module(module_name, imports=(), out_prefix='mock', element = getattr(module, element_name) # internal imports (from the same package) if (inspect.ismodule(element) and - element.__name__.split('.')[0] == module_name.split('.')[0]): + element.__name__.split('.')[0] == module_name.split('.')[0]): # add the module to the imports set full_name = element.__name__ name = full_name.split('.')[-1] @@ -197,7 +203,7 @@ def build_module(module_name, imports=(), out_prefix='mock', # was not working due to the metaclass problems # TODO: when moving back this utils to taurus check if the circular # import errors are still present - #mocks.append(mock_template.format(name=element_name)) + # mocks.append(mock_template.format(name=element_name)) # make sure that the module is built build_module(element.__name__, imports=(), @@ -216,7 +222,7 @@ def build_module(module_name, imports=(), out_prefix='mock', constants.append(mock_template.format(name=element_name)) # constants elif isinstance(element, (int, float, bool, str, unicode)): - try: # make sure that the repr makes sense + try: # make sure that the repr makes sense type(element)(repr(element)) except: # cannot write anything better than a mock constants.append(mock_template.format(name=element_name)) @@ -227,7 +233,6 @@ def build_module(module_name, imports=(), out_prefix='mock', elif (element_name not in imports): mocks.append(mock_template.format(name=element_name)) - imports = "\n".join(sorted(imports)) module_init = module_init_template.format(imports=imports) @@ -244,6 +249,7 @@ def build_module(module_name, imports=(), out_prefix='mock', f.write(klasses) f.write("\n\n") + def guess_submodules_from_package(module_name, exclude=(), include=()): '''returns a list of submodule names found in a given package name. If module_name is not implemented as a package, it returns an empty list''' @@ -255,7 +261,7 @@ def guess_submodules_from_package(module_name, exclude=(), include=()): except TypeError: return [] if not (modulefile.endswith('__init__.py') or - modulefile.endswith('__init__.pyc') ): + modulefile.endswith('__init__.pyc')): return [] pkgdir, _ = os.path.split(modulefile) @@ -271,13 +277,14 @@ def guess_submodules_from_package(module_name, exclude=(), include=()): # explore pkgdir to find .so files g = glob.glob(os.path.join(pkgdir, '*.so')) names += [re.findall(r".+\/(.*).so", s)[0] for s in g] - # build list with full module names and filter out non-importable submodules + # build list with full module names and filter out non-importable + # submodules full_module_names = [] for sm_name in names: name = '.'.join((module_name, sm_name)) # skip __main__ and __init__, etc and excluded (unless included) - if ( name not in include and - (name in exclude or sm_name.startswith('__')) ): + if (name not in include and + (name in exclude or sm_name.startswith('__'))): continue # check if the module is indeed importable try: @@ -289,6 +296,7 @@ def guess_submodules_from_package(module_name, exclude=(), include=()): pass return full_module_names + def build_full_module(module_name, exclude=(), include=(), out_prefix='mock'): '''build a full mocked package (modules and submodules, recursively) for the given module''' @@ -300,11 +308,12 @@ def build_full_module(module_name, exclude=(), include=(), out_prefix='mock'): build_module(module_name, imports=(), exclude=exclude, include=include, out_prefix=out_prefix) - #recursive call for submodules + # recursive call for submodules for name in guess_submodules_from_package(module_name, exclude=exclude): build_full_module(name, exclude=exclude, include=include, out_prefix=out_prefix) + def _zipdir(basedir, archivename): '''function to zip directories. Adapted from: http://stackoverflow.com/questions/296499 @@ -314,12 +323,13 @@ def _zipdir(basedir, archivename): assert os.path.isdir(basedir) with closing(ZipFile(archivename, "w", ZIP_DEFLATED)) as z: for root, dirs, files in os.walk(basedir): - #NOTE: ignore empty directories + # NOTE: ignore empty directories for fn in files: absfn = os.path.join(root, fn) - zfn = absfn[len(basedir)+len(os.sep):] #XXX: relative path + zfn = absfn[len(basedir) + len(os.sep):] # XXX: relative path z.write(absfn, zfn) + def build_mocks_for_sardana(output='mock.zip'): '''builds mocks for the packages required by taurus. The mocks are written into the given output directory (or a zip file if output ends with ".zip") @@ -350,11 +360,10 @@ def build_mocks_for_sardana(output='mock.zip'): build_full_module(module_name, exclude=exclude, include=include, out_prefix=outdir) if zfile: - _zipdir(outdir, zfile) # compress the dir into the zip file - shutil.rmtree(outdir) # delete the dir + _zipdir(outdir, zfile) # compress the dir into the zip file + shutil.rmtree(outdir) # delete the dir print '\nMocks written in %s' % output - if __name__ == "__main__": - build_mocks_for_sardana() \ No newline at end of file + build_mocks_for_sardana() diff --git a/doc/source/conf.py b/doc/source/conf.py index 2c79e3d6ca..a7b6dcdd0c 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,8 +29,8 @@ # declare some useful absolute paths _this_dir = os.path.dirname(os.path.abspath(__file__)) -_setup_dir = os.path.abspath(os.path.join(_this_dir, os.path.pardir, - os.path.pardir)) +_setup_dir = os.path.abspath(os.path.join(_this_dir, os.path.pardir, + os.path.pardir)) _src_dir = os.path.join(_setup_dir, 'src') _mock_path = os.path.join(_setup_dir, 'doc', 'mock.zip') # append mock dir to the sys path (mocks will be used if needed) @@ -49,6 +49,7 @@ # otherwise the mocked version of the decorator returns mock objects, # this is causing problems with inheritance diagrams import taurus.test + def insertTest(klass, *args, **kwargs): return klass taurus.test.insertTest = insertTest @@ -58,6 +59,8 @@ def insertTest(klass, *args, **kwargs): import sardana # TODO: check if it is still necessary to fix_sardana_for_doc + + def fix_sardana_for_doc(): def type_getattr(self, name): @@ -75,7 +78,7 @@ def type_getattr(self, name): # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.append(os.path.abspath('sphinxext')) -# -- General configuration ----------------------------------------------------- +# -- General configuration ----------------------------------------------- #autosummary_generate = True @@ -93,14 +96,14 @@ def type_getattr(self, name): 'sardanaextension', 'ipython_console_highlighting', 'spock_console_highlighting', -] + ] try: import rst2pdf.pdfbuilder extensions.append('rst2pdf.pdfbuilder') except: pass - + # Add any paths that contain templates here, relative to this directory. #templates_path = ['_templates'] @@ -119,7 +122,8 @@ def type_getattr(self, name): copyright = u"""Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution 3.0 License""" -#Ideally we would like to put the following html code for copyright... but how? +# Ideally we would like to put the following html code for copyright... +# but how? '''Creative Commons License
Taurus Documentation by CELLS - ALBA is licensed under a Creative Commons Attribution-Share Alike 3.0 Spain License.''' # The version info for the project you're documenting, acts as replacement for @@ -170,7 +174,7 @@ def type_getattr(self, name): #modindex_common_prefix = [] -# -- Options for HTML output --------------------------------------------------- +# -- Options for HTML output --------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. @@ -196,7 +200,7 @@ def type_getattr(self, name): # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = os.path.join(os.pardir,os.pardir,"logo.png") +html_logo = os.path.join(os.pardir, os.pardir, "logo.png") # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -247,7 +251,7 @@ def type_getattr(self, name): htmlhelp_basename = 'sardanadoc' -# -- Options for LaTeX output -------------------------------------------------- +# -- Options for LaTeX output -------------------------------------------- # The paper size ('letter' or 'a4'). latex_paper_size = 'a4' @@ -258,8 +262,8 @@ def type_getattr(self, name): # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'sardana.tex', u'Sardana Documentation', - u'Sardana team', 'manual'), + ('index', 'sardana.tex', u'Sardana Documentation', + u'Sardana team', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -288,30 +292,29 @@ def type_getattr(self, name): autodoc_member_order = "bysource" -# -- Options for Graphviz ----------------------------------------------------- +# -- Options for Graphviz ----------------------------------------------- -inheritance_node_attrs = dict(shape='box', fontcolor='black', +inheritance_node_attrs = dict(shape='box', fontcolor='black', height=0.4, color='brown', style='rounded') inheritance_graph_attrs = dict(rankdir="UD", ratio='compress') -graphviz_output_format = 'png' # 'svg' +graphviz_output_format = 'png' # 'svg' -#inheritance_graph_attrs = dict(rankdir="LR", size='"6.0, 8.0"', +# inheritance_graph_attrs = dict(rankdir="LR", size='"6.0, 8.0"', # fontsize=14, ratio='compress') -# -- Options for reference to other documentation ------------------------------ +# -- Options for reference to other documentation ------------------------ intersphinx_mapping = { 'http://docs.python.org/dev': None, - 'http://docs.scipy.org/doc/scipy/reference' : None, - 'http://docs.scipy.org/doc/numpy' : None, - 'http://ipython.org/ipython-doc/stable/' : None, + 'http://docs.scipy.org/doc/scipy/reference': None, + 'http://docs.scipy.org/doc/numpy': None, + 'http://ipython.org/ipython-doc/stable/': None, 'http://www.esrf.fr/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/': None, - 'http://www.taurus-scada.org' : None, - 'http://pyqt.sourceforge.net/Docs/PyQt4/' : None, - 'http://matplotlib.sourceforge.net/' : None, - 'http://packages.python.org/guiqwt/' : None, + 'http://www.taurus-scada.org': None, + 'http://pyqt.sourceforge.net/Docs/PyQt4/': None, + 'http://matplotlib.sourceforge.net/': None, + 'http://packages.python.org/guiqwt/': None, } - diff --git a/doc/source/devel/examples/ControllerTemplate.py b/doc/source/devel/examples/ControllerTemplate.py index bb072c0b5c..c9eb06973e 100644 --- a/doc/source/devel/examples/ControllerTemplate.py +++ b/doc/source/devel/examples/ControllerTemplate.py @@ -12,176 +12,184 @@ """ __author__ = "Carlos Falcon - cfalcon@cells.es" + class ControllerTemplate(): - def __init__(self,f, e=""): + + def __init__(self, f, e=""): self.filename = f self.end = e - self.ind = 'ind' + self.ind = 'ind' # pass + def addHead(self): - f=open(self.filename,"w") - f.write('##############################################################################\n'+\ - '##\n'+\ - '## This file is part of Sardana\n'+\ - '##\n'+\ - '## http://www.sardana-controls.org/\n'+\ - '##\n'+\ - '## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain\n'+\ - '##\n'+\ - '## Sardana is free software: you can redistribute it and/or modify\n'+\ - '## it under the terms of the GNU Lesser General Public License as published by\n'+\ - '## the Free Software Foundation, either version 3 of the License, or\n'+\ - '## (at your option) any later version.\n'+\ - '##\n'+\ - '## Sardana is distributed in the hope that it will be useful,\n'+\ - '## but WITHOUT ANY WARRANTY; without even the implied warranty of\n'+\ - '## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n'+\ - '## GNU Lesser General Public License for more details.\n'+\ - '##\n'+\ - '## You should have received a copy of the GNU Lesser General Public License\n'+\ - '## along with Sardana. If not, see .\n'+\ - '##\\n'+\ + f = open(self.filename, "w") + f.write('##############################################################################\n' + + '##\n' + + '## This file is part of Sardana\n' + + '##\n' + + '## http://www.sardana-controls.org/\n' + + '##\n' + + '## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain\n' + + '##\n' + + '## Sardana is free software: you can redistribute it and/or modify\n' + + '## it under the terms of the GNU Lesser General Public License as published by\n' + + '## the Free Software Foundation, either version 3 of the License, or\n' + + '## (at your option) any later version.\n' + + '##\n' + + '## Sardana is distributed in the hope that it will be useful,\n' + + '## but WITHOUT ANY WARRANTY; without even the implied warranty of\n' + + '## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n' + + '## GNU Lesser General Public License for more details.\n' + + '##\n' + + '## You should have received a copy of the GNU Lesser General Public License\n' + + '## along with Sardana. If not, see .\n' + + '##\\n' + '##############################################################################\n\n')\ - def addIncludes(self,inherit,others=None): - f = open(self.filename,"a") + + def addIncludes(self, inherit, others=None): + f = open(self.filename, "a") text = "from sardana import State\n" - if inherit!="": - text = text+"from sardana.pool.controller import "+inherit+"\n" - if inherit.find("Motor")>=0: + if inherit != "": + text = text + "from sardana.pool.controller import " + inherit + "\n" + if inherit.find("Motor") >= 0: self.ind = 'axis' if others is not None: - text = text+others - text = text+"#ADD others includes\n\n" + text = text + others + text = text + "#ADD others includes\n\n" f.write(text) - #f.close() + # f.close() def createBasicClass(self): - f = open(self.filename,"a") + f = open(self.filename, "a") text = "#TODO - Delete it if you don't need\n" - text = text +'class BasicClass():\n'+\ - '\tpass\n\n' + text = text + 'class BasicClass():\n' +\ + '\tpass\n\n' f.write(text) - def createMainClass(self,inherit): - f = open(self.filename,"a") - text = "class "+self.filename[0:len(self.filename)-3]+"("+inherit+"):\n"+\ - '\t"""Description""" #TODO\n'+\ - '\tgender = "Simulation"\n'+\ - '\tmodel = "Basic"\n'+\ - '\torganization = "CELLS - ALBA"\n'+\ - '\timage = "IMAGE.png"\n'+\ - '\tlogo = "ALBA_logo.png"\n\n'+\ - '\t#TODO - Delete it if you don\'t need\n'+\ - '\tctrl_properties= { \'AAA\' : { \'Type\' : \'DevString\', \'Description\' : \'AAA\' } }\n'+\ - '\taxis_attributes = { \'AAA\' : { \'type\' : str, \'Description\' : \'AAA\' }}\n\n'+\ - '\tMaxDevice = 1024 #TODO Standar value\n\n' - - fun = '# --------------------------------------------------------------------------\n'+\ - '# Init()\n'+\ - '# --------------------------------------------------------------------------\n'+\ - '\tdef __init__(self, inst, props, *args, **kwargs):\n' - if inherit!="": - fun = fun + '\t\t' + inherit + '.__init__(self, inst, props, *args, **kwargs)\n' + def createMainClass(self, inherit): + f = open(self.filename, "a") + text = "class " + self.filename[0:len(self.filename) - 3] + "(" + inherit + "):\n" +\ + '\t"""Description""" #TODO\n' +\ + '\tgender = "Simulation"\n' +\ + '\tmodel = "Basic"\n' +\ + '\torganization = "CELLS - ALBA"\n' +\ + '\timage = "IMAGE.png"\n' +\ + '\tlogo = "ALBA_logo.png"\n\n' +\ + '\t#TODO - Delete it if you don\'t need\n' +\ + '\tctrl_properties= { \'AAA\' : { \'Type\' : \'DevString\', \'Description\' : \'AAA\' } }\n' +\ + '\taxis_attributes = { \'AAA\' : { \'type\' : str, \'Description\' : \'AAA\' }}\n\n' +\ + '\tMaxDevice = 1024 #TODO Standar value\n\n' + + fun = '# --------------------------------------------------------------------------\n' +\ + '# Init()\n' +\ + '# --------------------------------------------------------------------------\n' +\ + '\tdef __init__(self, inst, props, *args, **kwargs):\n' + if inherit != "": + fun = fun + '\t\t' + inherit + \ + '.__init__(self, inst, props, *args, **kwargs)\n' fun = fun + '\t\t#TODO\n' text = text + fun - - fun = '# --------------------------------------------------------------------------\n'+\ - '# AddDevice/DelDevice()\n'+\ - '# --------------------------------------------------------------------------\n'+\ - '\tdef AddDevice(self,'+self.ind+'):\n' - fun = fun + '\t\t#TODO\n' - fun = fun + '\tdef DeleteDevice(self, '+self.ind+'):\n' - fun = fun + '\t\t#TODO\n' + + fun = '# --------------------------------------------------------------------------\n' +\ + '# AddDevice/DelDevice()\n' +\ + '# --------------------------------------------------------------------------\n' +\ + '\tdef AddDevice(self,' + self.ind + '):\n' + fun = fun + '\t\t#TODO\n' + fun = fun + '\tdef DeleteDevice(self, ' + self.ind + '):\n' + fun = fun + '\t\t#TODO\n' text = text + fun - fun = '# --------------------------------------------------------------------------\n'+\ - '# State()\n'+\ - '# --------------------------------------------------------------------------\n'+\ - '\tdef PreStateOne'+self.end+'(self, '+self.ind+'):\n'+'\t\tpass\n' - fun = fun + '\tdef StateOne(self, '+self.ind+'):\n' + fun = '# --------------------------------------------------------------------------\n' +\ + '# State()\n' +\ + '# --------------------------------------------------------------------------\n' +\ + '\tdef PreStateOne' + self.end + \ + '(self, ' + self.ind + '):\n' + '\t\tpass\n' + fun = fun + '\tdef StateOne(self, ' + self.ind + '):\n' fun = fun + '\t\tstate = State.On\n' fun = fun + '\t\tstatus = "Undefined"\n' - if inherit.find("Motor")>=0: + if inherit.find("Motor") >= 0: fun = fun + '\t\tswitchstate = 0"\n' - fun = fun + '\t\t#TODO\n' + fun = fun + '\t\t#TODO\n' fun = fun + '\t\treturn state, status, switchstate"\n' - else: - fun = fun + '\t\t#TODO\n' + else: + fun = fun + '\t\t#TODO\n' fun = fun + '\t\treturn state, status\n' - fun = fun + '\tdef PreStateAll'+self.end+'(self):\n' - fun = fun + '\t\tpass\n' + fun = fun + '\tdef PreStateAll' + self.end + '(self):\n' + fun = fun + '\t\tpass\n' - fun = fun + '\tdef StateAll'+self.end+'(self):\n' - fun = fun + '\t\tpass\n' + fun = fun + '\tdef StateAll' + self.end + '(self):\n' + fun = fun + '\t\tpass\n' text = text + fun - fun = '# --------------------------------------------------------------------------\n'+\ - '# Read()\n'+\ - '# --------------------------------------------------------------------------\n'+\ - '\tdef PreReadOne'+self.end+'(self, '+self.ind+'):\n'+'\t\tpass\n' - fun = fun + '\tdef ReadOne(self, '+self.ind+'):\n' + fun = '# --------------------------------------------------------------------------\n' +\ + '# Read()\n' +\ + '# --------------------------------------------------------------------------\n' +\ + '\tdef PreReadOne' + self.end + \ + '(self, ' + self.ind + '):\n' + '\t\tpass\n' + fun = fun + '\tdef ReadOne(self, ' + self.ind + '):\n' fun = fun + '\t\t#TODO\n' - fun = fun + '\tdef PreReadAll'+self.end+'(self):\n' - fun = fun + '\t\tpass\n' - fun = fun + '\tdef ReadAll'+self.end+'(self):\n' - fun = fun + '\t\tpass\n' - + fun = fun + '\tdef PreReadAll' + self.end + '(self):\n' + fun = fun + '\t\tpass\n' + fun = fun + '\tdef ReadAll' + self.end + '(self):\n' + fun = fun + '\t\tpass\n' + text = text + fun - fun = '# --------------------------------------------------------------------------\n'+\ - '# Start/Stop()\n'+\ - '# --------------------------------------------------------------------------\n'+\ - '\tdef PreStartOne'+self.end - if inherit.find("Motor")>=0: - fun = fun + '(self, '+self.ind+', pos):\n' + fun = '# --------------------------------------------------------------------------\n' +\ + '# Start/Stop()\n' +\ + '# --------------------------------------------------------------------------\n' +\ + '\tdef PreStartOne' + self.end + if inherit.find("Motor") >= 0: + fun = fun + '(self, ' + self.ind + ', pos):\n' else: - fun = fun + '(self, '+self.ind+'):\n' - fun = fun + '\t\tpass\n' - fun = fun + '\tdef StartOne'+self.end+'(self, '+self.ind+', pos):\n' - fun = fun + '\t\t#TODO\n' + fun = fun + '(self, ' + self.ind + '):\n' + fun = fun + '\t\tpass\n' + fun = fun + '\tdef StartOne' + self.end + \ + '(self, ' + self.ind + ', pos):\n' + fun = fun + '\t\t#TODO\n' - fun = fun + '\tdef AbortOne(self, '+self.ind+'):\n' - fun = fun + '\t\t#TODO\n' + fun = fun + '\tdef AbortOne(self, ' + self.ind + '):\n' + fun = fun + '\t\t#TODO\n' - fun = fun + '\tdef StopOne(self, '+self.ind+'):\n' - fun = fun + '\t\tself.AbortOne('+self.ind+')\n' + fun = fun + '\tdef StopOne(self, ' + self.ind + '):\n' + fun = fun + '\t\tself.AbortOne(' + self.ind + ')\n' - fun = fun + '\tdef PreStartAll'+self.end+'(self):\n' - fun = fun + '\t\tpass\n' + fun = fun + '\tdef PreStartAll' + self.end + '(self):\n' + fun = fun + '\t\tpass\n' - fun = fun + '\tdef StartAll'+self.end+'(self):\n' - fun = fun + '\t\tpass\n' + fun = fun + '\tdef StartAll' + self.end + '(self):\n' + fun = fun + '\t\tpass\n' fun = fun + '\tdef AbortAll(self):\n' - fun = fun + '\t\tpass\n' + fun = fun + '\t\tpass\n' text = text + fun - fun = '# --------------------------------------------------------------------------\n'+\ - '# SetAxisPar/GetAxisPar()\n'+\ - '# --------------------------------------------------------------------------\n'+\ - '\tdef SetAxisPar(self, '+self.ind+', name, value):\n' - fun = fun + '\t\t#TODO - Delete it if you don\'t need\n' + fun = '# --------------------------------------------------------------------------\n' +\ + '# SetAxisPar/GetAxisPar()\n' +\ + '# --------------------------------------------------------------------------\n' +\ + '\tdef SetAxisPar(self, ' + self.ind + ', name, value):\n' + fun = fun + '\t\t#TODO - Delete it if you don\'t need\n' - fun = fun + '\tdef GetAxisPar(self, '+self.ind+', name):\n' - fun = fun + '\t\t#TODO - Delete it if you don\'t need\n' + fun = fun + '\tdef GetAxisPar(self, ' + self.ind + ', name):\n' + fun = fun + '\t\t#TODO - Delete it if you don\'t need\n' text = text + fun - fun = '# --------------------------------------------------------------------------\n'+\ - '# SetAxisExtraPar/GetAxisExtraPar()\n'+\ - '# --------------------------------------------------------------------------\n'+\ - '\tdef SetAxisExtraPar(self, '+self.ind+', name, value):\n' - fun = fun + '\t\t#TODO - Delete it if you don\'t need\n' + fun = '# --------------------------------------------------------------------------\n' +\ + '# SetAxisExtraPar/GetAxisExtraPar()\n' +\ + '# --------------------------------------------------------------------------\n' +\ + '\tdef SetAxisExtraPar(self, ' + self.ind + ', name, value):\n' + fun = fun + '\t\t#TODO - Delete it if you don\'t need\n' - fun = fun + '\tdef GetAxisExtraPar(self, '+self.ind+', name):\n' - fun = fun + '\t\t#TODO - Delete it if you don\'t need - \n' + fun = fun + '\tdef GetAxisExtraPar(self, ' + self.ind + ', name):\n' + fun = fun + '\t\t#TODO - Delete it if you don\'t need - \n' text = text + fun f.write(text) def main(): - #Add MACRO_PATH + # Add MACRO_PATH filename = "" end = "" inherit = "" @@ -192,7 +200,7 @@ def main(): inherit = sys.argv[2] if(len(sys.argv) > 3): end = "CT" - s= ControllerTemplate(filename,end) + s = ControllerTemplate(filename, end) s.addHead() s.addIncludes(inherit) s.createBasicClass() diff --git a/doc/source/devel/howto_controllers/sf_ct_ctrl.py b/doc/source/devel/howto_controllers/sf_ct_ctrl.py index 7c5f04ac43..3aec2bd2ed 100644 --- a/doc/source/devel/howto_controllers/sf_ct_ctrl.py +++ b/doc/source/devel/howto_controllers/sf_ct_ctrl.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,6 +31,7 @@ from sardana import State from sardana.pool.controller import CounterTimerController + class SpringfieldBaseCounterTimerController(CounterTimerController): """The most basic controller intended from demonstration purposes only. This is the absolute minimum you have to implement to set a proper counter @@ -42,7 +43,8 @@ class SpringfieldBaseCounterTimerController(CounterTimerController): def __init__(self, inst, props, *args, **kwargs): """Constructor""" - super(SpringfieldBaseCounterTimerController, self).__init__(inst, props, *args, **kwargs) + super(SpringfieldBaseCounterTimerController, + self).__init__(inst, props, *args, **kwargs) self.springfield = springfieldlib.SpringfieldCounterHW() def ReadOne(self, axis): @@ -74,33 +76,35 @@ def StopOne(self, axis): from sardana import DataAccess from sardana.pool.controller import Type, Description, DefaultValue, Access, FGet, FSet - + + class SpringfieldCounterTimerController(CounterTimerController): def __init__(self, inst, props, *args, **kwargs): - super(SpringfieldCounterTimerController, self).__init__(inst, props, *args, **kwargs) - + super(SpringfieldCounterTimerController, self).__init__( + inst, props, *args, **kwargs) + # initialize hardware communication self.springfield = springfieldlib.SpringfieldCounterHW() - + # do some initialization self._counters = {} def AddDevice(self, axis): - self._counters[axis] = True + self._counters[axis] = True def DeleteDevice(self, axis): - del self._counters[axis] - + del self._counters[axis] + StateMap = { - 1 : State.On, - 2 : State.Moving, - 3 : State.Fault, + 1: State.On, + 2: State.Moving, + 3: State.Fault, } - + def StateOne(self, axis): springfield = self.springfield - state = self.StateMap[ springfield.getState(axis) ] + state = self.StateMap[springfield.getState(axis)] status = springfield.getStatus(axis) return state, status @@ -118,4 +122,4 @@ def StopOne(self, axis): self.springfield.stop(axis) def AbortOne(self, axis): - self.springfield.abort(axis) \ No newline at end of file + self.springfield.abort(axis) diff --git a/doc/source/devel/howto_controllers/sf_motor_ctrl.py b/doc/source/devel/howto_controllers/sf_motor_ctrl.py index 80d938bb53..3b34b7acb8 100644 --- a/doc/source/devel/howto_controllers/sf_motor_ctrl.py +++ b/doc/source/devel/howto_controllers/sf_motor_ctrl.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,26 +29,28 @@ from sardana import State from sardana.pool.controller import MotorController + class SpringfieldBaseMotorController(MotorController): """The most basic controller intended from demonstration purposes only. This is the absolute minimum you have to implement to set a proper motor controller able to get a motor position, get a motor state and move a motor. - + This example is so basic that it is not even directly described in the documentation""" MaxDevice = 128 - + def __init__(self, inst, props, *args, **kwargs): """Constructor""" - super(SpringfieldBaseMotorController, self).__init__(inst, props, *args, **kwargs) + super(SpringfieldBaseMotorController, self).__init__( + inst, props, *args, **kwargs) self.springfield = springfieldlib.SpringfieldMotorHW() - + def ReadOne(self, axis): """Get the specified motor position""" return self.springfield.getPosition(axis) - + def StateOne(self, axis): """Get the specified motor state""" springfield = self.springfield @@ -59,61 +61,63 @@ def StateOne(self, axis): return State.Moving, "Motor is moving" elif state == 3: return State.Fault, "Motor has an error" - + def StartOne(self, axis, position): """Move the specified motor to the specified position""" - self.springfield.move(axis, position) + self.springfield.move(axis, position) def StopOne(self, axis): """Stop the specified motor""" - self.springfield.stop(axis) + self.springfield.stop(axis) from sardana import DataAccess from sardana.pool.controller import Type, Description, DefaultValue, Access, FGet, FSet - + + class SpringfieldMotorController(MotorController): - axis_attributes = { - "CloseLoop" : { - Type : bool, - Description : "(de)activates the motor close loop algorithm", - DefaultValue : False, - }, + axis_attributes = { + "CloseLoop": { + Type: bool, + Description: "(de)activates the motor close loop algorithm", + DefaultValue: False, + }, } - + def getCloseLoop(self, axis): return self.springfield.isCloseLoopActive(axis) - + def setCloseLoop(self, axis, value): self.springfield.setCloseLoop(axis, value) - + def __init__(self, inst, props, *args, **kwargs): - super(SpringfieldMotorController, self).__init__(inst, props, *args, **kwargs) - + super(SpringfieldMotorController, self).__init__( + inst, props, *args, **kwargs) + # initialize hardware communication self.springfield = springfieldlib.SpringfieldMotorHW() - + # do some initialization self._motors = {} def AddDevice(self, axis): - self._motors[axis] = True + self._motors[axis] = True def DeleteDevice(self, axis): - del self._motors[axis] - + del self._motors[axis] + StateMap = { - 1 : State.On, - 2 : State.Moving, - 3 : State.Fault, + 1: State.On, + 2: State.Moving, + 3: State.Fault, } - + def StateOne(self, axis): springfield = self.springfield - state = self.StateMap[ springfield.getState(axis) ] + state = self.StateMap[springfield.getState(axis)] status = springfield.getStatus(axis) - + limit_switches = MotorController.NoLimitSwitch hw_limit_switches = springfield.getLimits(axis) if hw_limit_switches[0]: @@ -127,15 +131,15 @@ def StateOne(self, axis): def ReadOne(self, axis): position = self.springfield.getPosition(axis) return position - + def StartOne(self, axis, position): - self.springfield.move(axis, position) + self.springfield.move(axis, position) def StopOne(self, axis): - self.springfield.stop(axis) + self.springfield.stop(axis) def AbortOne(self, axis): self.springfield.abort(axis) - + def DefinePosition(self, axis, position): self.springfield.setCurrentPosition(axis, position) diff --git a/doc/source/devel/howto_controllers/sf_tg_ctrl.py b/doc/source/devel/howto_controllers/sf_tg_ctrl.py index 45f54f9314..4100e9b79c 100644 --- a/doc/source/devel/howto_controllers/sf_tg_ctrl.py +++ b/doc/source/devel/howto_controllers/sf_tg_ctrl.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,6 +31,7 @@ from sardana import State from sardana.pool.controller import TriggerGateController + class SpringfieldBaseTriggerGateController(TriggerGateController): """The most basic controller intended from demonstration purposes only. This is the absolute minimum you have to implement to set a proper trigger @@ -42,7 +43,8 @@ class SpringfieldBaseTriggerGateController(TriggerGateController): def __init__(self, inst, props, *args, **kwargs): """Constructor""" - super(SpringfieldBaseTriggerGateController, self).__init__(inst, props, *args, **kwargs) + super(SpringfieldBaseTriggerGateController, self).__init__( + inst, props, *args, **kwargs) self.springfield = springfieldlib.SpringfieldTriggerHW() def ReadOne(self, axis): @@ -75,10 +77,12 @@ def StopOne(self, axis): from sardana import DataAccess from sardana.pool.controller import Type, Description, DefaultValue, Access, FGet, FSet + class SpringfieldTriggerGateController(TriggerGateController): def __init__(self, inst, props, *args, **kwargs): - super(SpringfieldTriggerGateController, self).__init__(inst, props, *args, **kwargs) + super(SpringfieldTriggerGateController, self).__init__( + inst, props, *args, **kwargs) # initialize hardware communication self.springfield = springfieldlib.SpringfieldTriggerHW() @@ -87,20 +91,20 @@ def __init__(self, inst, props, *args, **kwargs): self._triggers = {} def AddDevice(self, axis): - self._triggers[axis] = True + self._triggers[axis] = True def DeleteDevice(self, axis): del self._triggers[axis] StateMap = { - 1 : State.On, - 2 : State.Moving, - 3 : State.Fault, + 1: State.On, + 2: State.Moving, + 3: State.Fault, } def StateOne(self, axis): springfield = self.springfield - state = self.StateMap[ springfield.getState(axis) ] + state = self.StateMap[springfield.getState(axis)] status = springfield.getStatus(axis) return state, status diff --git a/doc/source/devel/howto_controllers/springfieldlib.py b/doc/source/devel/howto_controllers/springfieldlib.py index 51e35d420a..f8cf9339e0 100644 --- a/doc/source/devel/howto_controllers/springfieldlib.py +++ b/doc/source/devel/howto_controllers/springfieldlib.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -33,6 +33,7 @@ import time from math import pow, sqrt + class BaseMotion(object): def __init__(self): @@ -66,7 +67,7 @@ def __init__(self): self.small_motion = False # position where maximum velocity will be reached - self.curr_max_vel_pos = -1 + self.curr_max_vel_pos = -1 # necessary displacement to reach maximum velocity self.curr_dsplmnt_reach_max_vel = -1 @@ -116,11 +117,11 @@ def __init__(self): def isCloseLoopActive(self): return self.close_loop - + def setCloseLoop(self, v): self.close_loop = v - def setMinVelocity(self,vi): + def setMinVelocity(self, vi): """ Sets the minimum velocity in ms^-1. A.k.a. base rate""" vi = float(vi) if vi < 0: @@ -140,7 +141,7 @@ def setMinVelocity(self,vi): def getMinVelocity(self): return self.min_vel - def setMaxVelocity(self,vf): + def setMaxVelocity(self, vf): """ Sets the maximum velocity in ms^-1.""" vf = float(vf) if vf <= 0: @@ -160,7 +161,7 @@ def setMaxVelocity(self,vf): def getMaxVelocity(self): return self.max_vel - def setAccelerationTime(self,at): + def setAccelerationTime(self, at): """Sets the time to go from minimum velocity to maximum velocity in seconds""" at = float(at) if at <= 0: @@ -174,7 +175,7 @@ def setAccelerationTime(self,at): def getAccelerationTime(self): return self.accel_time - def setDecelerationTime(self,dt): + def setDecelerationTime(self, dt): """Sets the time to go from maximum velocity to minimum velocity in seconds""" dt = float(dt) if dt <= 0: @@ -188,7 +189,7 @@ def setDecelerationTime(self,dt): def getDecelerationTime(self): return self.decel_time - def setAcceleration(self,a): + def setAcceleration(self, a): """Sets the acceleration in ms^-2""" a = float(a) if a < 0: @@ -203,7 +204,7 @@ def setAcceleration(self,a): self.__recalculate_acc_constants() - def setDeceleration(self,d): + def setDeceleration(self, d): """Sets the deceleration in ms^-2""" d = float(d) if d > 0: @@ -227,10 +228,10 @@ def setStepPerUnit(self, spu): def __recalculate_acc_constants(self): """precomputations assuming maximum speed can be reached in a motion""" - self.dsplmnt_reach_max_vel = 0.5 * self.accel * pow(self.accel_time,2) + self.dsplmnt_reach_max_vel = 0.5 * self.accel * pow(self.accel_time, 2) self.dsplmnt_reach_max_vel += self.min_vel * self.accel_time - self.dsplmnt_reach_min_vel = 0.5 * self.decel * pow(self.decel_time,2) + self.dsplmnt_reach_min_vel = 0.5 * self.decel * pow(self.decel_time, 2) self.dsplmnt_reach_min_vel += self.max_vel * self.decel_time def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): @@ -269,7 +270,6 @@ def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): self.curr_accel = -self.accel self.curr_decel = -self.decel - if not self.small_motion: # necessary displacement to reach maximum velocity @@ -289,21 +289,26 @@ def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): self.curr_max_vel_pos = self.init_pos - self.curr_dsplmnt_reach_max_vel # displacement at maximum velocity - self.curr_at_max_vel_dsplmnt = self.dsplmnt - (self.curr_dsplmnt_reach_max_vel + self.curr_dsplmnt_reach_min_vel) + self.curr_at_max_vel_dsplmnt = self.dsplmnt - \ + (self.curr_dsplmnt_reach_max_vel + self.curr_dsplmnt_reach_min_vel) else: # Small movement # position where maximum velocity will be reached - self.curr_max_vel_pos = self.init_pos * self.curr_accel - self.final_pos * self.curr_decel + self.curr_max_vel_pos = self.init_pos * \ + self.curr_accel - self.final_pos * self.curr_decel self.curr_max_vel_pos /= self.curr_accel - self.curr_decel # necessary displacement to reach maximum velocity - self.curr_dsplmnt_reach_max_vel = abs(self.curr_max_vel_pos - self.init_pos) + self.curr_dsplmnt_reach_max_vel = abs( + self.curr_max_vel_pos - self.init_pos) # necessary diplacement to reach minimum velocity - self.curr_dsplmnt_reach_min_vel = abs(self.final_pos - self.curr_max_vel_pos) + self.curr_dsplmnt_reach_min_vel = abs( + self.final_pos - self.curr_max_vel_pos) # maximum velocity possible - cnst = 2 * self.curr_accel * self.curr_decel * self.dsplmnt / (self.curr_decel - self.curr_accel) + cnst = 2 * self.curr_accel * self.curr_decel * \ + self.dsplmnt / (self.curr_decel - self.curr_accel) max_vel_2 = pow(self.min_vel, 2) + cnst self.curr_max_vel = sqrt(abs(max_vel_2)) @@ -318,13 +323,16 @@ def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): self.curr_at_max_vel_dsplmnt = 0.0 # time to reach maximum velocity - self.curr_max_vel_time = abs((self.curr_max_vel - self.curr_min_vel) / self.curr_accel) + self.curr_max_vel_time = abs( + (self.curr_max_vel - self.curr_min_vel) / self.curr_accel) # time to reach minimum velocity - self.curr_min_vel_time = abs((self.curr_min_vel - self.curr_max_vel) / self.curr_decel) + self.curr_min_vel_time = abs( + (self.curr_min_vel - self.curr_max_vel) / self.curr_decel) # time at maximum velocity - self.curr_at_max_vel_time = abs(self.curr_at_max_vel_dsplmnt / self.curr_max_vel) + self.curr_at_max_vel_time = abs( + self.curr_at_max_vel_dsplmnt / self.curr_max_vel) # instant when maximum velocity should be reached self.curr_max_vel_instant = self.start_instant + self.curr_max_vel_time @@ -333,7 +341,8 @@ def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): self.curr_min_vel_instant = self.curr_max_vel_instant + self.curr_at_max_vel_time # time the motion will take - self.duration = self.curr_max_vel_time + self.curr_at_max_vel_time + self.curr_min_vel_time + self.duration = self.curr_max_vel_time + \ + self.curr_at_max_vel_time + self.curr_min_vel_time # instant the motion will end self.final_instant = self.start_instant + self.duration @@ -380,9 +389,10 @@ def abortMotion(self, curr_instant=None): self.inMotion = False return self.curr_pos - def isInMotion(self,curr_instant=None): + def isInMotion(self, curr_instant=None): curr_instant = curr_instant or time.time() - #we call getCurrentPosition because inside it updates the inMotion flag + # we call getCurrentPosition because inside it updates the inMotion + # flag self.getCurrentPosition(curr_instant) return self.inMotion @@ -400,7 +410,7 @@ def getCurrentPosition(self, curr_instant=None): self.inMotion = False pos = self.final_pos else: - pos = self.init_pos + pos = self.init_pos if curr_instant > self.curr_min_vel_instant: if self.positive_dsplmnt: pos += self.curr_dsplmnt_reach_max_vel @@ -409,7 +419,8 @@ def getCurrentPosition(self, curr_instant=None): pos -= self.curr_dsplmnt_reach_max_vel pos -= self.curr_at_max_vel_dsplmnt dt = curr_instant - self.curr_min_vel_instant - pos += self.curr_max_vel * dt + 0.5 * self.curr_decel * pow(dt,2) + pos += self.curr_max_vel * dt + \ + 0.5 * self.curr_decel * pow(dt, 2) elif curr_instant > self.curr_max_vel_instant: if self.positive_dsplmnt: pos += self.curr_dsplmnt_reach_max_vel @@ -418,8 +429,9 @@ def getCurrentPosition(self, curr_instant=None): dt = curr_instant - self.curr_max_vel_instant pos += self.curr_max_vel * dt else: - dt = curr_instant - self.start_instant - pos += self.curr_min_vel * dt + 0.5 * self.curr_accel * pow(dt,2) + dt = curr_instant - self.start_instant + pos += self.curr_min_vel * dt + \ + 0.5 * self.curr_accel * pow(dt, 2) else: pos = self.curr_pos if pos <= self.lower_ls: @@ -432,7 +444,7 @@ def getCurrentPosition(self, curr_instant=None): return pos def setCurrentUserPosition(self, user_pos): - self.setCurrentPosition(user_pos*self.step_per_unit) + self.setCurrentPosition(user_pos * self.step_per_unit) def getCurrentUserPosition(self, curr_instant=None): return self.getCurrentPosition(curr_instant=curr_instant) / self.step_per_unit @@ -473,41 +485,41 @@ def setPower(self, power): self.power = power def info(self): - print "Small movement =",self.small_motion - print "length =",self.dsplmnt - print "position where maximum velocity will be reached =",self.curr_max_vel_pos - print "necessary displacement to reach maximum velocity =",self.curr_dsplmnt_reach_max_vel - print "necessary displacement to stop from maximum velocity =",self.curr_dsplmnt_reach_min_vel - print "maximum velocity possible =",self.curr_max_vel - print "time at top velocity =",self.curr_at_max_vel_time - print "displacement at top velocity =",self.curr_at_max_vel_dsplmnt - print "time to reach maximum velocity =",self.curr_max_vel_time - print "time to reach minimum velocity =",self.curr_min_vel_time - print "time the motion will take =",self.duration - print "instant when maximum velocity should be reached =",self.curr_max_vel_instant - print "instant when should start decelerating =",self.curr_min_vel_instant - print "instant the motion will end",self.final_instant + print "Small movement =", self.small_motion + print "length =", self.dsplmnt + print "position where maximum velocity will be reached =", self.curr_max_vel_pos + print "necessary displacement to reach maximum velocity =", self.curr_dsplmnt_reach_max_vel + print "necessary displacement to stop from maximum velocity =", self.curr_dsplmnt_reach_min_vel + print "maximum velocity possible =", self.curr_max_vel + print "time at top velocity =", self.curr_at_max_vel_time + print "displacement at top velocity =", self.curr_at_max_vel_dsplmnt + print "time to reach maximum velocity =", self.curr_max_vel_time + print "time to reach minimum velocity =", self.curr_min_vel_time + print "time the motion will take =", self.duration + print "instant when maximum velocity should be reached =", self.curr_max_vel_instant + print "instant when should start decelerating =", self.curr_min_vel_instant + print "instant the motion will end", self.final_instant print "" - print "For long movements (where top vel is possible), necessary displacement to reach maximum velocity =",self.dsplmnt_reach_max_vel - print "For long movements (where top vel is possible), necessary displacement to stop from maximum velocity =",self.dsplmnt_reach_min_vel + print "For long movements (where top vel is possible), necessary displacement to reach maximum velocity =", self.dsplmnt_reach_max_vel + print "For long movements (where top vel is possible), necessary displacement to stop from maximum velocity =", self.dsplmnt_reach_min_vel class SpringfieldMotorHW(object): - + DefaultHost = "localhost" DefaultPort = 10123 - + def __init__(self, host=DefaultHost, port=DefaultPort): self.host = host self.port = port self._motions = {} - + def getMotion(self, axis): motion = self._motions.get(axis) if motion is None: self._motions[axis] = motion = Motion() return motion - + def getState(self, axis): motion = self.getMotion(axis) motion.getCurrentUserPosition() @@ -520,7 +532,7 @@ def getState(self, axis): if not motion.hasPower(): return 4 return 1 - + def getStatus(self, axis): motion = self.getMotion(axis) motion.getCurrentUserPosition() @@ -538,13 +550,13 @@ def getStatus(self, axis): def getLimits(self, axis): motion = self.getMotion(axis) m.getCurrentUserPosition() - switchstate = 3*[False,] + switchstate = 3 * [False, ] if m.hitLowerLimit(): switchstate[2] = True if m.hitUpperLimit(): switchstate[1] = True return switchstate - + def getPosition(self, axis): motion = self.getMotion(axis) return motion.getCurrentUserPosition() @@ -563,7 +575,7 @@ def getMaxVelocity(self, axis): def getStepPerUnit(self, axis): return self.getMotion(axis).getStepPerUnit() - + def setAccelerationTime(self, axis, v): self.getMotion(axis).setAccelerationTime(v) @@ -594,7 +606,7 @@ def move(self, axis, position): t = time.time() motion = self.getMotion(axis) motion.startMotion(motion.getCurrentUserPosition(t), position, t) - + def stop(self, axis): motion = self.getMotion(axis) motion.abortMotion() @@ -602,33 +614,33 @@ def stop(self, axis): def abort(self, axis): motion = self.getMotion(axis) motion.abortMotion() - + class Channel: - - def __init__(self,idx): + + def __init__(self, idx): self.idx = idx # 1 based index self.value = 0.0 self.is_counting = False self.active = True - + class SpringfieldCounterHW(object): DefaultHost = "localhost" DefaultPort = 10124 - + def __init__(self, host=DefaultHost, port=DefaultPort): self.host = host self.port = port self._channels = {} - + def getChannel(self, axis): channel = self._channels.get(axis) if channel is None: self._channels[axis] = channel = Channel(axis) return channel - + def getState(self, axis): channel = self.getChannel(axis) channel.getCurrentValue() @@ -637,7 +649,7 @@ def getState(self, axis): if not channel.hasPower(): return 3 return 1 - + def getStatus(self, axis): channel = self.getChannel(axis) channel.getCurrentValue() @@ -670,4 +682,4 @@ def AbortChannel(self, axis): def LoadChannel(self, axis, value): # TODO - pass \ No newline at end of file + pass diff --git a/doc/source/sphinxext/ipython_console_highlighting.py b/doc/source/sphinxext/ipython_console_highlighting.py index 063468cd94..97bb6e0ed9 100644 --- a/doc/source/sphinxext/ipython_console_highlighting.py +++ b/doc/source/sphinxext/ipython_console_highlighting.py @@ -1,25 +1,25 @@ -################################################################################ +########################################################################## ## -## This file is part of PyTango, a python binding for Tango -## -## http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html +# This file is part of PyTango, a python binding for Tango ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## PyTango is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## PyTango is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with PyTango. If not, see . +# http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html ## -################################################################################ +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# PyTango is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# PyTango is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with PyTango. If not, see . +## +########################################################################## """reST directive for syntax-highlighting ipython interactive sessions. @@ -36,7 +36,7 @@ # Third party from pygments.lexer import Lexer, do_insertions -from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, +from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, PythonTracebackLexer) from pygments.token import Comment, Generic @@ -49,6 +49,7 @@ #----------------------------------------------------------------------------- # Code begins - classes and functions + class IPythonConsoleLexer(Lexer): """ For IPython console output or doctests, such as: @@ -71,7 +72,7 @@ class IPythonConsoleLexer(Lexer): - It assumes the default IPython prompts, not customized ones. """ - + name = 'IPython console session' aliases = ['ipython'] mimetypes = ['text/x-ipython-console'] @@ -134,4 +135,4 @@ def setup(app): #----------------------------------------------------------------------------- # Register the extension as a valid pygments lexer -highlighting.lexers['ipython'] = IPythonConsoleLexer() \ No newline at end of file +highlighting.lexers['ipython'] = IPythonConsoleLexer() diff --git a/doc/source/sphinxext/sardanaextension.py b/doc/source/sphinxext/sardanaextension.py index 43996a4a17..5cc2837190 100644 --- a/doc/source/sphinxext/sardanaextension.py +++ b/doc/source/sphinxext/sardanaextension.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -28,74 +28,82 @@ __expr = ('or',) + def process_type(t, obj_type='class'): t = t.strip() - if not t: return '' - if t in __expr: return t + if not t: + return '' + if t in __expr: + return t if t.count(' or '): - i = t.index(' or ') - return ' '.join(map(process_type, (t[:i],'or', t[i+4:]))) - if not t.count('<') or not t.count('>'): return ':%s:`%s`' % (obj_type, t) - - #process a container template + i = t.index(' or ') + return ' '.join(map(process_type, (t[:i], 'or', t[i + 4:]))) + if not t.count('<') or not t.count('>'): + return ':%s:`%s`' % (obj_type, t) + + # process a container template start, stop = t.index('<'), t.index('>') main_type = t[:start] main_type = process_type(main_type) - types = t[start+1:stop].split(',') + types = t[start + 1:stop].split(',') types = ', '.join(map(process_type, types)) return "%s <%s>" % (main_type, types) + def process_param(line): new_lines = [] try: prefix, param, desc = line.split(':', 2) p, param_name = param.split() desc = desc.strip() - if desc[0] == '(' : + if desc[0] == '(': pos = desc.find(')') if pos != -1: elem_type = desc[1:pos] klass = process_type(elem_type) - desc = desc[pos+1:] - new_lines.append('%s:type %s: %s' % (prefix, param_name, klass)) + desc = desc[pos + 1:] + new_lines.append('%s:type %s: %s' % + (prefix, param_name, klass)) new_lines.append('%s:param %s: %s' % (prefix, param_name, desc)) except Exception, e: print "Sardana sphinx extension: Not able to process param: '%s'" % line - print " Reason:",str(e) + print " Reason:", str(e) new_lines.append(line) return new_lines + def process_return(line): new_lines = [] try: prefix, param, desc = line.split(':', 2) desc = desc.strip() - if desc[0] == '(' : + if desc[0] == '(': pos = desc.find(')') if pos != -1: elem_type = desc[1:pos] klass = process_type(elem_type) - desc = desc[pos+1:] + desc = desc[pos + 1:] new_lines.append('%s:rtype: %s' % (prefix, klass)) new_lines.append('%s:return: %s' % (prefix, desc)) except Exception, e: print "Sardana sphinx extension: Not able to process 'return': '%s'" % line - print " Reason:",str(e) + print " Reason:", str(e) new_lines.append(line) return new_lines + def process_raise(line): new_lines = [] try: prefix, param, desc = line.split(':', 2) desc = desc.strip() klass = '' - if desc[0] == '(' : + if desc[0] == '(': pos = desc.find(')') if pos != -1: elem_type = desc[1:pos] klass = "(" + process_type(elem_type, obj_type='exc') + ")" - desc = desc[pos+1:] + desc = desc[pos + 1:] new_lines.append('%s:raise: %s %s' % (prefix, klass, desc)) except Exception, e: print "Sardana sphinx extension: Not able to process 'raise': '%s'" % line @@ -103,11 +111,13 @@ def process_raise(line): new_lines.append(line) return new_lines + def _is_return(line): ret = line.startswith(':return') ret |= line.startswith(':returns') return ret + def _is_param(line): ret = line.startswith(':param') ret |= line.startswith(':parameter') @@ -117,11 +127,13 @@ def _is_param(line): ret |= line.startswith(':keyword') return ret + def _is_raise(line): ret = line.startswith(':raise') ret |= line.startswith(':except') return ret + def process_docstring(app, what, name, obj, options, lines): ret = [] for nb, line in enumerate(lines): @@ -134,16 +146,17 @@ def process_docstring(app, what, name, obj, options, lines): ret.extend(process_raise(line)) else: ret.append(line) - + del lines[:] lines.extend(ret) import inspect from sphinx.util.inspect import getargspec + def _format_method_args(obj): if inspect.isbuiltin(obj) or \ - inspect.ismethoddescriptor(obj): + inspect.ismethoddescriptor(obj): # can never get arguments of a C function or method return None argspec = getargspec(obj) @@ -151,9 +164,10 @@ def _format_method_args(obj): del argspec[0][0] return inspect.formatargspec(*argspec) + def _format_function_args(obj): if inspect.isbuiltin(obj) or \ - inspect.ismethoddescriptor(obj): + inspect.ismethoddescriptor(obj): # cannot introspect arguments of a C function or method return None try: @@ -173,6 +187,7 @@ def _format_function_args(obj): args = args.replace('\\', '\\\\') return args + def process_signature(app, what, name, obj, options, signature, return_annotation): if hasattr(obj, "__wrapped__"): if what == "method": @@ -180,8 +195,8 @@ def process_signature(app, what, name, obj, options, signature, return_annotatio obj = wrapped(obj) signature = _format_method_args(obj) return signature, return_annotation - - + + def setup(app): #app.connect('autodoc-process-docstring', process_docstring) app.connect('autodoc-process-signature', process_signature) diff --git a/doc/source/sphinxext/spock_console_highlighting.py b/doc/source/sphinxext/spock_console_highlighting.py index 86716a7f2b..0ccfaaa898 100644 --- a/doc/source/sphinxext/spock_console_highlighting.py +++ b/doc/source/sphinxext/spock_console_highlighting.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -36,7 +36,7 @@ # Third party from pygments.lexer import Lexer, do_insertions -from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, +from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, PythonTracebackLexer) from pygments.token import Token, Comment, Generic from pygments.style import Style @@ -49,11 +49,13 @@ DftStyle = pygments.styles.get_style_by_name("default") + class SpockStyle(DftStyle): - + styles = copy.copy(DftStyle.styles) styles[Generic.Prompt] = 'bold #00AA00' + class SpockConsoleLexer(Lexer): """ For spock console output or doctests, such as: @@ -76,11 +78,12 @@ class SpockConsoleLexer(Lexer): - It assumes the default spock prompts, not customized ones. """ - + name = 'Spock console session' aliases = ['spock'] mimetypes = ['text/x-spock-console'] - input_prompt = re.compile("([a-zA-Z0-9_\-]+ \[(?P[0-9]+)\]: )|( \.\.\.+:)") + input_prompt = re.compile( + "([a-zA-Z0-9_\-]+ \[(?P[0-9]+)\]: )|( \.\.\.+:)") output_prompt = re.compile("(\s*Result \[(?P[0-9]+)\]: )|( \.\.\.+:)") continue_prompt = re.compile(" \.\.\.+:") tb_start = re.compile("\-+") diff --git a/sandbox/mntgrp_gui b/sandbox/mntgrp_gui index 2ea97c1251..bcabd7f59b 100755 --- a/sandbox/mntgrp_gui +++ b/sandbox/mntgrp_gui @@ -8,6 +8,7 @@ from taurus.qt.qtgui.application import TaurusApplication from taurus.qt.qtgui.extra_sardana.measurementgroup import MntGrpChannelPanel from functools import partial + def openCfgMg(mg): d = Qt.QDialog(panel) l = Qt.QVBoxLayout() @@ -26,8 +27,10 @@ ui = mntgrp_gui.Ui_Form() ui.setupUi(w) -Qt.QObject.connect(ui.cfgMg1, Qt.SIGNAL("clicked()"), partial(openCfgMg, "mg1")) -Qt.QObject.connect(ui.cfgMg2, Qt.SIGNAL("clicked()"), partial(openCfgMg, "mg2")) +Qt.QObject.connect(ui.cfgMg1, Qt.SIGNAL( + "clicked()"), partial(openCfgMg, "mg1")) +Qt.QObject.connect(ui.cfgMg2, Qt.SIGNAL( + "clicked()"), partial(openCfgMg, "mg2")) panel.show() diff --git a/sandbox/mntgrp_gui.py b/sandbox/mntgrp_gui.py index 25fd395df2..66fa96bf9b 100644 --- a/sandbox/mntgrp_gui.py +++ b/sandbox/mntgrp_gui.py @@ -14,7 +14,9 @@ except AttributeError: _fromUtf8 = lambda s: s + class Ui_Form(object): + def setupUi(self, Form): Form.setObjectName(_fromUtf8("Form")) Form.resize(501, 414) @@ -155,7 +157,8 @@ def setupUi(self, Form): self.taurusLabel_30.setObjectName(_fromUtf8("taurusLabel_30")) self.gridLayout_5.addWidget(self.taurusLabel_30, 2, 1, 1, 1) self.taurusValueLineEdit_2 = TaurusValueLineEdit(self.groupBox_4) - self.taurusValueLineEdit_2.setObjectName(_fromUtf8("taurusValueLineEdit_2")) + self.taurusValueLineEdit_2.setObjectName( + _fromUtf8("taurusValueLineEdit_2")) self.gridLayout_5.addWidget(self.taurusValueLineEdit_2, 2, 2, 1, 1) self.taurusLabel_33 = TaurusLabel(self.groupBox_4) self.taurusLabel_33.setObjectName(_fromUtf8("taurusLabel_33")) @@ -164,7 +167,8 @@ def setupUi(self, Form): self.taurusLabel_34.setObjectName(_fromUtf8("taurusLabel_34")) self.gridLayout_5.addWidget(self.taurusLabel_34, 3, 1, 1, 1) self.taurusValueLineEdit_4 = TaurusValueLineEdit(self.groupBox_4) - self.taurusValueLineEdit_4.setObjectName(_fromUtf8("taurusValueLineEdit_4")) + self.taurusValueLineEdit_4.setObjectName( + _fromUtf8("taurusValueLineEdit_4")) self.gridLayout_5.addWidget(self.taurusValueLineEdit_4, 3, 2, 1, 1) self.taurusLabel_37 = TaurusLabel(self.groupBox_4) self.taurusLabel_37.setObjectName(_fromUtf8("taurusLabel_37")) @@ -173,12 +177,14 @@ def setupUi(self, Form): self.taurusLabel_38.setObjectName(_fromUtf8("taurusLabel_38")) self.gridLayout_5.addWidget(self.taurusLabel_38, 4, 1, 1, 1) self.taurusValueLineEdit_6 = TaurusValueLineEdit(self.groupBox_4) - self.taurusValueLineEdit_6.setObjectName(_fromUtf8("taurusValueLineEdit_6")) + self.taurusValueLineEdit_6.setObjectName( + _fromUtf8("taurusValueLineEdit_6")) self.gridLayout_5.addWidget(self.taurusValueLineEdit_6, 4, 2, 1, 1) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.taurusCommandButton_2 = TaurusCommandButton(self.groupBox_4) - self.taurusCommandButton_2.setObjectName(_fromUtf8("taurusCommandButton_2")) + self.taurusCommandButton_2.setObjectName( + _fromUtf8("taurusCommandButton_2")) self.horizontalLayout_2.addWidget(self.taurusCommandButton_2) self.cfgMg2 = QtGui.QToolButton(self.groupBox_4) self.cfgMg2.setObjectName(_fromUtf8("cfgMg2")) @@ -200,7 +206,8 @@ def setupUi(self, Form): self.taurusLabel_28.setObjectName(_fromUtf8("taurusLabel_28")) self.gridLayout_4.addWidget(self.taurusLabel_28, 2, 0, 1, 1) self.taurusValueLineEdit = TaurusValueLineEdit(self.groupBox_3) - self.taurusValueLineEdit.setObjectName(_fromUtf8("taurusValueLineEdit")) + self.taurusValueLineEdit.setObjectName( + _fromUtf8("taurusValueLineEdit")) self.gridLayout_4.addWidget(self.taurusValueLineEdit, 2, 2, 1, 1) self.taurusLed = TaurusLed(self.groupBox_3) self.taurusLed.setObjectName(_fromUtf8("taurusLed")) @@ -212,7 +219,8 @@ def setupUi(self, Form): self.taurusLabel_32.setObjectName(_fromUtf8("taurusLabel_32")) self.gridLayout_4.addWidget(self.taurusLabel_32, 3, 1, 1, 1) self.taurusValueLineEdit_3 = TaurusValueLineEdit(self.groupBox_3) - self.taurusValueLineEdit_3.setObjectName(_fromUtf8("taurusValueLineEdit_3")) + self.taurusValueLineEdit_3.setObjectName( + _fromUtf8("taurusValueLineEdit_3")) self.gridLayout_4.addWidget(self.taurusValueLineEdit_3, 3, 2, 1, 1) self.taurusLabel_35 = TaurusLabel(self.groupBox_3) self.taurusLabel_35.setObjectName(_fromUtf8("taurusLabel_35")) @@ -221,12 +229,14 @@ def setupUi(self, Form): self.taurusLabel_36.setObjectName(_fromUtf8("taurusLabel_36")) self.gridLayout_4.addWidget(self.taurusLabel_36, 4, 1, 1, 1) self.taurusValueLineEdit_5 = TaurusValueLineEdit(self.groupBox_3) - self.taurusValueLineEdit_5.setObjectName(_fromUtf8("taurusValueLineEdit_5")) + self.taurusValueLineEdit_5.setObjectName( + _fromUtf8("taurusValueLineEdit_5")) self.gridLayout_4.addWidget(self.taurusValueLineEdit_5, 4, 2, 1, 1) self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) self.taurusCommandButton = TaurusCommandButton(self.groupBox_3) - self.taurusCommandButton.setObjectName(_fromUtf8("taurusCommandButton")) + self.taurusCommandButton.setObjectName( + _fromUtf8("taurusCommandButton")) self.horizontalLayout_3.addWidget(self.taurusCommandButton) self.cfgMg1 = QtGui.QToolButton(self.groupBox_3) self.cfgMg1.setObjectName(_fromUtf8("cfgMg1")) @@ -238,95 +248,184 @@ def setupUi(self, Form): QtCore.QMetaObject.connectSlotsByName(Form) def retranslateUi(self, Form): - Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) - self.groupBox.setTitle(QtGui.QApplication.translate("Form", "CTs of CTRL1", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/1/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_2.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/1/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_2.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/1/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_3.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/2/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_3.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_4.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/2/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_3.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/2/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_5.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/3/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_5.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_6.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/3/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_4.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/3/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_7.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/4/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_7.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_8.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/4/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_5.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/4/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_9.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/5/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_9.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_10.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/5/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_6.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/5/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_11.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/6/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_11.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_12.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/6/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_7.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl1/6/state", None, QtGui.QApplication.UnicodeUTF8)) - self.groupBox_2.setTitle(QtGui.QApplication.translate("Form", "CTs of CTRL2", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_13.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/1/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_13.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_14.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/1/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_8.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/1/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_15.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/2/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_15.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_16.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/2/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_9.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/2/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_17.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/3/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_17.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_18.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/3/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_10.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/3/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_19.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/4/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_19.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_20.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/4/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_11.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/4/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_21.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/5/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_21.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_22.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/5/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_12.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/5/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_23.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/6/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_23.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_24.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/6/value", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_13.setModel(QtGui.QApplication.translate("Form", "expchan/dummyctctrl2/6/state", None, QtGui.QApplication.UnicodeUTF8)) - self.groupBox_4.setTitle(QtGui.QApplication.translate("Form", "MG2", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_26.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/elementlist", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_26.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed_14.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_29.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/integrationtime?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_29.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_30.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/integrationtime", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusValueLineEdit_2.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/integrationtime", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_33.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/monitorcount?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_33.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_34.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/monitorcount", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusValueLineEdit_4.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/monitorcount", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_37.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/acquisitionmode?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_37.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_38.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/acquisitionmode", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusValueLineEdit_6.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2/acquisitionmode", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusCommandButton_2.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg2", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusCommandButton_2.setCommand(QtGui.QApplication.translate("Form", "start", None, QtGui.QApplication.UnicodeUTF8)) - self.cfgMg2.setText(QtGui.QApplication.translate("Form", "...", None, QtGui.QApplication.UnicodeUTF8)) - self.groupBox_3.setTitle(QtGui.QApplication.translate("Form", "MG1", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_25.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/elementlist", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_25.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_27.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/integrationtime", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_28.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/integrationtime?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_28.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusValueLineEdit.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/integrationtime", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLed.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/state", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_31.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/monitorcount?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_31.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_32.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/monitorcount", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusValueLineEdit_3.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/monitorcount", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_35.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/acquisitionmode?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_35.setBgRole(QtGui.QApplication.translate("Form", "none", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusLabel_36.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/acquisitionmode", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusValueLineEdit_5.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1/acquisitionmode", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusCommandButton.setModel(QtGui.QApplication.translate("Form", "mntgrp/v3/mg1", None, QtGui.QApplication.UnicodeUTF8)) - self.taurusCommandButton.setCommand(QtGui.QApplication.translate("Form", "start", None, QtGui.QApplication.UnicodeUTF8)) - self.cfgMg1.setText(QtGui.QApplication.translate("Form", "...", None, QtGui.QApplication.UnicodeUTF8)) + Form.setWindowTitle(QtGui.QApplication.translate( + "Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox.setTitle(QtGui.QApplication.translate( + "Form", "CTs of CTRL1", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/1/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_2.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/1/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_2.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/1/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_3.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/2/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_3.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_4.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/2/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_3.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/2/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_5.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/3/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_5.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_6.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/3/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_4.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/3/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_7.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/4/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_7.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_8.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/4/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_5.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/4/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_9.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/5/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_9.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_10.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/5/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_6.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/5/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_11.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/6/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_11.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_12.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/6/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_7.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl1/6/state", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_2.setTitle(QtGui.QApplication.translate( + "Form", "CTs of CTRL2", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_13.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/1/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_13.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_14.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/1/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_8.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/1/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_15.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/2/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_15.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_16.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/2/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_9.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/2/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_17.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/3/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_17.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_18.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/3/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_10.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/3/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_19.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/4/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_19.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_20.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/4/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_11.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/4/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_21.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/5/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_21.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_22.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/5/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_12.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/5/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_23.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/6/value?configuration=dev_alias", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_23.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_24.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/6/value", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_13.setModel(QtGui.QApplication.translate( + "Form", "expchan/dummyctctrl2/6/state", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_4.setTitle(QtGui.QApplication.translate( + "Form", "MG2", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_26.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/elementlist", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_26.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed_14.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_29.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/integrationtime?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_29.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_30.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/integrationtime", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusValueLineEdit_2.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/integrationtime", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_33.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/monitorcount?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_33.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_34.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/monitorcount", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusValueLineEdit_4.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/monitorcount", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_37.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/acquisitionmode?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_37.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_38.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/acquisitionmode", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusValueLineEdit_6.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2/acquisitionmode", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusCommandButton_2.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg2", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusCommandButton_2.setCommand(QtGui.QApplication.translate( + "Form", "start", None, QtGui.QApplication.UnicodeUTF8)) + self.cfgMg2.setText(QtGui.QApplication.translate( + "Form", "...", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox_3.setTitle(QtGui.QApplication.translate( + "Form", "MG1", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_25.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/elementlist", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_25.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_27.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/integrationtime", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_28.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/integrationtime?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_28.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusValueLineEdit.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/integrationtime", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLed.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/state", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_31.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/monitorcount?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_31.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_32.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/monitorcount", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusValueLineEdit_3.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/monitorcount", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_35.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/acquisitionmode?configuration=label", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_35.setBgRole(QtGui.QApplication.translate( + "Form", "none", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusLabel_36.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/acquisitionmode", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusValueLineEdit_5.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1/acquisitionmode", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusCommandButton.setModel(QtGui.QApplication.translate( + "Form", "mntgrp/v3/mg1", None, QtGui.QApplication.UnicodeUTF8)) + self.taurusCommandButton.setCommand(QtGui.QApplication.translate( + "Form", "start", None, QtGui.QApplication.UnicodeUTF8)) + self.cfgMg1.setText(QtGui.QApplication.translate( + "Form", "...", None, QtGui.QApplication.UnicodeUTF8)) from taurus.qt.qtgui.display import TaurusLabel, TaurusLed from taurus.qt.qtgui.input import TaurusValueLineEdit @@ -340,4 +439,3 @@ def retranslateUi(self, Form): ui.setupUi(Form) Form.show() sys.exit(app.exec_()) - diff --git a/sandbox/motgrp_gui b/sandbox/motgrp_gui index 8fe6364ca7..c782b9952b 100755 --- a/sandbox/motgrp_gui +++ b/sandbox/motgrp_gui @@ -17,11 +17,13 @@ from taurus.qt.qtgui.button import TaurusCommandButton, TaurusLockButton, \ Spin = TaurusValueSpinBox + class CmdButton(TaurusCommandButton): - + def getDisplayValue(self): return "" + class CfgButton(TaurusLauncherButton): def getDisplayValue(self): @@ -29,34 +31,35 @@ class CfgButton(TaurusLauncherButton): DFT_STATE_ICON_SIZE = Qt.QSize(24, 24) DFT_BTN_ICON_SIZE = Qt.QSize(20, 20) -LS_ICON_SIZE = Qt.QSize(16,16) +LS_ICON_SIZE = Qt.QSize(16, 16) DFT_BTN_STYLE = "QPushButton {margin: 0px; padding: 0px;}" + def createPoolPanel(name): panel = QGroupWidget() panel.titleIcon = getIcon(":/applications-system.svg") content = panel.content() panel_l = Qt.QGridLayout() content.setLayout(panel_l) - + stop = TaurusCommandButton(parent=content, command='Stop') stop.setIcon(getIcon(":/stop_sign.svg")) stop.setIconSize(Qt.QSize(48, 48)) - #stop.setStyleSheet(DFT_BTN_STYLE) - #stop.setFlat(True) + # stop.setStyleSheet(DFT_BTN_STYLE) + # stop.setFlat(True) stop.Model = name panel_l.addWidget(stop, 0, 0) - + abort = TaurusCommandButton(parent=content, command='Abort') abort.setIcon(getIcon(":/panic_button.png")) abort.setIconSize(Qt.QSize(48, 48)) - #abort.setStyleSheet(DFT_BTN_STYLE) - #abort.setFlat(True) + # abort.setStyleSheet(DFT_BTN_STYLE) + # abort.setFlat(True) abort.Model = name panel_l.addWidget(abort, 0, 1) return panel - + def createMotorPanel(*names): m_panel = QGroupWidget() @@ -65,45 +68,46 @@ def createMotorPanel(*names): m_panel_l = createMotorLayout(content, *names) content.setLayout(m_panel_l) return m_panel - + + def createMotorLayout(content, *names): m_panel_l = Qt.QGridLayout() m_panel_l.setMargin(4) m_panel_l.setHorizontalSpacing(2) m_panel_l.setVerticalSpacing(2) - monospace = Qt.QFont("Monospace",10) - monospace_small = Qt.QFont("Monospace",8) + monospace = Qt.QFont("Monospace", 10) + monospace_small = Qt.QFont("Monospace", 8) for i, name in enumerate(names): - row = i*2 + row = i * 2 motor = taurus.Device(name) - motor_attrs = [ attr.lower() for attr in motor.get_attribute_list() ] - + motor_attrs = [attr.lower() for attr in motor.get_attribute_list()] + state = TaurusLed(content) state.setMinimumSize(DFT_STATE_ICON_SIZE) state.setMaximumSize(DFT_STATE_ICON_SIZE) state.model = motor.getNormalName() + "/state" - m_panel_l.addWidget( state, row, 0) - + m_panel_l.addWidget(state, row, 0) + label = TaurusLabel(content) label.model = name + "/position?configuration=dev_alias" label.bgRole = None - m_panel_l.addWidget( label, row, 1) - + m_panel_l.addWidget(label, row, 1) + r_value = TaurusLabel(content) r_value.setMinimumWidth(80) r_value.model = name + "/position" m_panel_l.addWidget(r_value, row, 2) - + w_value = Spin(content) w_value.setMinimumWidth(100) w_value.model = name + "/position" m_panel_l.addWidget(w_value, row, 3) - + unit = TaurusLabel(content) unit.model = name + "/position?configuration=unit" unit.bgRole = None m_panel_l.addWidget(unit, row, 4) - + stop = CmdButton(parent=content, command='stop') stop.setIcon(getIcon(":/stop_sign.svg")) stop.setIconSize(DFT_BTN_ICON_SIZE) @@ -119,37 +123,38 @@ def createMotorLayout(content, *names): abort.setFlat(True) abort.Model = name m_panel_l.addWidget(abort, row, 6) - + lock = TaurusLockButton(content) lock.setIconSize(DFT_BTN_ICON_SIZE) lock.setStyleSheet(DFT_BTN_STYLE) lock.setFlat(True) lock.model = name m_panel_l.addWidget(lock, row, 7) - + w = TaurusAttrForm() - w.setMinimumSize(Qt.QSize(500,700)) + w.setMinimumSize(Qt.QSize(500, 700)) cfg = CfgButton(widget=w, icon=":/categories/preferences-system.svg") cfg.setIconSize(DFT_BTN_ICON_SIZE) cfg.setStyleSheet(DFT_BTN_STYLE) cfg.setModel(name) m_panel_l.addWidget(cfg, row, 8) - + status = TaurusLabel(content) font = Qt.QFont(status.font()) font.setPointSize(8) status.setFont(font) status.model = name + "/status" status.bgRole = None - m_panel_l.addWidget(status, row+1, 3, 1, 6) - + m_panel_l.addWidget(status, row + 1, 3, 1, 6) + if "dialposition" in motor_attrs: dial = TaurusLabel(content) dial.model = name + "/dialposition" - m_panel_l.addWidget(dial, row+1, 2) - + m_panel_l.addWidget(dial, row + 1, 2) + if "limit_switches" in motor_attrs: - limitswitches = TaurusLed(content), TaurusLed(content), TaurusLed(content) + limitswitches = TaurusLed(content), TaurusLed( + content), TaurusLed(content) lmswtch_l = Qt.QVBoxLayout() for n, lm_swtch_w in enumerate(limitswitches): lm_swtch_w.setMinimumSize(LS_ICON_SIZE) @@ -159,11 +164,11 @@ def createMotorLayout(content, *names): lm_swtch_w.modelIndex = n lm_swtch_w.onColor = "red" m_panel_l.addItem(lmswtch_l, row, 9, 2, 1) - + m_panel_l.setRowStretch(row, 0) - m_panel_l.setRowStretch(row+1, 0) - - m_panel_l.setRowStretch(row+2, 1) + m_panel_l.setRowStretch(row + 1, 0) + + m_panel_l.setRowStretch(row + 2, 1) m_panel_l.setColumnStretch(0, 0) m_panel_l.setColumnStretch(1, 0) m_panel_l.setColumnStretch(2, 1) @@ -173,34 +178,35 @@ def createMotorLayout(content, *names): m_panel_l.setColumnStretch(6, 0) return m_panel_l + def createMotorGroupPanel(*names): m_panel = QGroupWidget() m_panel.titleIcon = getIcon(":/designer/extra_motor.png") m_panel_l = Qt.QGridLayout() content = m_panel.content() content.setLayout(m_panel_l) - + name = names[0] mg = taurus.Device(name) elements = mg.elementlist state = TaurusLed(content) - state.setMinimumSize(24,24) + state.setMinimumSize(24, 24) label = TaurusLabel(content) m_panel_l.addWidget(state, 0, 0) m_panel_l.addWidget(label, 0, 1) go = Qt.QPushButton("Go") m_panel_l.addWidget(go, 0, 2) m_panel_l.setRowStretch(0, 0) - w_pos_widgets=[] + w_pos_widgets = [] for i, element in enumerate(elements): - row = i+1 + row = i + 1 m_label = Qt.QLabel(element, content) m_panel_l.addWidget(m_label, row, 0) r_value = TaurusLabel(content) r_value.model = name + "/position" r_value.modelIndex = str(i) m_panel_l.addWidget(r_value, row, 1) - w_value = Qt.QDoubleSpinBox() + w_value = Qt.QDoubleSpinBox() w_value.setMinimum(float("-inf")) w_value.setMaximum(float("+inf")) m_panel_l.addWidget(w_value, row, 2) @@ -209,20 +215,22 @@ def createMotorGroupPanel(*names): state.model = name + "/state" label.model = name + "/position?configuration=dev_alias" label.bgRole = None - + go._mg = state.getModelObj().getParentObj() go._positions = w_pos_widgets + class MoveIt(Qt.QObject): + def move(self): try: button = self.sender() - positions = [ w.value() for w in button._positions ] + positions = [w.value() for w in button._positions] button._mg.write_attribute("position", positions) except: traceback.print_exc() go._move = MoveIt() Qt.QObject.connect(go, Qt.SIGNAL("clicked()"), go._move.move) - m_panel_l.setRowStretch(i+2, 1) + m_panel_l.setRowStretch(i + 2, 1) m_panel_l.setColumnStretch(0, 0) m_panel_l.setColumnStretch(1, 0) m_panel_l.setColumnStretch(2, 1) @@ -244,10 +252,10 @@ panel.addDockWidget(Qt.Qt.LeftDockWidgetArea, dock2) dock2_w = Qt.QWidget() dock2.setWidget(dock2_w) -# MOTOR PANEL ------------------------------------------------------------------ +# MOTOR PANEL ------------------------------------------------------------ panel1_l = Qt.QGridLayout() -panel1_l.setContentsMargins(4,4,4,4) +panel1_l.setContentsMargins(4, 4, 4, 4) panel1_l.setSpacing(4) dock1_w.setLayout(panel1_l) @@ -255,7 +263,7 @@ pool_panel = createPoolPanel("Pool_V3_1") pool_panel.title = "Main Control Panel" panel1_l.addWidget(pool_panel, 0, 0) -motors = ["motor%02d" % i for i in range(1,5)] +motors = ["motor%02d" % i for i in range(1, 5)] m1_panel = createMotorPanel(*motors) m1_panel.title = "Motors on motorctrl01" panel1_l.addWidget(m1_panel, 1, 0) @@ -267,17 +275,17 @@ panel1_l.addWidget(pm1_panel, 2, 0, 1, 1) panel1_l.setRowStretch(0, 0) panel1_l.setRowStretch(1, 1) -# MOTOR GROUP PANEL ------------------------------------------------------------ +# MOTOR GROUP PANEL ------------------------------------------------------ mg_panel_style = { - 'start_color' : 'rgb(255, 60, 60)', - 'stop_color' : 'rgb(200, 0, 0)', - 'font_color' : 'rgb(0, 0, 0)', + 'start_color': 'rgb(255, 60, 60)', + 'stop_color': 'rgb(200, 0, 0)', + 'font_color': 'rgb(0, 0, 0)', #'border_radius': '10px', } panel2_l = Qt.QGridLayout() -panel2_l.setContentsMargins(4,4,4,4) +panel2_l.setContentsMargins(4, 4, 4, 4) panel2_l.setSpacing(4) dock2_w.setLayout(panel2_l) @@ -294,9 +302,7 @@ panel2_l.addWidget(mg2_panel, 0, 1) panel2_l.setRowStretch(0, 0) panel2_l.setRowStretch(1, 1) -# MAIN ------------------------------------------------------------------------- +# MAIN ------------------------------------------------------------------- panel.show() sys.exit(app.exec_()) - - diff --git a/sandbox/pool_gui b/sandbox/pool_gui index d55a2157f5..b0ac2c2268 100644 --- a/sandbox/pool_gui +++ b/sandbox/pool_gui @@ -19,11 +19,13 @@ from taurus.qt.qtgui.button import TaurusCommandButton, TaurusLockButton, \ Spin = TaurusValueSpinBox + class CmdButton(TaurusCommandButton): - + def getDisplayValue(self): return "" + class CfgButton(TaurusLauncherButton): def getDisplayValue(self): @@ -31,35 +33,36 @@ class CfgButton(TaurusLauncherButton): DFT_STATE_ICON_SIZE = Qt.QSize(24, 24) DFT_BTN_ICON_SIZE = Qt.QSize(20, 20) -LS_ICON_SIZE = Qt.QSize(16,16) +LS_ICON_SIZE = Qt.QSize(16, 16) DFT_BTN_STYLE = "QPushButton {margin: 0px; padding: 0px;}" + def create_main_panel(tab, pool): name = pool.getNormalName() main_panel = Qt.QWidget(tab) main_panel_l = Qt.QGridLayout() main_panel.setLayout(main_panel_l) - + panel = QGroupWidget() panel.title = "Emergency panel" panel.titleIcon = getIcon(":/applications-system.svg") content = panel.content() panel_l = Qt.QGridLayout() content.setLayout(panel_l) - + stop = TaurusCommandButton(parent=content, command='Stop') stop.setIcon(getIcon(":/stop_sign.svg")) stop.setIconSize(Qt.QSize(48, 48)) - #stop.setStyleSheet(DFT_BTN_STYLE) - #stop.setFlat(True) + # stop.setStyleSheet(DFT_BTN_STYLE) + # stop.setFlat(True) stop.Model = name panel_l.addWidget(stop, 0, 0) - + abort = TaurusCommandButton(parent=content, command='Abort') abort.setIcon(getIcon(":/panic_button.png")) abort.setIconSize(Qt.QSize(48, 48)) - #abort.setStyleSheet(DFT_BTN_STYLE) - #abort.setFlat(True) + # abort.setStyleSheet(DFT_BTN_STYLE) + # abort.setFlat(True) abort.Model = name panel_l.addWidget(abort, 0, 1) @@ -69,17 +72,21 @@ def create_main_panel(tab, pool): MOTION_TYPES = "Motor", "PseudoMotor" + def get_elements(elements, e_type): - ret = [ data for data in elements if data['type'] == e_type ] - ret.sort(cmp = lambda a,b : cmp(a['name'], b['name'])) + ret = [data for data in elements if data['type'] == e_type] + ret.sort(cmp=lambda a, b: cmp(a['name'], b['name'])) return ret + def get_motor_elements(elements): return get_elements(elements, "Motor") + def get_pseudo_motor_elements(elements): return get_elements(elements, "PseudoMotor") + def get_elements_by_controller(elements): ret = {} for elem in elements: @@ -90,6 +97,7 @@ def get_elements_by_controller(elements): ctrl_elems.append(elem) return ret + def create_motor_panel(elements): m_panel = QGroupWidget() m_panel.title = "Motors" @@ -100,26 +108,27 @@ def create_motor_panel(elements): content.setLayout(m_panel_l) return m_panel + def create_motor_layout(content, ctrl_elements): m_panel_l = Qt.QGridLayout() m_panel_l.setMargin(4) m_panel_l.setHorizontalSpacing(2) m_panel_l.setVerticalSpacing(2) - - monospace = Qt.QFont("Monospace",10) - monospace_small = Qt.QFont("Monospace",8) + + monospace = Qt.QFont("Monospace", 10) + monospace_small = Qt.QFont("Monospace", 8) ctrl_element_names = ctrl_elements.keys() - ctrl_element_names.sort(cmp=lambda a,b : cmp(len(ctrl_elements[a]), len(ctrl_elements[b])), + ctrl_element_names.sort(cmp=lambda a, b: cmp(len(ctrl_elements[a]), len(ctrl_elements[b])), reverse=True) - + j = 0 for j, ctrl_name in enumerate(ctrl_element_names): motors = ctrl_elements[ctrl_name] - motor_names = [ motor['name'] for motor in motors ] - + motor_names = [motor['name'] for motor in motors] + ctrl_panel = QGroupWidget(content) - m_panel_l.addWidget(ctrl_panel, j/2, j %2) - + m_panel_l.addWidget(ctrl_panel, j / 2, j % 2) + ctrl_panel.title = "Motors in %s" % ctrl_name ctrl_panel.titleIcon = getIcon(":/designer/extra_motor.png") ctrl_content = ctrl_panel.content() @@ -128,40 +137,40 @@ def create_motor_layout(content, ctrl_elements): ctrl_panel_l.setMargin(4) ctrl_panel_l.setHorizontalSpacing(2) ctrl_panel_l.setVerticalSpacing(2) - + i = 0 for i, name in enumerate(motor_names): t = datetime.datetime.now() - row = i*2 + row = i * 2 motor = taurus.Device(name) - motor_attrs = [ attr.lower() for attr in motor.get_attribute_list() ] - + motor_attrs = [attr.lower() for attr in motor.get_attribute_list()] + state = TaurusLed(ctrl_content) state.setMinimumSize(DFT_STATE_ICON_SIZE) state.setMaximumSize(DFT_STATE_ICON_SIZE) state.model = motor.getNormalName() + "/state" - ctrl_panel_l.addWidget( state, row, 0) - + ctrl_panel_l.addWidget(state, row, 0) + label = TaurusLabel(ctrl_content) label.model = name + "/position?configuration=dev_alias" label.bgRole = None - ctrl_panel_l.addWidget( label, row, 1) - + ctrl_panel_l.addWidget(label, row, 1) + r_value = TaurusLabel(ctrl_content) r_value.setMinimumWidth(80) r_value.model = name + "/position" ctrl_panel_l.addWidget(r_value, row, 2) - + w_value = Spin(ctrl_content) w_value.setMinimumWidth(100) w_value.model = name + "/position" ctrl_panel_l.addWidget(w_value, row, 3) - + unit = TaurusLabel(ctrl_content) unit.model = name + "/position?configuration=unit" unit.bgRole = None ctrl_panel_l.addWidget(unit, row, 4) - + stop = CmdButton(parent=ctrl_content, command='stop') stop.setIcon(getIcon(":/stop_sign.svg")) stop.setIconSize(DFT_BTN_ICON_SIZE) @@ -177,14 +186,14 @@ def create_motor_layout(content, ctrl_elements): abort.setFlat(True) abort.Model = name ctrl_panel_l.addWidget(abort, row, 6) - + # lock = TaurusLockButton(ctrl_content) # lock.setIconSize(DFT_BTN_ICON_SIZE) # lock.setStyleSheet(DFT_BTN_STYLE) # lock.setFlat(True) # lock.model = name # ctrl_panel_l.addWidget(lock, row, 7) - + # w = TaurusAttrForm() # w.setMinimumSize(Qt.QSize(500,700)) # cfg = CfgButton(widget=w, icon=":/categories/preferences-system.svg") @@ -192,22 +201,23 @@ def create_motor_layout(content, ctrl_elements): # cfg.setStyleSheet(DFT_BTN_STYLE) # cfg.setModel(name) # ctrl_panel_l.addWidget(cfg, row, 8) - + status = TaurusLabel(ctrl_content) font = Qt.QFont(status.font()) font.setPointSize(8) status.setFont(font) status.model = name + "/status" status.bgRole = None - ctrl_panel_l.addWidget(status, row+1, 3, 1, 6) - + ctrl_panel_l.addWidget(status, row + 1, 3, 1, 6) + if "dialposition" in motor_attrs: dial = TaurusLabel(ctrl_content) dial.model = name + "/dialposition" - ctrl_panel_l.addWidget(dial, row+1, 2) - + ctrl_panel_l.addWidget(dial, row + 1, 2) + if "limit_switches" in motor_attrs: - limitswitches = TaurusLed(ctrl_content), TaurusLed(ctrl_content), TaurusLed(ctrl_content) + limitswitches = TaurusLed(ctrl_content), TaurusLed( + ctrl_content), TaurusLed(ctrl_content) lmswtch_l = Qt.QVBoxLayout() for n, lm_swtch_w in enumerate(limitswitches): lm_swtch_w.setMinimumSize(LS_ICON_SIZE) @@ -217,13 +227,13 @@ def create_motor_layout(content, ctrl_elements): lm_swtch_w.modelIndex = n lm_swtch_w.onColor = "red" ctrl_panel_l.addItem(lmswtch_l, row, 9, 2, 1) - + ctrl_panel_l.setRowStretch(row, 0) - ctrl_panel_l.setRowStretch(row+1, 0) - - print "Created", name,"took", datetime.datetime.now()-t - - ctrl_panel_l.setRowStretch(row+2, 1) + ctrl_panel_l.setRowStretch(row + 1, 0) + + print "Created", name, "took", datetime.datetime.now() - t + + ctrl_panel_l.setRowStretch(row + 2, 1) ctrl_panel_l.setColumnStretch(0, 0) ctrl_panel_l.setColumnStretch(1, 0) ctrl_panel_l.setColumnStretch(2, 1) @@ -231,12 +241,13 @@ def create_motor_layout(content, ctrl_elements): ctrl_panel_l.setColumnStretch(4, 0) ctrl_panel_l.setColumnStretch(5, 0) ctrl_panel_l.setColumnStretch(6, 0) - + m_panel_l.setRowStretch(j, 0) - - m_panel_l.setRowStretch(j+1, 1) + + m_panel_l.setRowStretch(j + 1, 1) return m_panel_l + def create_motion_panel(tab, pool, elements): motion_panel = Qt.QWidget(tab) motion_panel_l = Qt.QGridLayout() @@ -246,23 +257,25 @@ def create_motion_panel(tab, pool, elements): motion_panel_l.addWidget(motor_panel) return motion_panel + def gui(model): pool = taurus.Device(model) elements = CodecFactory().decode(pool.elements, ensure_ascii=True)['new'] window = Qt.QMainWindow() window.setWindowTitle("Pool %s test" % pool.getSimpleName()) - + tab = Qt.QTabWidget(window) window.setCentralWidget(tab) - + main_panel = create_main_panel(tab, pool) tab.addTab(main_panel, "Main") - + motion_panel = create_motion_panel(tab, pool, elements) tab.addTab(motion_panel, "Motion") - + return window + def main(): parser = get_taurus_parser() parser.usage = "%prog [options] " diff --git a/sardanaConfig/doc/source/conf.py b/sardanaConfig/doc/source/conf.py index 0852894972..ed0df0a3b9 100644 --- a/sardanaConfig/doc/source/conf.py +++ b/sardanaConfig/doc/source/conf.py @@ -11,7 +11,8 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import sys +import os local_dir = os.path.dirname(os.path.abspath(__file__)) d = os.path.join(local_dir, "..", "..", "src", "wizards") @@ -22,7 +23,7 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) -# -- General configuration ----------------------------------------------------- +# -- General configuration ----------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' @@ -91,7 +92,7 @@ #modindex_common_prefix = [] -# -- Options for HTML output --------------------------------------------------- +# -- Options for HTML output --------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. @@ -171,7 +172,7 @@ htmlhelp_basename = 'sardanaConfigdoc' -# -- Options for LaTeX output -------------------------------------------------- +# -- Options for LaTeX output -------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' @@ -182,8 +183,8 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'sardanaConfig.tex', u'sardanaConfig Documentation', - u'Marek', 'manual'), + ('index', 'sardanaConfig.tex', u'sardanaConfig Documentation', + u'Marek', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -210,7 +211,7 @@ #latex_domain_indices = True -# -- Options for manual page output -------------------------------------------- +# -- Options for manual page output -------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). diff --git a/sardanaConfig/src/wizards/add_device_wizard.py b/sardanaConfig/src/wizards/add_device_wizard.py index 34f3eadf0f..1c2292425f 100644 --- a/sardanaConfig/src/wizards/add_device_wizard.py +++ b/sardanaConfig/src/wizards/add_device_wizard.py @@ -1,4 +1,11 @@ -import os, sys, wx, copy, taurus, settings_widget, simple_tree_model, wiz +import os +import sys +import wx +import copy +import taurus +import settings_widget +import simple_tree_model +import wiz import taurus.qt.qtgui.resource from PyQt4 import QtGui, QtCore, Qt from types import * @@ -14,14 +21,15 @@ - OutroPage """ + class SelectSardanaPoolBasePage(wiz.SardanaBasePage): """Page for selecting Sardana and Pool - + Selected values are saved in - + self['sardana'] self['pool'] - + """ def __init__(self, sardana=None, pool=None, parent=None): @@ -35,19 +43,24 @@ def __init__(self, sardana=None, pool=None, parent=None): layout = QtGui.QGridLayout() self._sardanaNameCB = QtGui.QComboBox() self._poolNameCB = QtGui.QComboBox() - layout.addItem(QtGui.QSpacerItem(60, 60, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum), 0, 0) + layout.addItem(QtGui.QSpacerItem( + 60, 60, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum), 0, 0) layout.addWidget(QtGui.QLabel("Sardana"), 0, 1) - layout.addItem(QtGui.QSpacerItem(60, 60, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum), 0, 3) + layout.addItem(QtGui.QSpacerItem( + 60, 60, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum), 0, 3) layout.addWidget(self._sardanaNameCB, 0, 2) layout.addWidget(QtGui.QLabel("Pool"), 1, 1) layout.addWidget(self._poolNameCB, 1, 2) - layout.addItem(QtGui.QSpacerItem(200, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum), 2, 2) + layout.addItem(QtGui.QSpacerItem( + 200, 10, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum), 2, 2) self._panel.setLayout(layout) - self.setStatus("Select the instances of Sardana and Pool, and click Next to continue") + self.setStatus( + "Select the instances of Sardana and Pool, and click Next to continue") self['sardana'] = self._getSardana self['pool'] = self._getPool - self.connect(self._sardanaNameCB, QtCore.SIGNAL('currentIndexChanged(int)'), self._fillPoolNameCB) + self.connect(self._sardanaNameCB, QtCore.SIGNAL( + 'currentIndexChanged(int)'), self._fillPoolNameCB) def initializePage(self): wiz.SardanaBasePage.initializePage(self) @@ -126,23 +139,25 @@ def currentFields(self): def activated(self, index): self.emit(QtCore.SIGNAL("activated"), self.model().asRecord(index)) - def expanded(self): if not self.model() == None: for column in range(self.model().columnCount( QtCore.QModelIndex())): self.resizeColumnToContents(column) + class AxisSteper(Qt.QSpinBox): """ Object of this class is a Spin box that can jumps from 1 to the total number of axis while skipping busy values """ + def __init__(self, controllerInfo=None, busyValues=[], parent=None): Qt.QSpinBox.__init__(self, parent) self._busyValues = busyValues self._controllerInfo = controllerInfo self.setControllerInfo(controllerInfo) - QtCore.QObject.connect(self.lineEdit(), QtCore.SIGNAL("editingFinished()"), self._textEdited) + QtCore.QObject.connect(self.lineEdit(), QtCore.SIGNAL( + "editingFinished()"), self._textEdited) def _textEdited(self): axis = int(self.value()) @@ -188,6 +203,7 @@ class SingleAxisWidget(Qt.QWidget): """ Widget for selecting name and axis for the device """ + def __init__(self, parent=None): Qt.QWidget.__init__(self, parent) self._layout = QtGui.QGridLayout(self) @@ -207,8 +223,10 @@ def setupUi(self): self._axisSpinBox = AxisSteper() self._layout.addWidget(self._axisLabel, 1, 0, 1, 1) self._layout.addWidget(self._axisSpinBox, 1, 1, 1, 1) - QtCore.QObject.connect(self._axisSpinBox.lineEdit(), QtCore.SIGNAL("textEdited(QString)"), self._textEdited) - QtCore.QObject.connect(self._nameLineEdit, QtCore.SIGNAL("textEdited(QString)"), self._textEdited) + QtCore.QObject.connect(self._axisSpinBox.lineEdit(), QtCore.SIGNAL( + "textEdited(QString)"), self._textEdited) + QtCore.QObject.connect(self._nameLineEdit, QtCore.SIGNAL( + "textEdited(QString)"), self._textEdited) def _textEdited(self, str): self._edited = True @@ -247,13 +265,14 @@ def getValue(self): def textChanged(self, string): QtGui.QLineEdit.textChanged(self, string) - def focusOutEvent (self, event): #QFocusEvent + def focusOutEvent(self, event): # QFocusEvent QtGui.QLineEdit.focusOutEvent(self, event) self.valueChanged() def valueChanged(self): if not (self.getValue() == self._actualValue): - self.emit(QtCore.SIGNAL("valueChanged"), self._actualValue, self.getValue()) + self.emit(QtCore.SIGNAL("valueChanged"), + self._actualValue, self.getValue()) self._actualValue = self.getValue() self.setValue(self.getValue()) # if value is not valid @@ -261,6 +280,7 @@ def valueChanged(self): def getDefaultValue(self): return "" + class TableAxisDelegate(QtGui.QItemDelegate): """ Item delegate for Table Axis Widget @@ -277,7 +297,8 @@ def createEditor(self, parent, option, index): editor = NameEditorWidget(parent) editor.installEventFilter(self) if index.column() == 1: - editor = AxisSteper(self._controllerInfo, self.parent().parent().getAxisList(), parent=parent) + editor = AxisSteper(self._controllerInfo, self.parent( + ).parent().getAxisList(), parent=parent) editor.installEventFilter(self) return editor @@ -288,18 +309,18 @@ def setEditorData(self, editor, index): editor.setValue(value.toString()) if index.column() == 1: value = index.model().data(index, QtCore.Qt.DisplayRole) - int , bool = value.toInt() + int, bool = value.toInt() editor.setValue(int) def setModelData(self, editor, model, index): - self.emit(QtCore.SIGNAL("editorValueChanged"), editor.getValue(), index.row(), index.column()) + self.emit(QtCore.SIGNAL("editorValueChanged"), + editor.getValue(), index.row(), index.column()) value = editor.getValue() - if index.column() == 0: #name - model.setData(index - , QtCore.QVariant(value)) - if index.column() == 1: #axis + if index.column() == 0: # name + model.setData(index, QtCore.QVariant(value)) + if index.column() == 1: # axis if editor.is_axis_free(int(value)): - model.setData(index , QtCore.QVariant(value)) + model.setData(index, QtCore.QVariant(value)) def updateEditorGeometry(self, editor, option, index): editor.setGeometry(option.rect) @@ -309,6 +330,7 @@ class TableAxisWidget (QtGui.QWidget): """ Table for selecting multiple axis """ + def __init__(self, value=None, parent=None): QtGui.QWidget.__init__(self, parent) self._controllerInfo = None @@ -320,11 +342,13 @@ def __init__(self, value=None, parent=None): self._layout.addWidget(self._tableView) self._verticalLayout = QtGui.QVBoxLayout() self._addRowButton = QtGui.QPushButton(self) - self._addRowButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-add")) + self._addRowButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-add")) self._addRowButton.setText("Add Device ") self._verticalLayout.addWidget(self._addRowButton) self._removeRowButton = QtGui.QPushButton(self) - self._removeRowButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-remove")) + self._removeRowButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-remove")) self._removeRowButton.setText("Remove Device ") self._verticalLayout.addWidget(self._removeRowButton) self._upButton = QtGui.QPushButton(self) @@ -332,22 +356,30 @@ def __init__(self, value=None, parent=None): self._upButton.setText("Move Up ") self._verticalLayout.addWidget(self._upButton) self._downButton = QtGui.QPushButton(self) - self._downButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("go-down")) + self._downButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("go-down")) self._downButton.setText("Move Down") self._verticalLayout.addWidget(self._downButton) - spacerItem = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacerItem = QtGui.QSpacerItem( + 20, 20, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self._verticalLayout.addItem(spacerItem) - QtCore.QObject.connect(self._addRowButton, QtCore.SIGNAL("clicked()"), self._addRow) - QtCore.QObject.connect(self._removeRowButton, QtCore.SIGNAL("clicked()"), self._removeRow) - QtCore.QObject.connect(self._upButton, QtCore.SIGNAL("clicked()"), self._moveUp) - QtCore.QObject.connect(self._downButton, QtCore.SIGNAL("clicked()"), self._moveDown) + QtCore.QObject.connect( + self._addRowButton, QtCore.SIGNAL("clicked()"), self._addRow) + QtCore.QObject.connect(self._removeRowButton, + QtCore.SIGNAL("clicked()"), self._removeRow) + QtCore.QObject.connect( + self._upButton, QtCore.SIGNAL("clicked()"), self._moveUp) + QtCore.QObject.connect( + self._downButton, QtCore.SIGNAL("clicked()"), self._moveDown) self._layout.addLayout(self._verticalLayout) self._delegate = TableAxisDelegate(self._tableView) #QtCore.QObject.connect(self._delegate, QtCore.SIGNAL("editorValueChanged"), self._valueChanged) self._tableView.setItemDelegate(self._delegate) - QtCore.QObject.connect(self._delegate, QtCore.SIGNAL("editorValueChanged"), self._textEdited) - #self._tableView.setItemDelegate(self._delegate) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding) + QtCore.QObject.connect(self._delegate, QtCore.SIGNAL( + "editorValueChanged"), self._textEdited) + # self._tableView.setItemDelegate(self._delegate) + sizePolicy = QtGui.QSizePolicy( + QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding) self._tableView.setSizePolicy(sizePolicy) self._tableView.horizontalHeader().setDefaultSectionSize(80) self._tableView.horizontalHeader().setVisible(True) @@ -390,7 +422,7 @@ def setControllerInfo(self, controllerInfo): self._edited = False def _getSelectedIndex(self): - if len (self._tableView.selectedIndexes()): + if len(self._tableView.selectedIndexes()): row = self._tableView.selectedIndexes()[0].row() column = self._tableView.selectedIndexes()[0].column() else: @@ -418,36 +450,39 @@ def _removeRow(self): if rowIndex is not None: msgBox = QtGui.QMessageBox() msgBox.setText("Confirmation ") - msgBox.setStandardButtons(QtGui.QMessageBox().No | QtGui.QMessageBox().Yes) + msgBox.setStandardButtons( + QtGui.QMessageBox().No | QtGui.QMessageBox().Yes) msgBox.setInformativeText("Remove device {%i} ?" % (rowIndex + 1)) msgBox.setIcon(QtGui.QMessageBox.Question) ret = msgBox.exec_() if ret == QtGui.QMessageBox().Yes: - value = self.getValue() - self.setValue(value[:rowIndex] + value[rowIndex + 1:]) - self._textEdited() - self._addRowButton.setEnabled(True) + value = self.getValue() + self.setValue(value[:rowIndex] + value[rowIndex + 1:]) + self._textEdited() + self._addRowButton.setEnabled(True) def _moveUp(self): value = self.getValue() # stored table rows = len(value) rowIndex = self._getSelectedIndex()[0] - if (rows > 1) and (rowIndex is not None) and (rowIndex > 0) : + if (rows > 1) and (rowIndex is not None) and (rowIndex > 0): x = value.pop(rowIndex) value.insert(rowIndex - 1, x) self.setValue(value) - self._tableView.setCurrentIndex(self._tableView.model().index(rowIndex - 1, 0)) + self._tableView.setCurrentIndex( + self._tableView.model().index(rowIndex - 1, 0)) self._textEdited() def _moveDown(self): value = self.getValue() # stored table rows = len(value) rowIndex = self._getSelectedIndex()[0] - if (rows > 1) and (rowIndex is not None) and (rowIndex < rows - 1) : + if (rows > 1) and (rowIndex is not None) and (rowIndex < rows - 1): x = value.pop(rowIndex) value.insert(rowIndex + 1, x) self.setValue(value) - self._tableView.setCurrentIndex(self._tableView.model().index(rowIndex + 1, 0)) + self._tableView.setCurrentIndex( + self._tableView.model().index(rowIndex + 1, 0)) self._textEdited() def setValue(self, value): @@ -537,9 +572,12 @@ def setupUi(self): self._multipleAxisWidget = MultipleAxisWidget() self._layout.addWidget(self._multipleAxisWidget, 2, 0, 1, 2) - QtCore.QObject.connect(self._singleButton, QtCore.SIGNAL("clicked()"), self._changeView) - QtCore.QObject.connect(self._multipleButton, QtCore.SIGNAL("clicked()"), self._changeView) - self._spacerItem1 = Qt.QSpacerItem(10, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) + QtCore.QObject.connect(self._singleButton, QtCore.SIGNAL( + "clicked()"), self._changeView) + QtCore.QObject.connect(self._multipleButton, + QtCore.SIGNAL("clicked()"), self._changeView) + self._spacerItem1 = Qt.QSpacerItem( + 10, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) self._layout.addItem(self._spacerItem1, 4, 0, 1, 1, Qt.Qt.AlignCenter) def _changeView(self): @@ -573,7 +611,7 @@ def __init__(self, parent=None): self.setLayout(self._layout) self.setTitle('Selecting device') self.connect(self._treeView, QtCore.SIGNAL("activated"), - self.activated) + self.activated) self._currentItem = None self._currentItemIndex = None @@ -601,8 +639,10 @@ def checkData(self): def keyPressEvent(self, event): wiz.SardanaBasePage.keyPressEvent(self, event) if self._tabWidget.currentIndex() == 0: - undo = (event.modifiers() == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Z) - redo = (event.modifiers() == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Y) + undo = (event.modifiers() == + QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Z) + redo = (event.modifiers() == + QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Y) if (undo): self._settings.undo() if (redo): @@ -612,26 +652,30 @@ def initializePage(self): wiz.SardanaIntroBasePage.initializePage(self) self.wizard().__setitem__("properties", self.getProperties) # resizing application - self._previousPageSize = copy.deepcopy([self.wizard().size().width(), self.wizard().size().height()]) + self._previousPageSize = copy.deepcopy( + [self.wizard().size().width(), self.wizard().size().height()]) preferedSize = [800, 600] desktopRect = QtGui.QApplication.desktop().availableGeometry(self) center = desktopRect.center() - if (not self.wizard().isMaximized()) and (self.wizard().size().height () < preferedSize[1]) and (self.wizard().size().width() < preferedSize[0]): + if (not self.wizard().isMaximized()) and (self.wizard().size().height() < preferedSize[1]) and (self.wizard().size().width() < preferedSize[0]): self.wizard().resize(preferedSize[0], preferedSize[1]) - self.wizard().move(center.x() - self.wizard().width() * 0.5, center.y() - self.wizard().height() * 0.5) + self.wizard().move(center.x() - self.wizard().width() * + 0.5, center.y() - self.wizard().height() * 0.5) self._pool = self.wizard()["pool"] self._loadTreeModel() self.checkData() def cleanupPage(self): wiz.SardanaIntroBasePage.cleanupPage(self) - preferedSize = copy.deepcopy(self._previousPageSize) # setUp size for previous page + # setUp size for previous page + preferedSize = copy.deepcopy(self._previousPageSize) desktopRect = QtGui.QApplication.desktop().availableGeometry(self) center = desktopRect.center() - if (not self.wizard().isMaximized()) and (self.wizard().size().height () > preferedSize[1]) and (self.wizard().size().width() > preferedSize[0]): + if (not self.wizard().isMaximized()) and (self.wizard().size().height() > preferedSize[1]) and (self.wizard().size().width() > preferedSize[0]): self.wizard().resize(preferedSize[0], preferedSize[1]) - self.wizard().move(center.x() - self.wizard().width() * 0.5, center.y() - self.wizard().height() * 0.5) + self.wizard().move(center.x() - self.wizard().width() * + 0.5, center.y() - self.wizard().height() * 0.5) def _loadTreeModel(self): @@ -641,20 +685,23 @@ def _loadTreeModel(self): self.model.sort(-1) for item in controllerinfos: - self.model.addRecord(["Controller", PoolElementType[item.get_controller_type()] , item.get_name()], item , False) + self.model.addRecord(["Controller", PoolElementType[ + item.get_controller_type()], item.get_name()], item, False) elementTypeList = PoolElementType.keys() elementTypeList.sort() for type in elementTypeList: self.model.addNodes([type], False) for item in controllers: - self.model.addRecord([PoolElementType[item.get_controller_type()], item.get_name() ], item , False) + self.model.addRecord( + [PoolElementType[item.get_controller_type()], item.get_name()], item, False) self._treeView.setModel(self.model) def setupUi(self): self._treeView = SimpleTreeView(self) - self._treeView.setSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) + self._treeView.setSizePolicy( + QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) self._layout.addWidget(self._treeView, 0, 0, 1, 1) self._tabWidget = QtGui.QTabWidget(self) self._settingsTab = QtGui.QWidget(self) @@ -663,7 +710,8 @@ def setupUi(self): self._scrollArea.setFrameShape(QtGui.QFrame.NoFrame) self._scrollArea.setWidgetResizable(True) self._scrollAreaWidgetContents = QtGui.QWidget(self._scrollArea) - self._scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 263, 316)) + self._scrollAreaWidgetContents.setGeometry( + QtCore.QRect(0, 0, 263, 316)) self._gridLayout_2 = QtGui.QGridLayout(self._scrollAreaWidgetContents) self._settings = settings_widget.SettingsWidget() self._hardwareSettings = HardwareSettings() @@ -677,13 +725,15 @@ def setupUi(self): self._scrollArea_2.setFrameShape(QtGui.QFrame.NoFrame) self._scrollArea_2.setWidgetResizable(True) self._scrollAreaWidgetContents_2 = QtGui.QWidget(self._scrollArea_2) - self._gridLayout_3 = QtGui.QGridLayout(self._scrollAreaWidgetContents_2) + self._gridLayout_3 = QtGui.QGridLayout( + self._scrollAreaWidgetContents_2) self._description = DescriptionWidget() self._gridLayout_3.addWidget(self._description) self._scrollArea_2.setWidget(self._scrollAreaWidgetContents_2) self._horizontalLayout.addWidget(self._scrollArea_2) self._tabWidget.addTab(self._descriptionTab, "Description") - self._tabWidget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) + self._tabWidget.setSizePolicy( + QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self._layout.addWidget(self._tabWidget, 0, 1, 1, 2) self._tabWidget.setCurrentIndex(0) @@ -714,8 +764,10 @@ def activated(self, name): if self._settings.isEdited() or self._hardwareSettings.isEdited(): msgBox = QtGui.QMessageBox() msgBox.setText("Confirmation ") - msgBox.setStandardButtons(QtGui.QMessageBox().No | QtGui.QMessageBox().Yes) - msgBox.setInformativeText("Do you want to leave the editor of %s without saving the changes?" % self._currentItem.get_name()) + msgBox.setStandardButtons( + QtGui.QMessageBox().No | QtGui.QMessageBox().Yes) + msgBox.setInformativeText( + "Do you want to leave the editor of %s without saving the changes?" % self._currentItem.get_name()) msgBox.setIcon(QtGui.QMessageBox.Question) ret = msgBox.exec_() @@ -735,13 +787,16 @@ def activated(self, name): self._tabWidget.setTabEnabled(1, True) self.setStatus("Editing: " + self.picked().get_name()) - - self._settings.setProperties(self.picked().get_properties()) - QtCore.QObject.connect(self._settings, QtCore.SIGNAL("propertyValueChanged()"), self.checkData) - self._description.setOrganization(self.picked().get_organization()) + self._settings.setProperties( + self.picked().get_properties()) + QtCore.QObject.connect(self._settings, QtCore.SIGNAL( + "propertyValueChanged()"), self.checkData) + self._description.setOrganization( + self.picked().get_organization()) self._description.setFamily(self.picked().get_family()) self._description.setModel(self.picked().get_model()) - self._description.setDescription(self.picked().get_description()) + self._description.setDescription( + self.picked().get_description()) self._description.setImage(None) if type(self._currentItem) == taurus.core.tango.sardana.sardana.ControllerInfo: @@ -754,8 +809,8 @@ def activated(self, name): self._tabWidget.setTabEnabled(1, False) self.setStatus("Editing: " + self.picked().get_name()) else: - self._treeView.selectionModel().setCurrentIndex(self._currentItemIndex, QtGui.QItemSelectionModel.SelectCurrent) - + self._treeView.selectionModel().setCurrentIndex( + self._currentItemIndex, QtGui.QItemSelectionModel.SelectCurrent) self.checkData() @@ -773,7 +828,8 @@ class NewDeviceCommitBasePage(wiz.SardanaIntroBasePage): def __init__(self, parent=None): QtGui.QWizardPage.__init__(self, parent) - self.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap(":/watermark.jpg")) + self.setPixmap(QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(":/watermark.jpg")) self._layout = QtGui.QFormLayout() self.setCommitPage(True) self.setTitle('Confirmation') @@ -789,26 +845,33 @@ def _set_style(self, w): def initializePage(self): wiz.SardanaIntroBasePage.initializePage(self) - self._previousPageSize = copy.deepcopy([self.wizard().size().width(), self.wizard().size().height()]) - self.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap(":/watermark.jpg")) - self._spacerItem1 = QtGui.QSpacerItem(800, 600, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) + self._previousPageSize = copy.deepcopy( + [self.wizard().size().width(), self.wizard().size().height()]) + self.setPixmap(QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(":/watermark.jpg")) + self._spacerItem1 = QtGui.QSpacerItem( + 800, 600, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self._layout.addItem(self._spacerItem1) preferedSize = [600, 600] # prefered size for this page desktopRect = QtGui.QApplication.desktop().availableGeometry(self) center = desktopRect.center() if (not self.wizard().isMaximized()): self.wizard().resize(preferedSize[0], preferedSize[1]) - self.wizard().move(center.x() - self.wizard().width() * 0.5, center.y() - self.wizard().height() * 0.5) - # and (self.wizard().size().height () > preferedSize[1]) and (self.wizard().size().width() > preferedSize[0]): + self.wizard().move(center.x() - self.wizard().width() * + 0.5, center.y() - self.wizard().height() * 0.5) + # and (self.wizard().size().height () > preferedSize[1]) and + # (self.wizard().size().width() > preferedSize[0]): def cleanupPage(self): wiz.SardanaIntroBasePage.cleanupPage(self) self.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap()) - preferedSize = copy.deepcopy(self._previousPageSize) # setUp size for previous page + # setUp size for previous page + preferedSize = copy.deepcopy(self._previousPageSize) desktopRect = QtGui.QApplication.desktop().availableGeometry(self) center = desktopRect.center() - if (not self.wizard().isMaximized()) and (self.wizard().size().height () < preferedSize[1]) and (self.wizard().size().width() < preferedSize[0]): - self.wizard().move(center.x() - preferedSize[0] * 0.5, center.y() - preferedSize[1] * 0.5) + if (not self.wizard().isMaximized()) and (self.wizard().size().height() < preferedSize[1]) and (self.wizard().size().width() < preferedSize[0]): + self.wizard().move( + center.x() - preferedSize[0] * 0.5, center.y() - preferedSize[1] * 0.5) self.wizard().resize(preferedSize[0], preferedSize[1]) def setNextPageId(self, id): @@ -828,41 +891,52 @@ def setupUi(self): self._imageSize = [100, 100] self._formLayout = QtGui.QFormLayout(self) self._organizationLabel = QtGui.QLabel("Organization:") - self._formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self._organizationLabel) + self._formLayout.setWidget( + 0, QtGui.QFormLayout.LabelRole, self._organizationLabel) self._organizationLabelText = QtGui.QLabel(self) self._organizationLabelText.setFrameShape(QtGui.QFrame.Panel) self._organizationLabelText.setFrameShadow(QtGui.QFrame.Sunken) self._organizationLabelText.setWordWrap(False) - self._formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self._organizationLabelText) + self._formLayout.setWidget( + 0, QtGui.QFormLayout.FieldRole, self._organizationLabelText) self._familyLabel = QtGui.QLabel("Family:") - self._formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self._familyLabel) + self._formLayout.setWidget( + 1, QtGui.QFormLayout.LabelRole, self._familyLabel) self._familyLabelText = QtGui.QLabel(self) self._familyLabelText.setFrameShape(QtGui.QFrame.Panel) self._familyLabelText.setFrameShadow(QtGui.QFrame.Sunken) self._familyLabelText.setWordWrap(False) - self._formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self._familyLabelText) + self._formLayout.setWidget( + 1, QtGui.QFormLayout.FieldRole, self._familyLabelText) self._modelLabel = QtGui.QLabel("Model:") - self._formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self._modelLabel) + self._formLayout.setWidget( + 2, QtGui.QFormLayout.LabelRole, self._modelLabel) self._modelLabelText = QtGui.QLabel(self) self._modelLabelText.setFrameShape(QtGui.QFrame.Panel) self._modelLabelText.setFrameShadow(QtGui.QFrame.Sunken) self._modelLabelText.setWordWrap(False) - self._formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self._modelLabelText) + self._formLayout.setWidget( + 2, QtGui.QFormLayout.FieldRole, self._modelLabelText) self._descriptionLabel = QtGui.QLabel("Description:") - self._formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self._descriptionLabel) + self._formLayout.setWidget( + 3, QtGui.QFormLayout.LabelRole, self._descriptionLabel) self._descriptionLabelText = QtGui.QLabel(self) self._descriptionLabelText.setFrameShape(QtGui.QFrame.Panel) self._descriptionLabelText.setFrameShadow(QtGui.QFrame.Sunken) self._descriptionLabelText.setWordWrap(True) self._descriptionLabelText.setAlignment(QtCore.Qt.AlignTop) - self._formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self._descriptionLabelText) + self._formLayout.setWidget( + 3, QtGui.QFormLayout.FieldRole, self._descriptionLabelText) self._imageLabel = QtGui.QLabel("Image:") - self._formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self._imageLabel) + self._formLayout.setWidget( + 4, QtGui.QFormLayout.LabelRole, self._imageLabel) self._deviceLogo = QtGui.QLabel(self) - self._deviceLogo.setPixmap(taurus.qt.qtgui.resource.getThemePixmap("image-missing").scaled(*self._imageSize)) + self._deviceLogo.setPixmap(taurus.qt.qtgui.resource.getThemePixmap( + "image-missing").scaled(*self._imageSize)) self._deviceLogo.pixmap() self._deviceLogo.setAlignment(QtCore.Qt.AlignHCenter) - self._formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self._deviceLogo) + self._formLayout.setWidget( + 4, QtGui.QFormLayout.FieldRole, self._deviceLogo) def setOrganization(self, name): self._organizationLabelText.setText(name) @@ -880,15 +954,18 @@ def setImage(self, image): if type(image) == QtGui.QPixmap: self._deviceLogo.setPixmap(image.scaled(*self._imageSize)) elif type(image) == QtGui.QImage: - self._deviceLogo.setPixmap(QtGui.QPixmap().fromImage(image).scaled(*self._imageSize)) + self._deviceLogo.setPixmap( + QtGui.QPixmap().fromImage(image).scaled(*self._imageSize)) else: - self._deviceLogo.setPixmap(taurus.qt.qtgui.resource.getThemePixmap("image-missing").scaled(50, 50)) + self._deviceLogo.setPixmap( + taurus.qt.qtgui.resource.getThemePixmap("image-missing").scaled(50, 50)) def addDevice(Sardana=None, Pool=None): app = QtGui.QApplication([]) QtCore.QResource.registerResource(get_resources()) - Pages = Enumeration('Pages', ('SelectSardanaPool', 'NewDevice', 'CommitPage', 'OutroPage')) + Pages = Enumeration('Pages', ('SelectSardanaPool', + 'NewDevice', 'CommitPage', 'OutroPage')) w = wiz.SardanaBaseWizard() w.setWindowTitle("Add New Hardware Wizard") selectPool = SelectSardanaPoolBasePage(Sardana, Pool) @@ -903,6 +980,7 @@ def addDevice(Sardana=None, Pool=None): w.show() sys.exit(app.exec_()) + def get_resources(): res_fname = os.path.abspath(__file__) res_fname = os.path.splitext(res_fname)[0] + '.rcc' diff --git a/sardanaConfig/src/wizards/add_new_hw.py b/sardanaConfig/src/wizards/add_new_hw.py index 7feb4961dd..c388af5b06 100644 --- a/sardanaConfig/src/wizards/add_new_hw.py +++ b/sardanaConfig/src/wizards/add_new_hw.py @@ -1,4 +1,5 @@ -import os, sys +import os +import sys from PyQt4 import QtGui, QtCore, Qt import wiz @@ -8,11 +9,10 @@ from pool_page import SelectPoolBasePage - def main(): app = QtGui.QApplication([]) QtCore.QResource.registerResource(wiz.get_resources()) sys.exit(app.exec_()) - + if __name__ == "__main__": main() diff --git a/sardanaConfig/src/wizards/ms_editor_UI.py b/sardanaConfig/src/wizards/ms_editor_UI.py index 8b7ba364be..ded18c995e 100644 --- a/sardanaConfig/src/wizards/ms_editor_UI.py +++ b/sardanaConfig/src/wizards/ms_editor_UI.py @@ -9,7 +9,9 @@ from PyQt4 import QtCore, QtGui + class Ui_MSEditor(object): + def setupUi(self, MSEditor): MSEditor.setObjectName("MSEditor") MSEditor.resize(400, 429) @@ -82,7 +84,8 @@ def setupUi(self, MSEditor): self.msPathList = QtGui.QListWidget(self.groupBox) self.msPathList.setMouseTracking(True) self.msPathList.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) - self.msPathList.setSelectionBehavior(QtGui.QAbstractItemView.SelectItems) + self.msPathList.setSelectionBehavior( + QtGui.QAbstractItemView.SelectItems) self.msPathList.setObjectName("msPathList") self.horizontalLayout.addWidget(self.msPathList) self.verticalLayout = QtGui.QVBoxLayout() @@ -103,7 +106,8 @@ def setupUi(self, MSEditor): self.gridLayout.addWidget(self.groupBox, 1, 0, 1, 1) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") - spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + spacerItem = QtGui.QSpacerItem( + 40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem) self.createButton = QtGui.QPushButton(MSEditor) self.createButton.setObjectName("createButton") @@ -114,31 +118,53 @@ def setupUi(self, MSEditor): self.gridLayout.addLayout(self.horizontalLayout_2, 2, 0, 1, 1) self.retranslateUi(MSEditor) - QtCore.QObject.connect(self.msDeviceNameCheckBox, QtCore.SIGNAL("toggled(bool)"), self.msDeviceNameLineEdit.setDisabled) - QtCore.QObject.connect(self.msAliasCheckBox, QtCore.SIGNAL("toggled(bool)"), self.msAliasLineEdit.setDisabled) - QtCore.QObject.connect(self.msVersionCheckBox, QtCore.SIGNAL("toggled(bool)"), self.msVersionLineEdit.setDisabled) - QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), MSEditor.close) - QtCore.QObject.connect(self.doorNameCheckBox, QtCore.SIGNAL("toggled(bool)"), self.doorNameLineEdit.setDisabled) - QtCore.QObject.connect(self.doorAliasCheckBox, QtCore.SIGNAL("toggled(bool)"), self.doorAliasLineEdit.setDisabled) + QtCore.QObject.connect(self.msDeviceNameCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self.msDeviceNameLineEdit.setDisabled) + QtCore.QObject.connect(self.msAliasCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self.msAliasLineEdit.setDisabled) + QtCore.QObject.connect(self.msVersionCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self.msVersionLineEdit.setDisabled) + QtCore.QObject.connect( + self.closeButton, QtCore.SIGNAL("clicked()"), MSEditor.close) + QtCore.QObject.connect(self.doorNameCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self.doorNameLineEdit.setDisabled) + QtCore.QObject.connect(self.doorAliasCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self.doorAliasLineEdit.setDisabled) QtCore.QMetaObject.connectSlotsByName(MSEditor) def retranslateUi(self, MSEditor): - MSEditor.setWindowTitle(QtGui.QApplication.translate("MSEditor", "Create Pool", None, QtGui.QApplication.UnicodeUTF8)) - self.instanceNameLabel.setText(QtGui.QApplication.translate("MSEditor", "Instance name", None, QtGui.QApplication.UnicodeUTF8)) - self.msDeviceNameLabel.setText(QtGui.QApplication.translate("MSEditor", "MS device name", None, QtGui.QApplication.UnicodeUTF8)) - self.msAliasLabel.setText(QtGui.QApplication.translate("MSEditor", "MS alias (optional)", None, QtGui.QApplication.UnicodeUTF8)) - self.msVersionLabel.setText(QtGui.QApplication.translate("MSEditor", "MS version", None, QtGui.QApplication.UnicodeUTF8)) - self.msDeviceNameCheckBox.setText(QtGui.QApplication.translate("MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) - self.msAliasCheckBox.setText(QtGui.QApplication.translate("MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) - self.msVersionCheckBox.setText(QtGui.QApplication.translate("MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) - self.poolNameLabel.setText(QtGui.QApplication.translate("MSEditor", "Pool name", None, QtGui.QApplication.UnicodeUTF8)) - self.doorNameLabel.setText(QtGui.QApplication.translate("MSEditor", "Door name", None, QtGui.QApplication.UnicodeUTF8)) - self.doorAliasLabel.setText(QtGui.QApplication.translate("MSEditor", "Door alias (optional)", None, QtGui.QApplication.UnicodeUTF8)) - self.doorNameCheckBox.setText(QtGui.QApplication.translate("MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) - self.doorAliasCheckBox.setText(QtGui.QApplication.translate("MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) - self.groupBox.setTitle(QtGui.QApplication.translate("MSEditor", "MacroPath", None, QtGui.QApplication.UnicodeUTF8)) - self.createButton.setText(QtGui.QApplication.translate("MSEditor", "Create", None, QtGui.QApplication.UnicodeUTF8)) - self.closeButton.setText(QtGui.QApplication.translate("MSEditor", "Close", None, QtGui.QApplication.UnicodeUTF8)) + MSEditor.setWindowTitle(QtGui.QApplication.translate( + "MSEditor", "Create Pool", None, QtGui.QApplication.UnicodeUTF8)) + self.instanceNameLabel.setText(QtGui.QApplication.translate( + "MSEditor", "Instance name", None, QtGui.QApplication.UnicodeUTF8)) + self.msDeviceNameLabel.setText(QtGui.QApplication.translate( + "MSEditor", "MS device name", None, QtGui.QApplication.UnicodeUTF8)) + self.msAliasLabel.setText(QtGui.QApplication.translate( + "MSEditor", "MS alias (optional)", None, QtGui.QApplication.UnicodeUTF8)) + self.msVersionLabel.setText(QtGui.QApplication.translate( + "MSEditor", "MS version", None, QtGui.QApplication.UnicodeUTF8)) + self.msDeviceNameCheckBox.setText(QtGui.QApplication.translate( + "MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) + self.msAliasCheckBox.setText(QtGui.QApplication.translate( + "MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) + self.msVersionCheckBox.setText(QtGui.QApplication.translate( + "MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) + self.poolNameLabel.setText(QtGui.QApplication.translate( + "MSEditor", "Pool name", None, QtGui.QApplication.UnicodeUTF8)) + self.doorNameLabel.setText(QtGui.QApplication.translate( + "MSEditor", "Door name", None, QtGui.QApplication.UnicodeUTF8)) + self.doorAliasLabel.setText(QtGui.QApplication.translate( + "MSEditor", "Door alias (optional)", None, QtGui.QApplication.UnicodeUTF8)) + self.doorNameCheckBox.setText(QtGui.QApplication.translate( + "MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) + self.doorAliasCheckBox.setText(QtGui.QApplication.translate( + "MSEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox.setTitle(QtGui.QApplication.translate( + "MSEditor", "MacroPath", None, QtGui.QApplication.UnicodeUTF8)) + self.createButton.setText(QtGui.QApplication.translate( + "MSEditor", "Create", None, QtGui.QApplication.UnicodeUTF8)) + self.closeButton.setText(QtGui.QApplication.translate( + "MSEditor", "Close", None, QtGui.QApplication.UnicodeUTF8)) if __name__ == "__main__": @@ -149,4 +175,3 @@ def retranslateUi(self, MSEditor): ui.setupUi(MSEditor) MSEditor.show() sys.exit(app.exec_()) - diff --git a/sardanaConfig/src/wizards/new_sardana_wizard.py b/sardanaConfig/src/wizards/new_sardana_wizard.py index a96d6879f8..8df2367eee 100644 --- a/sardanaConfig/src/wizards/new_sardana_wizard.py +++ b/sardanaConfig/src/wizards/new_sardana_wizard.py @@ -1,6 +1,13 @@ -import os, sys, wiz, re, traceback, time -import taurus.qt.qtgui.resource, pool_editor_UI -import pool_editor_UI, ms_editor_UI +import os +import sys +import wiz +import re +import traceback +import time +import taurus.qt.qtgui.resource +import pool_editor_UI +import pool_editor_UI +import ms_editor_UI from PyQt4 import QtGui, QtCore, Qt from taurus.core.util.enumeration import Enumeration from sardana.taurus.core.tango.sardana import SardanaManager @@ -17,6 +24,8 @@ - OutroPage """ + + class NewSardanaIntroPage(wiz.SardanaIntroBasePage): """ Introduction page @@ -37,6 +46,7 @@ class SelectTangoHostPage(wiz.SardanaBasePage): """ Page for selecting tango host """ + def __init__(self, parent=None): wiz.SardanaBasePage.__init__(self, parent) @@ -74,15 +84,19 @@ def __init__(self, parent=None): self['port'] = self._getPort self['host'] = self._getHost - self.connect(self.hostEdit, QtCore.SIGNAL('textEdited(const QString &)'), self._letterChanged) - self.connect(self.portEdit, QtCore.SIGNAL('textEdited(const QString &)'), self._letterChanged) - self.connect(self.checkButton, QtCore.SIGNAL('clicked()'), self.checkData) + self.connect(self.hostEdit, QtCore.SIGNAL( + 'textEdited(const QString &)'), self._letterChanged) + self.connect(self.portEdit, QtCore.SIGNAL( + 'textEdited(const QString &)'), self._letterChanged) + self.connect(self.checkButton, QtCore.SIGNAL( + 'clicked()'), self.checkData) self.checkData() def get_default_tango_host(self): tg = os.environ.get('TANGO_HOST', '') - if not tg or tg.count(':') != 1: return '', '' + if not tg or tg.count(':') != 1: + return '', '' return tg.split(':') def _letterChanged(self): @@ -99,8 +113,8 @@ def checkData(self): self._valid = True self.emit(QtCore.SIGNAL('completeChanged()')) except Exception, e: - self.setStatus('Invalid database') - self._valid = False + self.setStatus('Invalid database') + self._valid = False self.checkButton.hide() def _getPort(self): @@ -168,12 +182,14 @@ def __init__(self, parent=None): panel.setLayout(layout) - self.connect(self.nameEdit, QtCore.SIGNAL('textEdited(const QString &)'), self._letterChanged) - self.connect(self.checkButton, QtCore.SIGNAL('clicked()'), self.checkData) + self.connect(self.nameEdit, QtCore.SIGNAL( + 'textEdited(const QString &)'), self._letterChanged) + self.connect(self.checkButton, QtCore.SIGNAL( + 'clicked()'), self.checkData) def _getSardana(self): - sardana = str(self.nameEdit.text()) - return sardana + sardana = str(self.nameEdit.text()) + return sardana def _letterChanged(self): self._valid = False @@ -192,13 +208,13 @@ def checkData(self): self.setStatus('Please type the name') self._valid = False else: - if self.nameEdit.text() not in self._getSardanas(): - self.setStatus('please click the ''Next'' button') - self._valid = True - self.emit(QtCore.SIGNAL('completeChanged()')) - else: - self.setStatus('The name already exists in the database') - self._valid = False + if self.nameEdit.text() not in self._getSardanas(): + self.setStatus('please click the ''Next'' button') + self._valid = True + self.emit(QtCore.SIGNAL('completeChanged()')) + else: + self.setStatus('The name already exists in the database') + self._valid = False self.checkButton.hide() def isComplete(self): @@ -228,27 +244,36 @@ class Item(object): """ SuperClass of Pool and Macroservers items """ + def __init__(self, instanceName="", hostName="", level=None): self._instanceName = str(instanceName) self._hostName = str(hostName) self._level = level + def setInstanceName(self, name): self._instanceName = str(name) + def getInstanceName(self): return self._instanceName + def setHostName(self, name): self._hostName = str(name) + def getHostName(self): return self._hostName + def setLevel(self, level): self._level = level + def getLevel(self): return self._level + class SimpleEditorBasePage(wiz.SardanaBasePage): """ Superclass of Pool and Macroserver editor """ + def __init__(self, parent=None): wiz.SardanaBasePage.__init__(self, parent) self.setSubTitle('SubTitle') @@ -260,8 +285,10 @@ def __init__(self, parent=None): self.tableWidget.setObjectName("tableWidget") self.tableWidget.setColumnCount(3) self.tableWidget.setRowCount(0) - self.tableWidget.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) - self.tableWidget.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.tableWidget.setSelectionMode( + QtGui.QAbstractItemView.SingleSelection) + self.tableWidget.setSelectionBehavior( + QtGui.QAbstractItemView.SelectRows) self.horizontalLayout.addWidget(self.tableWidget) self._setTableHeaders() self.tableWidget.horizontalHeader().resizeSection(0, 125) @@ -273,39 +300,49 @@ def __init__(self, parent=None): self.verticalLayout.setObjectName("verticalLayout") self.addButton = QtGui.QPushButton(self) - self.addButton.setText(QtGui.QApplication.translate("Form", "Add", None, QtGui.QApplication.UnicodeUTF8)) + self.addButton.setText(QtGui.QApplication.translate( + "Form", "Add", None, QtGui.QApplication.UnicodeUTF8)) self.addButton.setObjectName("addButton") - self.addButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-add")) + self.addButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-add")) self.verticalLayout.addWidget(self.addButton) self.editButton = QtGui.QPushButton(self) - self.editButton.setText(QtGui.QApplication.translate("Form", "Edit", None, QtGui.QApplication.UnicodeUTF8)) + self.editButton.setText(QtGui.QApplication.translate( + "Form", "Edit", None, QtGui.QApplication.UnicodeUTF8)) self.editButton.setObjectName("editButton") - self.editButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("preferences-system")) + self.editButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("preferences-system")) self.verticalLayout.addWidget(self.editButton) self.removeButton = QtGui.QPushButton(self) - self.removeButton.setText(QtGui.QApplication.translate("Form", "Remove", None, QtGui.QApplication.UnicodeUTF8)) + self.removeButton.setText(QtGui.QApplication.translate( + "Form", "Remove", None, QtGui.QApplication.UnicodeUTF8)) self.removeButton.setObjectName("removeButton") - self.removeButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-remove")) + self.removeButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-remove")) self.verticalLayout.addWidget(self.removeButton) - spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacerItem = QtGui.QSpacerItem( + 20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) self.horizontalLayout.addLayout(self.verticalLayout) #spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - #self.horizontalLayout.addItem(spacerItem1) + # self.horizontalLayout.addItem(spacerItem1) self.listOfItems = [] self._comboList = [] self._spinList = [] def _setTableHeaders(self): self.tableWidget.setColumnCount(3) - self.tableWidget.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("name")) - self.tableWidget.setHorizontalHeaderItem(1, QtGui.QTableWidgetItem("host")) - self.tableWidget.setHorizontalHeaderItem(2, QtGui.QTableWidgetItem("level")) - - def openEditor (self, item=None): + self.tableWidget.setHorizontalHeaderItem( + 0, QtGui.QTableWidgetItem("name")) + self.tableWidget.setHorizontalHeaderItem( + 1, QtGui.QTableWidgetItem("host")) + self.tableWidget.setHorizontalHeaderItem( + 2, QtGui.QTableWidgetItem("level")) + + def openEditor(self, item=None): pass def checkName(self, name, id=None): @@ -317,7 +354,7 @@ def checkName(self, name, id=None): i += 1 return True - def addItem (self, item): + def addItem(self, item): if item.getLevel() == None: item.setLevel("1") item.setHostName(self._getHostList()[0]) @@ -326,7 +363,7 @@ def addItem (self, item): self.checkData() return True - def editItem (self, item, id): + def editItem(self, item, id): if item.getLevel() == None: item.setLevel("1") self.listOfItems[id] = item @@ -369,9 +406,9 @@ def _fillList(self): self.tableWidget.setRowCount(len(self.listOfItems)) self.tableWidget.clearSelection() - #self.tableWidget.setItemSelected(None) + # self.tableWidget.setItemSelected(None) - #self.tableWidget.selectRow(-1) + # self.tableWidget.selectRow(-1) self.editButton.setObjectName("editButton") i = 0 @@ -386,12 +423,14 @@ def _fillList(self): self._comboList[i].addItems(self._hostList) self._comboList[i].addItem("None") self._comboList[i].insertSeparator(len(self._hostList) + 1) - QtCore.QObject.connect(self._comboList[i], QtCore.SIGNAL("currentIndexChanged(int)"), self.hostChanged) + QtCore.QObject.connect(self._comboList[i], QtCore.SIGNAL( + "currentIndexChanged(int)"), self.hostChanged) self.tableWidget.setCellWidget(i, 1, self._comboList[i]) self._spinList.append(QtGui.QSpinBox()) self._spinList[i].setRange(*SardanaManager().get_level_range()) self._spinList[i].setObjectName("levelSpinBox_%d" % i) - QtCore.QObject.connect(self._spinList[i], QtCore.SIGNAL("valueChanged(int)"), self.levelChanged) + QtCore.QObject.connect(self._spinList[i], QtCore.SIGNAL( + "valueChanged(int)"), self.levelChanged) self.tableWidget.setCellWidget(i, 2, self._spinList[i]) if (item.getHostName() == "") or (item.getHostName() == None): @@ -417,7 +456,7 @@ def _getHostList(self): return SardanaManager().get_hosts() def getPoolServerList(self): - return [ s[s.index('/') + 1:] for s in self.db().get_server_list() if s.startswith('Pool/') ] + return [s[s.index('/') + 1:] for s in self.db().get_server_list() if s.startswith('Pool/')] class Pool(Item): @@ -435,55 +474,74 @@ def __init__(self, instanceName="", hostName="", level=None, poolDeviceName="", def setPoolDeviceName(self, name): self._poolDeviceName = str(name) + def getPoolDeviceName(self): return str(self._poolDeviceName) + def setAlias(self, alias): self._alias = str(alias) + def getAlias(self): return self._alias + def setPoolVersion(self, poolVersion): self._poolVersion = str(poolVersion) + def getPoolVersion(self): return self._poolVersion + def setPoolPath(self, path): self._poolPath = map(str, path) + def getPoolPath(self): return self._poolPath + def text(self): return str(self._instanceName) + def copy(self): return Pool(self._instanceName, self._hostName, self._level, self._poolDeviceName, self._alias, self._poolVersion, self._poolPath[:]) - class AddPoolBasePage(SimpleEditorBasePage): """ Page for editing the list of Pools """ + def __init__(self, parent=None): self._editor = None SimpleEditorBasePage.__init__(self, parent) self._editor = PoolEditor(parent=self) self.selectedItem = None self.item_id = None - self.setSubTitle('You can use this manager if you would like to Add, Edit or Delete Pool entries in the database.') - self.addButton.setText(QtGui.QApplication.translate("Form", "Add Pool", None, QtGui.QApplication.UnicodeUTF8)) - self.editButton.setText(QtGui.QApplication.translate("Form", "Edit Pool", None, QtGui.QApplication.UnicodeUTF8)) - self.removeButton.setText(QtGui.QApplication.translate("Form", "Remove Pool", None, QtGui.QApplication.UnicodeUTF8)) - QtCore.QObject.connect(self.addButton, QtCore.SIGNAL("clicked()"), self.openAddEditor) - QtCore.QObject.connect(self.editButton, QtCore.SIGNAL("clicked()"), self.openItemEditor) - QtCore.QObject.connect(self.removeButton, QtCore.SIGNAL("clicked()"), self.delete) - QtCore.QObject.connect(self.tableWidget, QtCore.SIGNAL("cellDoubleClicked(int,int)"), self.openItemEditor) - - def delete (self): + self.setSubTitle( + 'You can use this manager if you would like to Add, Edit or Delete Pool entries in the database.') + self.addButton.setText(QtGui.QApplication.translate( + "Form", "Add Pool", None, QtGui.QApplication.UnicodeUTF8)) + self.editButton.setText(QtGui.QApplication.translate( + "Form", "Edit Pool", None, QtGui.QApplication.UnicodeUTF8)) + self.removeButton.setText(QtGui.QApplication.translate( + "Form", "Remove Pool", None, QtGui.QApplication.UnicodeUTF8)) + QtCore.QObject.connect(self.addButton, QtCore.SIGNAL( + "clicked()"), self.openAddEditor) + QtCore.QObject.connect(self.editButton, QtCore.SIGNAL( + "clicked()"), self.openItemEditor) + QtCore.QObject.connect( + self.removeButton, QtCore.SIGNAL("clicked()"), self.delete) + QtCore.QObject.connect(self.tableWidget, QtCore.SIGNAL( + "cellDoubleClicked(int,int)"), self.openItemEditor) + + def delete(self): if len(self.tableWidget.selectedIndexes()) > 0: msgBox = QtGui.QMessageBox() msgBox.setText("The list of Pools has been modified.") self.item_id = self.tableWidget.selectedIndexes()[0].row() self.selectedItem = self.listOfItems[self.item_id] - msgBox.setInformativeText("Do you want to delete Pool?:\n" + self.selectedItem.text()) - msgBox.setStandardButtons(QtGui.QMessageBox().Ok | QtGui.QMessageBox().Cancel) - msgBox.setDefaultButton(QtGui.QMessageBox().Cancel); + msgBox.setInformativeText( + "Do you want to delete Pool?:\n" + self.selectedItem.text()) + msgBox.setStandardButtons( + QtGui.QMessageBox().Ok | QtGui.QMessageBox().Cancel) + msgBox.setDefaultButton(QtGui.QMessageBox().Cancel) msgBox.setIcon(QtGui.QMessageBox.Question) ret = msgBox.exec_() if ret == QtGui.QMessageBox().Ok: @@ -491,18 +549,19 @@ def delete (self): if ret == QtGui.QMessageBox().Cancel: pass - def openAddEditor (self): + def openAddEditor(self): self.item_id = None self.selectedItem = None SimpleEditorBasePage.openEditor(self) self._editor.showEditor(item=None, item_id=None) - def openItemEditor (self): + def openItemEditor(self): if len(self.tableWidget.selectedIndexes()) > 0: self.item_id = self.tableWidget.selectedIndexes()[0].row() self.selectedItem = self.listOfItems[self.item_id] SimpleEditorBasePage.openEditor(self) - self._editor.showEditor(item=self.selectedItem, item_id=self.item_id) + self._editor.showEditor( + item=self.selectedItem, item_id=self.item_id) def checkData(self): if len(self.listOfItems) > 0: @@ -534,6 +593,7 @@ class PoolEditor(object): """ Pool editor """ + def __init__(self, parent=None): self._parent = parent @@ -546,49 +606,69 @@ def __init__(self, parent=None): self._regExp = QtCore.QRegExp("^[0-9a-zA-Z_/]{,50}") self._regValid = QtGui.QRegExpValidator(self._regExp, self.poolEditor) self._regExp2 = QtCore.QRegExp("^[0-9.]{,50}") - self._versionValid = QtGui.QRegExpValidator(self._regExp2, self.poolEditor) + self._versionValid = QtGui.QRegExpValidator( + self._regExp2, self.poolEditor) self._regExp3 = QtCore.QRegExp("^[0-9a-zA-Z_/]{,100}") - self._deviceNameValid = QtGui.QRegExpValidator(self._regExp3, self.poolEditor) + self._deviceNameValid = QtGui.QRegExpValidator( + self._regExp3, self.poolEditor) self.ui.instanceNameLineEdit.setValidator(self._regValid) self.ui.poolDeviceNameLineEdit.setValidator(self._deviceNameValid) self.ui.aliasLineEdit.setValidator(self._regValid) self.ui.poolVersionLineEdit.setValidator(self._versionValid) self._item_id = None self._path_id = None - self.ui.addButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-add")) - self.ui.removeButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-remove")) - self.ui.upButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("go-up")) - self.ui.downButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("go-down")) - #connections - QtCore.QObject.connect(self.ui.createButton, QtCore.SIGNAL("clicked()"), self._createPool) - QtCore.QObject.connect(self.ui.addButton, QtCore.SIGNAL("clicked()"), self._addPath) - QtCore.QObject.connect(self.ui.removeButton, QtCore.SIGNAL("clicked()"), self._removePath) - QtCore.QObject.connect(self.ui.upButton, QtCore.SIGNAL("clicked()"), self._moveUp) - QtCore.QObject.connect(self.ui.downButton, QtCore.SIGNAL("clicked()"), self._moveDown) - QtCore.QObject.connect(self.ui.instanceNameLineEdit, QtCore.SIGNAL('textEdited(const QString &)'), self._letterChanged) - QtCore.QObject.connect(self.ui.poolDeviceNameCheckBox, QtCore.SIGNAL("toggled(bool)"), self._letterChanged) - QtCore.QObject.connect(self.ui.aliasCheckBox, QtCore.SIGNAL("toggled(bool)"), self._letterChanged) - QtCore.QObject.connect(self.ui.poolVersionCheckBox, QtCore.SIGNAL("toggled(bool)"), self._letterChanged) - QtCore.QObject.connect(self.ui.poolPathList, QtCore.SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self._editPath) + self.ui.addButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-add")) + self.ui.removeButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-remove")) + self.ui.upButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("go-up")) + self.ui.downButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("go-down")) + # connections + QtCore.QObject.connect(self.ui.createButton, + QtCore.SIGNAL("clicked()"), self._createPool) + QtCore.QObject.connect( + self.ui.addButton, QtCore.SIGNAL("clicked()"), self._addPath) + QtCore.QObject.connect(self.ui.removeButton, + QtCore.SIGNAL("clicked()"), self._removePath) + QtCore.QObject.connect( + self.ui.upButton, QtCore.SIGNAL("clicked()"), self._moveUp) + QtCore.QObject.connect( + self.ui.downButton, QtCore.SIGNAL("clicked()"), self._moveDown) + QtCore.QObject.connect(self.ui.instanceNameLineEdit, QtCore.SIGNAL( + 'textEdited(const QString &)'), self._letterChanged) + QtCore.QObject.connect(self.ui.poolDeviceNameCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self._letterChanged) + QtCore.QObject.connect(self.ui.aliasCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self._letterChanged) + QtCore.QObject.connect(self.ui.poolVersionCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self._letterChanged) + QtCore.QObject.connect(self.ui.poolPathList, QtCore.SIGNAL( + "itemDoubleClicked(QListWidgetItem*)"), self._editPath) def _letterChanged(self): if self.ui.poolDeviceNameCheckBox.isChecked(): - self.ui.poolDeviceNameLineEdit.setText("pool/" + self.ui.instanceNameLineEdit.text() + "/1") + self.ui.poolDeviceNameLineEdit.setText( + "pool/" + self.ui.instanceNameLineEdit.text() + "/1") if self.ui.aliasCheckBox.isChecked(): - self.ui.aliasLineEdit.setText("Pool_" + self.ui.instanceNameLineEdit.text()) + self.ui.aliasLineEdit.setText( + "Pool_" + self.ui.instanceNameLineEdit.text()) if self.ui.poolVersionCheckBox.isChecked(): self.ui.poolVersionLineEdit.setText("0.3.0") - def _addPath (self): - text, ok = QtGui.QInputDialog.getText(self.poolEditor, 'Input Dialog', 'Type directory to be added:') + def _addPath(self): + text, ok = QtGui.QInputDialog.getText( + self.poolEditor, 'Input Dialog', 'Type directory to be added:') if (ok and len(text) > 0): self._pool.getPoolPath().append(str(text)) self._refreshPathList() - def _editPath (self): + def _editPath(self): if len(self.ui.poolPathList.selectedIndexes()) > 0: self._path_id = self.ui.poolPathList.selectedIndexes()[0].row() - text, ok = QtGui.QInputDialog.getText(self.poolEditor, 'Input Dialog', 'Edit selected directory:', QtGui.QLineEdit.Normal, self._pool.getPoolPath()[self._path_id]) + text, ok = QtGui.QInputDialog.getText( + self.poolEditor, 'Input Dialog', 'Edit selected directory:', QtGui.QLineEdit.Normal, self._pool.getPoolPath()[self._path_id]) if (ok and len(text) > 0): self._pool.getPoolPath()[self._path_id] = text self._refreshPathList() @@ -596,7 +676,8 @@ def _editPath (self): def _removePath(self): if len(self.ui.poolPathList.selectedIndexes()) > 0: self._path_id = self.ui.poolPathList.selectedIndexes()[0].row() - self._pool.getPoolPath().remove(self._pool.getPoolPath()[self._path_id]) + self._pool.getPoolPath().remove( + self._pool.getPoolPath()[self._path_id]) self._refreshPathList() def _moveUp(self): @@ -604,20 +685,24 @@ def _moveUp(self): self._path_id = self.ui.poolPathList.selectedIndexes()[0].row() if self._path_id > 0: tmp = self._pool.getPoolPath()[self._path_id] - self._pool.getPoolPath()[self._path_id] = self._pool.getPoolPath()[self._path_id - 1] + self._pool.getPoolPath()[self._path_id] = self._pool.getPoolPath()[ + self._path_id - 1] self._pool.getPoolPath()[self._path_id - 1] = tmp self._refreshPathList() - self.ui.poolPathList.setCurrentIndex(self.ui.poolPathList.indexFromItem(self.ui.poolPathList.item(self._path_id - 1))) + self.ui.poolPathList.setCurrentIndex(self.ui.poolPathList.indexFromItem( + self.ui.poolPathList.item(self._path_id - 1))) def _moveDown(self): if len(self.ui.poolPathList.selectedIndexes()) > 0: self._path_id = self.ui.poolPathList.selectedIndexes()[0].row() if self._path_id < self.ui.poolPathList.count() - 1: tmp = self._pool.getPoolPath()[self._path_id] - self._pool.getPoolPath()[self._path_id] = self._pool.getPoolPath()[self._path_id + 1] + self._pool.getPoolPath()[self._path_id] = self._pool.getPoolPath()[ + self._path_id + 1] self._pool.getPoolPath()[self._path_id + 1] = tmp self._refreshPathList() - self.ui.poolPathList.setCurrentIndex(self.ui.poolPathList.indexFromItem(self.ui.poolPathList.item(self._path_id + 1))) + self.ui.poolPathList.setCurrentIndex(self.ui.poolPathList.indexFromItem( + self.ui.poolPathList.item(self._path_id + 1))) def _refreshPathList(self): self.ui.poolPathList.clear() @@ -635,16 +720,16 @@ def _validate(self): if self._parent.checkName(self.ui.instanceNameLineEdit.text(), id=self._item_id): pass else: - err = 1 - warnMess += "The Instance Name already exist in the DataBase\n" + err = 1 + warnMess += "The Instance Name already exist in the DataBase\n" pdn = str(self.ui.poolDeviceNameLineEdit.text()) allowed = re.compile("^.{1,}/.{1,}/.{1,}$") - if not ((len(pdn) > 0) and (allowed.match(pdn)) and (pdn.count("/") == 2)): + if not ((len(pdn) > 0) and (allowed.match(pdn)) and (pdn.count("/") == 2)): err = 1 warnMess += "The Pool Device Name is not valid\n" - #if self.ui.aliasLineEdit.text() == "": + # if self.ui.aliasLineEdit.text() == "": # err=1 # warnMess+="Please type the Alias\n" @@ -710,7 +795,7 @@ def showEditor(self, item=None, item_id=None): self.ui.aliasCheckBox.setChecked(False) self.ui.poolVersionLineEdit.setText(item.getPoolVersion()) self.ui.poolVersionLineEdit.setEnabled(True) - self.ui.poolVersionCheckBox.setChecked(True) ### + self.ui.poolVersionCheckBox.setChecked(True) self.ui.createButton.setText("Edit") self._item_id = item_id self.poolEditor.setModal(True) @@ -721,6 +806,7 @@ class MS(Item): """ Represents a Macroserver """ + def __init__(self, instanceName="", hostName="", level=None, poolName="", msDeviceName="", msAlias="", msVersion="", msPath=[], doorName="", doorAlias=""): Item.__init__(self, instanceName, hostName, level) self._msDeviceName = str(msDeviceName) @@ -733,34 +819,49 @@ def __init__(self, instanceName="", hostName="", level=None, poolName="", msDevi def setPoolName(self, name): self._poolName = str(name) + def getPoolName(self): return self._poolName + def setMSDeviceName(self, name): self._msDeviceName = str(name) + def getMSDeviceName(self): return self._msDeviceName + def setMSAlias(self, alias): self._msAlias = str(alias) + def getMSAlias(self): return self._msAlias + def setMSVersion(self, msVersion): self._msVersion = str(msVersion) + def getMSVersion(self): return self._msVersion + def setMSPath(self, path): self._msPath = map(str, path) + def getMSPath(self): return self._msPath + def setDoorName(self, doorName): self._doorName = str(doorName) + def getDoorName(self): return self._doorName + def setDoorAlias(self, doorAlias): self._doorAlias = str(doorAlias) + def getDoorAlias(self): return self._doorAlias + def text(self): return str(self._instanceName) + def copy(self): return MS(self._instanceName, self._hostName, self._level, self._poolName, self._msDeviceName, self._msAlias, self._msVersion, self._msPath[:], self._doorName, self._doorAlias) @@ -769,6 +870,7 @@ class MSEditor(object): """ Macroserver editor """ + def __init__(self, parent=None): self._parent = parent #self._parent = weakref.ref(parent) @@ -781,9 +883,11 @@ def __init__(self, parent=None): self._regExp = QtCore.QRegExp("^[0-9a-zA-Z]{,50}") self._regValid = QtGui.QRegExpValidator(self._regExp, self.msEditor) self._regExp2 = QtCore.QRegExp("^[0-9.]{,50}") - self._versionValid = QtGui.QRegExpValidator(self._regExp2, self.msEditor) + self._versionValid = QtGui.QRegExpValidator( + self._regExp2, self.msEditor) self._regExp3 = QtCore.QRegExp("^[0-9a-zA-Z_/]{,100}") - self._deviceNameValid = QtGui.QRegExpValidator(self._regExp3, self.msEditor) + self._deviceNameValid = QtGui.QRegExpValidator( + self._regExp3, self.msEditor) self.ui.instanceNameLineEdit.setValidator(self._regValid) self.ui.msDeviceNameLineEdit.setValidator(self._deviceNameValid) self.ui.msAliasLineEdit.setValidator(self._regValid) @@ -792,35 +896,55 @@ def __init__(self, parent=None): self.ui.doorAliasLineEdit.setValidator(self._regValid) self._item_id = None self._path_id = None - self.ui.addButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-add")) - self.ui.removeButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-remove")) - self.ui.upButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("go-up")) - self.ui.downButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("go-down")) - #connections - QtCore.QObject.connect(self.ui.createButton, QtCore.SIGNAL("clicked()"), self._createMS) - QtCore.QObject.connect(self.ui.addButton, QtCore.SIGNAL("clicked()"), self._addPath) - QtCore.QObject.connect(self.ui.removeButton, QtCore.SIGNAL("clicked()"), self._removePath) - QtCore.QObject.connect(self.ui.upButton, QtCore.SIGNAL("clicked()"), self._moveUp) - QtCore.QObject.connect(self.ui.downButton, QtCore.SIGNAL("clicked()"), self._moveDown) - QtCore.QObject.connect(self.ui.instanceNameLineEdit, QtCore.SIGNAL('textEdited(const QString &)'), self._letterChanged) - QtCore.QObject.connect(self.ui.msDeviceNameCheckBox, QtCore.SIGNAL("toggled(bool)"), self._letterChanged) - QtCore.QObject.connect(self.ui.msAliasCheckBox, QtCore.SIGNAL("toggled(bool)"), self._letterChanged) - QtCore.QObject.connect(self.ui.msVersionCheckBox, QtCore.SIGNAL("toggled(bool)"), self._letterChanged) - QtCore.QObject.connect(self.ui.doorNameCheckBox, QtCore.SIGNAL("toggled(bool)"), self._letterChanged) - QtCore.QObject.connect(self.ui.doorAliasCheckBox, QtCore.SIGNAL("toggled(bool)"), self._letterChanged) - QtCore.QObject.connect(self.ui.msPathList, QtCore.SIGNAL("itemDoubleClicked(QListWidgetItem*)"), self._editPath) + self.ui.addButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-add")) + self.ui.removeButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-remove")) + self.ui.upButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("go-up")) + self.ui.downButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("go-down")) + # connections + QtCore.QObject.connect(self.ui.createButton, + QtCore.SIGNAL("clicked()"), self._createMS) + QtCore.QObject.connect( + self.ui.addButton, QtCore.SIGNAL("clicked()"), self._addPath) + QtCore.QObject.connect(self.ui.removeButton, + QtCore.SIGNAL("clicked()"), self._removePath) + QtCore.QObject.connect( + self.ui.upButton, QtCore.SIGNAL("clicked()"), self._moveUp) + QtCore.QObject.connect( + self.ui.downButton, QtCore.SIGNAL("clicked()"), self._moveDown) + QtCore.QObject.connect(self.ui.instanceNameLineEdit, QtCore.SIGNAL( + 'textEdited(const QString &)'), self._letterChanged) + QtCore.QObject.connect(self.ui.msDeviceNameCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self._letterChanged) + QtCore.QObject.connect(self.ui.msAliasCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self._letterChanged) + QtCore.QObject.connect(self.ui.msVersionCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self._letterChanged) + QtCore.QObject.connect(self.ui.doorNameCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self._letterChanged) + QtCore.QObject.connect(self.ui.doorAliasCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self._letterChanged) + QtCore.QObject.connect(self.ui.msPathList, QtCore.SIGNAL( + "itemDoubleClicked(QListWidgetItem*)"), self._editPath) def _letterChanged(self): if self.ui.msDeviceNameCheckBox.isChecked(): - self.ui.msDeviceNameLineEdit.setText("macroserver/" + self.ui.instanceNameLineEdit.text() + "/1") + self.ui.msDeviceNameLineEdit.setText( + "macroserver/" + self.ui.instanceNameLineEdit.text() + "/1") if self.ui.msAliasCheckBox.isChecked(): - self.ui.msAliasLineEdit.setText("MS_" + self.ui.instanceNameLineEdit.text()) + self.ui.msAliasLineEdit.setText( + "MS_" + self.ui.instanceNameLineEdit.text()) if self.ui.msVersionCheckBox.isChecked(): self.ui.msVersionLineEdit.setText("0.3.0") if self.ui.doorNameCheckBox.isChecked(): - self.ui.doorNameLineEdit.setText("door/" + self.ui.instanceNameLineEdit.text() + "/1") + self.ui.doorNameLineEdit.setText( + "door/" + self.ui.instanceNameLineEdit.text() + "/1") if self.ui.doorAliasCheckBox.isChecked(): - self.ui.doorAliasLineEdit.setText("Door_" + self.ui.instanceNameLineEdit.text()) + self.ui.doorAliasLineEdit.setText( + "Door_" + self.ui.instanceNameLineEdit.text()) def getPoolServerList(self): return self._parent.getPoolServerList() @@ -847,16 +971,18 @@ def fillPoolNameCB(self, selected=None): def db(self): return self._parent.wizard()['db'] - def _editPath (self): + def _editPath(self): if len(self.ui.msPathList.selectedIndexes()) > 0: self._path_id = self.ui.msPathList.selectedIndexes()[0].row() - text, ok = QtGui.QInputDialog.getText(self.msEditor, 'Input Dialog', 'Edit selected directory:', QtGui.QLineEdit.Normal, self._ms.getMSPath()[self._path_id]) + text, ok = QtGui.QInputDialog.getText( + self.msEditor, 'Input Dialog', 'Edit selected directory:', QtGui.QLineEdit.Normal, self._ms.getMSPath()[self._path_id]) if (ok and len(text) > 0): self._ms.getMSPath()[self._path_id] = text self._refreshPathList() - def _addPath (self): - text, ok = QtGui.QInputDialog.getText(self.msEditor, 'Input Dialog', 'Type directory to be added:') + def _addPath(self): + text, ok = QtGui.QInputDialog.getText( + self.msEditor, 'Input Dialog', 'Type directory to be added:') if (ok and len(text) > 0): self._ms.getMSPath().append(str(text)) self._refreshPathList() @@ -872,20 +998,24 @@ def _moveUp(self): self._path_id = self.ui.msPathList.selectedIndexes()[0].row() if self._path_id > 0: tmp = self._ms.getMSPath()[self._path_id] - self._ms.getMSPath()[self._path_id] = self._ms.getMSPath()[self._path_id - 1] + self._ms.getMSPath()[self._path_id] = self._ms.getMSPath()[ + self._path_id - 1] self._ms.getMSPath()[self._path_id - 1] = tmp self._refreshPathList() - self.ui.msPathList.setCurrentIndex(self.ui.msPathList.indexFromItem(self.ui.msPathList.item(self._path_id - 1))) + self.ui.msPathList.setCurrentIndex(self.ui.msPathList.indexFromItem( + self.ui.msPathList.item(self._path_id - 1))) def _moveDown(self): if len(self.ui.msPathList.selectedIndexes()) > 0: self._path_id = self.ui.msPathList.selectedIndexes()[0].row() if self._path_id < self.ui.msPathList.count() - 1: tmp = self._ms.getMSPath()[self._path_id] - self._ms.getMSPath()[self._path_id] = self._ms.getMSPath()[self._path_id + 1] + self._ms.getMSPath()[self._path_id] = self._ms.getMSPath()[ + self._path_id + 1] self._ms.getMSPath()[self._path_id + 1] = tmp self._refreshPathList() - self.ui.msPathList.setCurrentIndex(self.ui.msPathList.indexFromItem(self.ui.msPathList.item(self._path_id + 1))) + self.ui.msPathList.setCurrentIndex(self.ui.msPathList.indexFromItem( + self.ui.msPathList.item(self._path_id + 1))) def _refreshPathList(self): self.ui.msPathList.clear() @@ -903,8 +1033,8 @@ def _validate(self): if self._parent.checkName(name=self.ui.instanceNameLineEdit.text(), id=self._item_id): pass else: - err = 1 - warnMess += "The Instance Name already exist in the DataBase\n" + err = 1 + warnMess += "The Instance Name already exist in the DataBase\n" if self.ui.msDeviceNameLineEdit.text() == "": err = 1 @@ -912,11 +1042,11 @@ def _validate(self): mdn = str(self.ui.msDeviceNameLineEdit.text()) allowed = re.compile("^.{1,}/.{1,}/.{1,}$") - if not ((len(mdn) > 0) and (allowed.match(mdn)) and (mdn.count("/") == 2)): + if not ((len(mdn) > 0) and (allowed.match(mdn)) and (mdn.count("/") == 2)): err = 1 warnMess += "The Macro Server Device Name is not valid\n" - #if self.ui.msAliasLineEdit.text() == "": + # if self.ui.msAliasLineEdit.text() == "": # err=1 # warnMess+="Please type the Macro Server Alias\n" @@ -926,11 +1056,11 @@ def _validate(self): dn = str(self.ui.doorNameLineEdit.text()) allowed = re.compile("^.{1,}/.{1,}/.{1,}$") - if not ((len(dn) > 0) and (allowed.match(dn)) and (dn.count("/") == 2)): + if not ((len(dn) > 0) and (allowed.match(dn)) and (dn.count("/") == 2)): err = 1 warnMess += "The Door Name is not valid\n" - #if self.ui.doorAliasLineEdit.text() == "": + # if self.ui.doorAliasLineEdit.text() == "": # err=1 # warnMess+="Please type the Door Alias\n" @@ -1007,7 +1137,7 @@ def showEditor(self, item=None, item_id=None): self.ui.msAliasCheckBox.setChecked(False) self.ui.msVersionLineEdit.setText(item.getMSVersion()) self.ui.msVersionLineEdit.setEnabled(True) - self.ui.msVersionCheckBox.setChecked(True) ### + self.ui.msVersionCheckBox.setChecked(True) self.ui.doorNameLineEdit.setText(item.getDoorName()) self.ui.doorNameLineEdit.setEnabled(True) self.ui.doorNameCheckBox.setChecked(False) @@ -1031,25 +1161,35 @@ def __init__(self, parent=None): self._editor = MSEditor(parent=self) self.selectedItem = None self.item_id = None - self.setSubTitle('You can use this manager if you would like to Add, Edit or Delete Macro Server entries in the database.') - self.addButton.setText(QtGui.QApplication.translate("Form", "Add MS", None, QtGui.QApplication.UnicodeUTF8)) - self.editButton.setText(QtGui.QApplication.translate("Form", "Edit MS", None, QtGui.QApplication.UnicodeUTF8)) - self.removeButton.setText(QtGui.QApplication.translate("Form", "Remove MS", None, QtGui.QApplication.UnicodeUTF8)) - #connections - QtCore.QObject.connect(self.addButton, QtCore.SIGNAL("clicked()"), self.openAddEditor) - QtCore.QObject.connect(self.editButton, QtCore.SIGNAL("clicked()"), self.openItemEditor) - QtCore.QObject.connect(self.removeButton, QtCore.SIGNAL("clicked()"), self.delete) - QtCore.QObject.connect(self.tableWidget, QtCore.SIGNAL("cellDoubleClicked(int,int)"), self.openItemEditor) - - def delete (self): + self.setSubTitle( + 'You can use this manager if you would like to Add, Edit or Delete Macro Server entries in the database.') + self.addButton.setText(QtGui.QApplication.translate( + "Form", "Add MS", None, QtGui.QApplication.UnicodeUTF8)) + self.editButton.setText(QtGui.QApplication.translate( + "Form", "Edit MS", None, QtGui.QApplication.UnicodeUTF8)) + self.removeButton.setText(QtGui.QApplication.translate( + "Form", "Remove MS", None, QtGui.QApplication.UnicodeUTF8)) + # connections + QtCore.QObject.connect(self.addButton, QtCore.SIGNAL( + "clicked()"), self.openAddEditor) + QtCore.QObject.connect(self.editButton, QtCore.SIGNAL( + "clicked()"), self.openItemEditor) + QtCore.QObject.connect( + self.removeButton, QtCore.SIGNAL("clicked()"), self.delete) + QtCore.QObject.connect(self.tableWidget, QtCore.SIGNAL( + "cellDoubleClicked(int,int)"), self.openItemEditor) + + def delete(self): if len(self.tableWidget.selectedIndexes()) > 0: msgBox = QtGui.QMessageBox() msgBox.setText("The list of Macro Servers has been modified.") self.item_id = self.tableWidget.selectedIndexes()[0].row() self.selectedItem = self.listOfItems[self.item_id] - msgBox.setInformativeText("Do you want to delete Macro Server?:\n" + self.selectedItem.text()) - msgBox.setStandardButtons(QtGui.QMessageBox().Ok | QtGui.QMessageBox().Cancel) - msgBox.setDefaultButton(QtGui.QMessageBox().Cancel); + msgBox.setInformativeText( + "Do you want to delete Macro Server?:\n" + self.selectedItem.text()) + msgBox.setStandardButtons( + QtGui.QMessageBox().Ok | QtGui.QMessageBox().Cancel) + msgBox.setDefaultButton(QtGui.QMessageBox().Cancel) msgBox.setIcon(QtGui.QMessageBox.Question) ret = msgBox.exec_() if ret == QtGui.QMessageBox().Ok: @@ -1057,19 +1197,19 @@ def delete (self): if ret == QtGui.QMessageBox().Cancel: pass - def openAddEditor (self): + def openAddEditor(self): self.item_id = None self.selectedItem = None SimpleEditorBasePage.openEditor(self) self._editor.showEditor(item=None, item_id=None) - - def openItemEditor (self): + def openItemEditor(self): if len(self.tableWidget.selectedIndexes()) > 0: self.item_id = self.tableWidget.selectedIndexes()[0].row() self.selectedItem = self.listOfItems[self.item_id] SimpleEditorBasePage.openEditor(self) - self._editor.showEditor(item=self.selectedItem, item_id=self.item_id) + self._editor.showEditor( + item=self.selectedItem, item_id=self.item_id) def checkData(self): pass @@ -1132,28 +1272,37 @@ class SardanaCommitBasePage(wiz.SardanaIntroBasePage): """ Commiting page """ + def __init__(self, parent=None): QtGui.QWizardPage.__init__(self, parent) - self.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap(":/watermark.jpg")) + self.setPixmap(QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(":/watermark.jpg")) self._layout = QtGui.QFormLayout() self._sardanaNameLabel = QtGui.QLabel() self._hostNameLabel = QtGui.QLabel() self._portLabel = QtGui.QLabel() self._poollsLabel = QtGui.QLabel() self._mssLabel = QtGui.QLabel() - self._layout.addRow(self._set_style(QtGui.QLabel("Sardana:")), self._sardanaNameLabel) - self._layout.addRow(self._set_style(QtGui.QLabel("Host:")), self._hostNameLabel) - self._layout.addRow(self._set_style(QtGui.QLabel("Port:")), self._portLabel) - self._layout.addRow(self._set_style(QtGui.QLabel("")), QtGui.QLabel("")) - self._layout.addRow(self._set_style(QtGui.QLabel("Pools:")), self._poollsLabel) - self._layout.addRow(self._set_style(QtGui.QLabel("MacroServers:")), self._mssLabel) - self._checkBox = QtGui.QCheckBox("Start local server automatically\neven if no starter is present") + self._layout.addRow(self._set_style( + QtGui.QLabel("Sardana:")), self._sardanaNameLabel) + self._layout.addRow(self._set_style( + QtGui.QLabel("Host:")), self._hostNameLabel) + self._layout.addRow(self._set_style( + QtGui.QLabel("Port:")), self._portLabel) + self._layout.addRow(self._set_style( + QtGui.QLabel("")), QtGui.QLabel("")) + self._layout.addRow(self._set_style( + QtGui.QLabel("Pools:")), self._poollsLabel) + self._layout.addRow(self._set_style( + QtGui.QLabel("MacroServers:")), self._mssLabel) + self._checkBox = QtGui.QCheckBox( + "Start local server automatically\neven if no starter is present") self._checkBox.setChecked(True) self._layout.addRow(self._checkBox) self._poolListText = "" self._msListText = "" self.setLayout(self._layout) - #self.setCommitPage(True) + # self.setCommitPage(True) self.setTitle('Confirmation.') def next(self): @@ -1216,12 +1365,15 @@ class SardanaOutroBasePage(wiz.SardanaBasePage): """ The last page in the wizard for creation sardana and all of the pools and macroservers that it consist """ + def __init__(self, parent=None): QtGui.QWizardPage.__init__(self, parent) - self.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap(":/watermark.jpg")) + self.setPixmap(QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(":/watermark.jpg")) self._valid = True self._layout = QtGui.QVBoxLayout() - self._spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self._spacerItem = QtGui.QSpacerItem( + 20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self._layout.addItem(self._spacerItem) self._horizontalLayout_1 = QtGui.QHBoxLayout() self._label = QtGui.QLabel("\nInitializing...") @@ -1231,24 +1383,30 @@ def __init__(self, parent=None): self._pbar = QtGui.QProgressBar(self) self._layout.addWidget(self._pbar) self._horizontalLayout_2 = QtGui.QHBoxLayout() - self._spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self._spacerItem1 = QtGui.QSpacerItem( + 40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self._horizontalLayout_2.addItem(self._spacerItem1) self._cancelButton = QtGui.QPushButton("Cancel") self._horizontalLayout_2.addWidget(self._cancelButton) - self._spacerItem2 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self._spacerItem2 = QtGui.QSpacerItem( + 40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self._horizontalLayout_2.addItem(self._spacerItem2) self._layout.addLayout(self._horizontalLayout_2) - self._spacerItem3 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + self._spacerItem3 = QtGui.QSpacerItem( + 20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self._layout.addItem(self._spacerItem3) self.setLayout(self._layout) # self.setTitle('The new instance of Sardana has been successfully created.') def initializePage(self): self.wizard().setOption(QtGui.QWizard.NoCancelButton, True) - self.wizard().setOption (QtGui.QWizard.NoBackButtonOnLastPage , True) - self.progress = Progress(self.wizard()["db"], self.wizard()["sardana"], self.wizard()["poolList"][:], self.wizard()["msList"][:], self.wizard()["autoStart"]) - Qt.QObject.connect(self.progress, Qt.SIGNAL("valueUpdated"), self.setProgress) - QtCore.QObject.connect(self._cancelButton, QtCore.SIGNAL("clicked()"), self.progress.cancel) + self.wizard().setOption(QtGui.QWizard.NoBackButtonOnLastPage, True) + self.progress = Progress(self.wizard()["db"], self.wizard()["sardana"], self.wizard()[ + "poolList"][:], self.wizard()["msList"][:], self.wizard()["autoStart"]) + Qt.QObject.connect(self.progress, Qt.SIGNAL( + "valueUpdated"), self.setProgress) + QtCore.QObject.connect(self._cancelButton, QtCore.SIGNAL( + "clicked()"), self.progress.cancel) self.progress.start() self._valid = False self._cancelButton.show() @@ -1257,20 +1415,22 @@ def isComplete(self): return self._valid def setProgress(self, message, value, status): - #status + # status # 0 - normal # 1 - finished # -1 - interrupted if status == 0: - self.setTitle('The Wizard is creating the new instance of Sardana.') + self.setTitle( + 'The Wizard is creating the new instance of Sardana.') if status == 1: - self.setTitle('The new instance of Sardana has been successfully created.') + self.setTitle( + 'The new instance of Sardana has been successfully created.') self._cancelButton.hide() self._valid = True self.emit(QtCore.SIGNAL('completeChanged()')) if status == -1: self.setTitle('The new instance of Sardana has NOT been created.') - self.wizard().setOption (QtGui.QWizard.NoBackButtonOnLastPage , False) + self.wizard().setOption(QtGui.QWizard.NoBackButtonOnLastPage, False) self.wizard().setOption(QtGui.QWizard.NoCancelButton, False) self._cancelButton.hide() self._valid = False @@ -1284,6 +1444,7 @@ class Progress (Qt.QThread): """ Indicate the percent of sardana creation process """ + def __init__(self, db, sardana, poolList, msList, autoStart): Qt.QThread.__init__(self) self._sardana = sardana @@ -1297,8 +1458,8 @@ def __init__(self, db, sardana, poolList, msList, autoStart): def cancel(self): self._cancelled = True - def run(self): - #status + def run(self): + # status # 0 - normal # 1 - finished # -1 - interrupted @@ -1306,99 +1467,107 @@ def run(self): self.emit(Qt.SIGNAL("valueUpdated"), msg, percentage, status) def _createSardana(self): - err = False - mess = "Click the Finish button to exit this wizard." - sardanaManager = SardanaManager() - self._newSardana = None - - percent = 0 - step = 100 / (len(self._poolList) + len(self._msList) + 1) - - if len (self._msList) > 0: - try: - self._sardana_device_name = str(self._msList[0].getMSDeviceName()) - self._newSardana = sardanaManager.create_sardana(str(self._sardana), self._sardana_device_name, db=self._db) - except Exception, e: - err = True - mess = str(e) - traceback.print_exc() - else: - try: - self._sardana_device_name = str(self._poolList[0].getPoolDeviceName()) - self._newSardana = sardanaManager.create_sardana(str(self._sardana), self._sardana_device_name, db=self._db) - except Exception, e: - err = True - mess = str(e) + err = False + mess = "Click the Finish button to exit this wizard." + sardanaManager = SardanaManager() + self._newSardana = None + + percent = 0 + step = 100 / (len(self._poolList) + len(self._msList) + 1) + + if len(self._msList) > 0: + try: + self._sardana_device_name = str( + self._msList[0].getMSDeviceName()) + self._newSardana = sardanaManager.create_sardana( + str(self._sardana), self._sardana_device_name, db=self._db) + except Exception, e: + err = True + mess = str(e) + traceback.print_exc() + else: + try: + self._sardana_device_name = str( + self._poolList[0].getPoolDeviceName()) + self._newSardana = sardanaManager.create_sardana( + str(self._sardana), self._sardana_device_name, db=self._db) + except Exception, e: + err = True + mess = str(e) + + if err: + #msgbox = TaurusMessageBox(*sys.exc_info()) + # msgbox.exec_() - if err: - #msgbox = TaurusMessageBox(*sys.exc_info()) - #msgbox.exec_() + yield "\nCancelled...", 100, 1 - yield "\nCancelled...", 100, 1 + else: # Sardana has been created + percent += step + yield "\nProcessing the list of Pools", int(percent), 0 + time.sleep(0.5) - else: # Sardana has been created - percent += step - yield "\nProcessing the list of Pools", int(percent), 0 - time.sleep(0.5) + try: - try: - - for pool in self._poolList: - if self._cancelled: - raise Exception("Canceled by user") - - yield "Adding Pool:\n %s" % pool.getInstanceName(), int(percent), 0 - - if pool.getPoolDeviceName() == "": - pool.setPoolDeviceName(None) - if pool.getAlias() == "": - pool.setAlias(None) - newPool = self._newSardana.create_pool(pool.getInstanceName(), pool.getPoolPath(), pool.getPoolVersion(), alias=pool.getAlias() , device_name=pool.getPoolDeviceName()) - if pool.getHostName() not in (None, '', 'None'): - if pool.getHostName() == "localhost": - if self._autoStart: - yield "Starting Pool:\n %s" % pool.getInstanceName(), int(percent), 0 - newPool.local_run() - else: + for pool in self._poolList: + if self._cancelled: + raise Exception("Canceled by user") + + yield "Adding Pool:\n %s" % pool.getInstanceName(), int(percent), 0 + + if pool.getPoolDeviceName() == "": + pool.setPoolDeviceName(None) + if pool.getAlias() == "": + pool.setAlias(None) + newPool = self._newSardana.create_pool(pool.getInstanceName(), pool.getPoolPath( + ), pool.getPoolVersion(), alias=pool.getAlias(), device_name=pool.getPoolDeviceName()) + if pool.getHostName() not in (None, '', 'None'): + if pool.getHostName() == "localhost": + if self._autoStart: yield "Starting Pool:\n %s" % pool.getInstanceName(), int(percent), 0 - newPool.starter_run(pool.getHostName(), pool.getLevel()) - percent += step - - yield "\nProcessing the list of MacroServers", int(percent), 0 - time.sleep(0.5) - - for ms in self._msList: - if self._cancelled: - raise Exception("Canceled by user") - - yield "Adding MacroServer:\n %s" % ms.getInstanceName(), int(percent), 0 - - if ms.getMSDeviceName() == "": - ms.setMSDeviceName(None) - if ms.getMSAlias() == "": - ms.setMSAlias(None) - newMS = self._newSardana.create_macroserver(ms.getInstanceName(), ms.getMSPath(), self._poolNames, ms.getMSVersion(), alias=ms.getMSAlias() , device_name=ms.getMSDeviceName()) - newMS.create_door(ms.getDoorAlias(), ms.getDoorName()) - if ms.getHostName() not in (None, '', 'None'): - if ms.getHostName() == "localhost": - if self._autoStart: - yield "Starting MacroServer:\n %s" % ms.getInstanceName(), int(percent), 0 - newMS.local_run() - else: + newPool.local_run() + else: + yield "Starting Pool:\n %s" % pool.getInstanceName(), int(percent), 0 + newPool.starter_run( + pool.getHostName(), pool.getLevel()) + percent += step + + yield "\nProcessing the list of MacroServers", int(percent), 0 + time.sleep(0.5) + + for ms in self._msList: + if self._cancelled: + raise Exception("Canceled by user") + + yield "Adding MacroServer:\n %s" % ms.getInstanceName(), int(percent), 0 + + if ms.getMSDeviceName() == "": + ms.setMSDeviceName(None) + if ms.getMSAlias() == "": + ms.setMSAlias(None) + newMS = self._newSardana.create_macroserver(ms.getInstanceName(), ms.getMSPath( + ), self._poolNames, ms.getMSVersion(), alias=ms.getMSAlias(), device_name=ms.getMSDeviceName()) + newMS.create_door(ms.getDoorAlias(), ms.getDoorName()) + if ms.getHostName() not in (None, '', 'None'): + if ms.getHostName() == "localhost": + if self._autoStart: yield "Starting MacroServer:\n %s" % ms.getInstanceName(), int(percent), 0 - newMS.starter_run(ms.getHostName(), ms.getLevel()) + newMS.local_run() + else: + yield "Starting MacroServer:\n %s" % ms.getInstanceName(), int(percent), 0 + newMS.starter_run(ms.getHostName(), ms.getLevel()) - percent += step + percent += step - self._newSardana.set_device_name(self._sardana_device_name) - yield "\nDone...", 100, 1 + self._newSardana.set_device_name(self._sardana_device_name) + yield "\nDone...", 100, 1 - except Exception, e: - err = True - mess = str(e) - traceback.print_exc() - sardanaManager.remove_sardana(str(self._sardana)) # remove Sardana if something goes wrong - yield "\nCanceled by user", 0, -1 + except Exception, e: + err = True + mess = str(e) + traceback.print_exc() + # remove Sardana if something goes wrong + sardanaManager.remove_sardana(str(self._sardana)) + yield "\nCanceled by user", 0, -1 def addSardana(): @@ -1406,7 +1575,8 @@ def addSardana(): app = QtGui.QApplication([]) QtCore.QResource.registerResource(wiz.get_resources()) - Pages = Enumeration('Pages', ('IntroPage', 'TangoPage', 'SardanaPage', 'PoolPage', 'MSPage', 'CommitPage', 'OutroPage')) + Pages = Enumeration('Pages', ('IntroPage', 'TangoPage', 'SardanaPage', + 'PoolPage', 'MSPage', 'CommitPage', 'OutroPage')) w = wiz.SardanaBaseWizard() intro = NewSardanaIntroPage() @@ -1436,15 +1606,12 @@ def addSardana(): outro_page = SardanaOutroBasePage() w.setPage(Pages.OutroPage, outro_page) - w.setOption (QtGui.QWizard.CancelButtonOnLeft , True) - + w.setOption(QtGui.QWizard.CancelButtonOnLeft, True) #Qt.QObject.connect(w, Qt.SIGNAL("done()"), done) w.show() sys.exit(app.exec_()) - - if __name__ == "__main__": addSardana() diff --git a/sardanaConfig/src/wizards/pool_editor_UI.py b/sardanaConfig/src/wizards/pool_editor_UI.py index eeec023d64..3d5f05752e 100644 --- a/sardanaConfig/src/wizards/pool_editor_UI.py +++ b/sardanaConfig/src/wizards/pool_editor_UI.py @@ -9,7 +9,9 @@ from PyQt4 import QtCore, QtGui + class Ui_PoolEditor(object): + def setupUi(self, PoolEditor): PoolEditor.setObjectName("PoolEditor") PoolEditor.resize(400, 333) @@ -77,7 +79,8 @@ def setupUi(self, PoolEditor): self.gridLayout.addWidget(self.groupBox, 1, 0, 1, 1) self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") - spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + spacerItem = QtGui.QSpacerItem( + 40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem) self.createButton = QtGui.QPushButton(PoolEditor) self.createButton.setObjectName("createButton") @@ -88,24 +91,39 @@ def setupUi(self, PoolEditor): self.gridLayout.addLayout(self.horizontalLayout_2, 2, 0, 1, 1) self.retranslateUi(PoolEditor) - QtCore.QObject.connect(self.poolDeviceNameCheckBox, QtCore.SIGNAL("toggled(bool)"), self.poolDeviceNameLineEdit.setDisabled) - QtCore.QObject.connect(self.aliasCheckBox, QtCore.SIGNAL("toggled(bool)"), self.aliasLineEdit.setDisabled) - QtCore.QObject.connect(self.poolVersionCheckBox, QtCore.SIGNAL("toggled(bool)"), self.poolVersionLineEdit.setDisabled) - QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), PoolEditor.close) + QtCore.QObject.connect(self.poolDeviceNameCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self.poolDeviceNameLineEdit.setDisabled) + QtCore.QObject.connect(self.aliasCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self.aliasLineEdit.setDisabled) + QtCore.QObject.connect(self.poolVersionCheckBox, QtCore.SIGNAL( + "toggled(bool)"), self.poolVersionLineEdit.setDisabled) + QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL( + "clicked()"), PoolEditor.close) QtCore.QMetaObject.connectSlotsByName(PoolEditor) def retranslateUi(self, PoolEditor): - PoolEditor.setWindowTitle(QtGui.QApplication.translate("PoolEditor", "Create Pool", None, QtGui.QApplication.UnicodeUTF8)) - self.instanceNameLabel.setText(QtGui.QApplication.translate("PoolEditor", "Instance name", None, QtGui.QApplication.UnicodeUTF8)) - self.poolDeviceNameLabel.setText(QtGui.QApplication.translate("PoolEditor", "Pool device name", None, QtGui.QApplication.UnicodeUTF8)) - self.aliasLabel.setText(QtGui.QApplication.translate("PoolEditor", "Alias (optional)", None, QtGui.QApplication.UnicodeUTF8)) - self.poolVersionLabel.setText(QtGui.QApplication.translate("PoolEditor", "Pool version", None, QtGui.QApplication.UnicodeUTF8)) - self.poolDeviceNameCheckBox.setText(QtGui.QApplication.translate("PoolEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) - self.aliasCheckBox.setText(QtGui.QApplication.translate("PoolEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) - self.poolVersionCheckBox.setText(QtGui.QApplication.translate("PoolEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) - self.groupBox.setTitle(QtGui.QApplication.translate("PoolEditor", "PoolPath", None, QtGui.QApplication.UnicodeUTF8)) - self.createButton.setText(QtGui.QApplication.translate("PoolEditor", "Create", None, QtGui.QApplication.UnicodeUTF8)) - self.closeButton.setText(QtGui.QApplication.translate("PoolEditor", "Close", None, QtGui.QApplication.UnicodeUTF8)) + PoolEditor.setWindowTitle(QtGui.QApplication.translate( + "PoolEditor", "Create Pool", None, QtGui.QApplication.UnicodeUTF8)) + self.instanceNameLabel.setText(QtGui.QApplication.translate( + "PoolEditor", "Instance name", None, QtGui.QApplication.UnicodeUTF8)) + self.poolDeviceNameLabel.setText(QtGui.QApplication.translate( + "PoolEditor", "Pool device name", None, QtGui.QApplication.UnicodeUTF8)) + self.aliasLabel.setText(QtGui.QApplication.translate( + "PoolEditor", "Alias (optional)", None, QtGui.QApplication.UnicodeUTF8)) + self.poolVersionLabel.setText(QtGui.QApplication.translate( + "PoolEditor", "Pool version", None, QtGui.QApplication.UnicodeUTF8)) + self.poolDeviceNameCheckBox.setText(QtGui.QApplication.translate( + "PoolEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) + self.aliasCheckBox.setText(QtGui.QApplication.translate( + "PoolEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) + self.poolVersionCheckBox.setText(QtGui.QApplication.translate( + "PoolEditor", "Automatic", None, QtGui.QApplication.UnicodeUTF8)) + self.groupBox.setTitle(QtGui.QApplication.translate( + "PoolEditor", "PoolPath", None, QtGui.QApplication.UnicodeUTF8)) + self.createButton.setText(QtGui.QApplication.translate( + "PoolEditor", "Create", None, QtGui.QApplication.UnicodeUTF8)) + self.closeButton.setText(QtGui.QApplication.translate( + "PoolEditor", "Close", None, QtGui.QApplication.UnicodeUTF8)) if __name__ == "__main__": @@ -116,4 +134,3 @@ def retranslateUi(self, PoolEditor): ui.setupUi(PoolEditor) PoolEditor.show() sys.exit(app.exec_()) - diff --git a/sardanaConfig/src/wizards/pool_page.py b/sardanaConfig/src/wizards/pool_page.py index 3092b21d37..d77ebd3936 100644 --- a/sardanaConfig/src/wizards/pool_page.py +++ b/sardanaConfig/src/wizards/pool_page.py @@ -1,4 +1,5 @@ -import sys, os +import sys +import os from PyQt4 import QtGui, QtCore, Qt @@ -7,22 +8,24 @@ from taurus.core.utils import Enumeration -PoolSelectionMode = Enumeration('PoolSelectionMode', ('FromSardana', 'FromDatabase')) - +PoolSelectionMode = Enumeration( + 'PoolSelectionMode', ('FromSardana', 'FromDatabase')) + + class SelectPoolBasePage(wiz.SardanaBasePage): - - def __init__(self, parent = None, selectionMode=PoolSelectionMode.FromDatabase): + + def __init__(self, parent=None, selectionMode=PoolSelectionMode.FromDatabase): wiz.SardanaBasePage.__init__(self, parent) self.setSelectionMode(selectionMode) - + self['pool'] = self._getPool - + self.setSubTitle('Please select the Pool instance') - + panel = self.getPanelWidget() - + layout = QtGui.QFormLayout() - + self.poolCB = QtGui.QComboBox(panel) self.poolCB.setDuplicatesEnabled(False) self.poolCB.setEditable(False) @@ -31,26 +34,26 @@ def __init__(self, parent = None, selectionMode=PoolSelectionMode.FromDatabase): panel.setLayout(layout) - self.connect(self.poolCB, - QtCore.SIGNAL('currentIndexChanged(int)'), + self.connect(self.poolCB, + QtCore.SIGNAL('currentIndexChanged(int)'), QtCore.SIGNAL('completeChanged()')) - + def getSelectionMode(self): return self._selectionMode - + def setSelectionMode(self, selectionMode): self._selectionMode = selectionMode - + def _getPool(self): pool_server = str(self.poolCB.currentText()) return pool_server def pool(self): return self.wizard()['pool'] - + def db(self): return self.wizard()['db'] - + def isComplete(self): idx = self.poolCB.currentIndex() if idx >= 0: @@ -60,31 +63,32 @@ def isComplete(self): return False def getPoolServerList(self): - return [ s[s.index('/')+1:] for s in self.db().get_server_list() if s.startswith('Pool/') ] - + return [s[s.index('/') + 1:] for s in self.db().get_server_list() if s.startswith('Pool/')] + def _fillCB(self): self.poolCB.clear() mode = self.getSelectionMode() if mode == PoolSelectionMode.FromDatabase: self.poolCB.addItems(self.getPoolServerList()) else: - #TODO + # TODO pass - + def initializePage(self): wiz.SardanaBasePage.initializePage(self) self._fillCB() + def t1(tg_host=None, sardana=None): - PoolExamplePages = Enumeration('PoolExamplePages', - ('IntroPage', 'TangoPage', 'SardanaPage', 'PoolPage')) + PoolExamplePages = Enumeration('PoolExamplePages', + ('IntroPage', 'TangoPage', 'SardanaPage', 'PoolPage')) class PoolExampleIntroPage(wiz.SardanaIntroBasePage): def setNextPageId(self, id): self._nextPageId = id - + def nextId(self): return self._nextPageId @@ -94,23 +98,23 @@ class SelectTangoHostExamplePage(SelectTangoHostBasePage): def setNextPageId(self, id): self._nextPageId = id - + def nextId(self): return self._nextPageId - + from sardana_page import SelectSardanaBasePage class SelectSardanaExamplePage(SelectSardanaBasePage): def setNextPageId(self, id): self._nextPageId = id - + def nextId(self): return self._nextPageId - + app = QtGui.QApplication([]) QtCore.QResource.registerResource(wiz.get_resources()) - + w = wiz.SardanaBaseWizard() intro = PoolExampleIntroPage() @@ -123,7 +127,7 @@ def nextId(self): w.setPage(PoolExamplePages.TangoPage, tg_host_page) curr_page = tg_host_page else: - w['db'] = lambda : tau.Database(tg_host) + w['db'] = lambda: tau.Database(tg_host) if sardana is None: curr_page.setNextPageId(PoolExamplePages.SardanaPage) @@ -131,26 +135,25 @@ def nextId(self): w.setPage(PoolExamplePages.SardanaPage, sardana_page) curr_page = sardana_page else: - w['sardana'] = lambda : sardana + w['sardana'] = lambda: sardana curr_page.setNextPageId(PoolExamplePages.PoolPage) - + pool_page = SelectPoolBasePage(selectionMode=PoolSelectionMode.FromSardana) w.setPage(PoolExamplePages.PoolPage, pool_page) - + w.show() sys.exit(app.exec_()) - + + def main(): tg_host, sardana = None, None - if len(sys.argv) >1: + if len(sys.argv) > 1: tg_host = sys.argv[1] - if len(sys.argv) >2: + if len(sys.argv) > 2: sardana = sys.argv[2] - t1(tg_host=tg_host,sardana=sardana) + t1(tg_host=tg_host, sardana=sardana) if __name__ == '__main__': main() - - diff --git a/sardanaConfig/src/wizards/sardana_page.py b/sardanaConfig/src/wizards/sardana_page.py index a9566d44b4..8aecd96a78 100644 --- a/sardanaConfig/src/wizards/sardana_page.py +++ b/sardanaConfig/src/wizards/sardana_page.py @@ -1,4 +1,5 @@ -import sys, os +import sys +import os from PyQt4 import QtGui, QtCore, Qt @@ -6,20 +7,21 @@ import wiz from taurus.core.utils import Enumeration - + + class SelectSardanaBasePage(wiz.SardanaBasePage): - - def __init__(self, parent = None): + + def __init__(self, parent=None): wiz.SardanaBasePage.__init__(self, parent) - + self['sardana'] = self._getSardana - + self.setSubTitle('Please select the Sardana instance') - + panel = self.getPanelWidget() - + layout = QtGui.QFormLayout() - + self.sardanaCB = QtGui.QComboBox(panel) self.sardanaCB.setDuplicatesEnabled(False) self.sardanaCB.setEditable(False) @@ -28,20 +30,20 @@ def __init__(self, parent = None): panel.setLayout(layout) - self.connect(self.sardanaCB, - QtCore.SIGNAL('currentIndexChanged(int)'), + self.connect(self.sardanaCB, + QtCore.SIGNAL('currentIndexChanged(int)'), QtCore.SIGNAL('completeChanged()')) - + def _getSardana(self): sardana = str(self.sardanaCB.currentText()) return sardana def sardana(self): return self.wizard()['sardana'] - + def db(self): return self.wizard()['db'] - + def isComplete(self): idx = self.sardanaCB.currentIndex() if idx >= 0: @@ -49,7 +51,7 @@ def isComplete(self): return True self.setStatus('No instance selected') return False - + def _fillCB(self): self.sardanaCB.clear() db = self.db() @@ -58,20 +60,22 @@ def _fillCB(self): for service in services: service_instances.append(service.split('/', 1)[1]) self.sardanaCB.addItems(service_instances) - + def initializePage(self): wiz.SardanaBasePage.initializePage(self) self._fillCB() + def t1(tg_host=None): - SardanaExamplePages = Enumeration('SardanaExamplePages', ('IntroPage', 'TangoPage', 'SardanaPage')) + SardanaExamplePages = Enumeration( + 'SardanaExamplePages', ('IntroPage', 'TangoPage', 'SardanaPage')) class SardanaExampleIntroPage(wiz.SardanaIntroBasePage): def setNextPageId(self, id): self._nextPageId = id - + def nextId(self): return self._nextPageId @@ -81,18 +85,18 @@ class SelectTangoHostExamplePage(SelectTangoHostBasePage): def setNextPageId(self, id): self._nextPageId = id - + def nextId(self): return self._nextPageId - + app = QtGui.QApplication([]) QtCore.QResource.registerResource(wiz.get_resources()) - + w = wiz.SardanaBaseWizard() intro = SardanaExampleIntroPage() w.setPage(SardanaExamplePages.IntroPage, intro) - + curr_page = intro if tg_host is None: curr_page.setNextPageId(SardanaExamplePages.TangoPage) @@ -101,24 +105,23 @@ def nextId(self): w.setPage(SardanaExamplePages.TangoPage, tg_host_page) curr_page = tg_host_page else: - w['db'] = lambda : taurus.Database(tg_host) + w['db'] = lambda: taurus.Database(tg_host) curr_page.setNextPageId(SardanaExamplePages.SardanaPage) sardana_page = SelectSardanaBasePage() w.setPage(SardanaExamplePages.SardanaPage, sardana_page) - + w.show() sys.exit(app.exec_()) - + + def main(): import taurus taurus.setLogLevel(taurus.Warning) - tg_host=None - if len(sys.argv) >1: + tg_host = None + if len(sys.argv) > 1: tg_host = sys.argv[1] t1(tg_host=tg_host) if __name__ == '__main__': main() - - diff --git a/sardanaConfig/src/wizards/settings_widget.py b/sardanaConfig/src/wizards/settings_widget.py index 329e178350..aafb1329f4 100644 --- a/sardanaConfig/src/wizards/settings_widget.py +++ b/sardanaConfig/src/wizards/settings_widget.py @@ -7,54 +7,54 @@ ############## FAKE ###################################### + class PropertyInfo(object): + def __init__(self, name, type, format, default_value=None): self._name = name self._type = type self._format = format - self._default_value=default_value - + self._default_value = default_value + def get_name(self): return self._name def get_type(self): return self._type - + def get_format(self): return self._format - + def get_default_value(self): return self._default_value ####################################################### - ########################## BASIC INPUT WIDGETS ################# class InputWidget (object): - + @abstractmethod def setValue(self, value, undo=False): pass - - @abstractmethod + + @abstractmethod def getValue(self): return None - - @abstractmethod + + @abstractmethod def valueChanged(self): pass - + def deselectWidget(self): pass - class BooleanWidget(QtGui.QWidget, InputWidget): - + def __init__(self, parent=None): - QtGui.QWidget.__init__(self,parent) + QtGui.QWidget.__init__(self, parent) self._formLayout = QtGui.QHBoxLayout(self) self.trueButton = QtGui.QRadioButton(self) self._formLayout.addWidget(self.trueButton) @@ -62,41 +62,44 @@ def __init__(self, parent=None): self._formLayout.addWidget(self.falseButton) self.trueButton.setText("True") self.falseButton.setText("False") - QtCore.QObject.connect(self.trueButton, QtCore.SIGNAL("clicked()"), self.valueChanged) - QtCore.QObject.connect(self.falseButton, QtCore.SIGNAL("clicked()"), self.valueChanged) + QtCore.QObject.connect(self.trueButton, QtCore.SIGNAL( + "clicked()"), self.valueChanged) + QtCore.QObject.connect(self.falseButton, QtCore.SIGNAL( + "clicked()"), self.valueChanged) self.setValue(self.getDefaultValue(), undo=False) def valueChanged(self): if not (self.trueButton.isChecked() == self._actualValue): - self.emit(QtCore.SIGNAL("valueChanged"),self._actualValue,not self._actualValue) + self.emit(QtCore.SIGNAL("valueChanged"), + self._actualValue, not self._actualValue) self._actualValue = self.trueButton.isChecked() - + def setValue(self, value, undo=False): if value is None: value = self.getDefaultValue() self.trueButton.setChecked(value) self.falseButton.setChecked(not value) self._actualValue = value - + def getValue(self): return self.trueButton.isChecked() - - @classmethod + + @classmethod def getDefaultValue(self): return True - - + + class BooleanComboWidget(QtGui.QComboBox, InputWidget): - + def __init__(self, parent=None): - QtGui.QComboBox.__init__(self,parent) - self.addItems(["True","False"]) + QtGui.QComboBox.__init__(self, parent) + self.addItems(["True", "False"]) self.setValue(self.getDefaultValue(), undo=False) def setValue(self, value, undo=False): if value is None: value = self.getDefaultValue() - + if value is True: self.setCurrentIndex(0) else: @@ -104,112 +107,114 @@ def setValue(self, value, undo=False): def getValue(self): return not self.currentIndex() - + def valueChanged(self): pass - - @classmethod + + @classmethod def getDefaultValue(self): return True - - + + class IntegerWidget(QtGui.QLineEdit, InputWidget): - + def __init__(self, parent=None): - QtGui.QLineEdit.__init__(self,parent) + QtGui.QLineEdit.__init__(self, parent) self.setValidator(QtGui.QIntValidator(self)) self.setValue(self.getDefaultValue(), undo=False) - + def setValue(self, value, undo=False): if value is None: value = self.getDefaultValue() self.setText(str(value)) self._actualValue = value - + def getValue(self): try: return int(self.text()) except: return self.getDefaultValue() - - def focusOutEvent (self, event): #QFocusEvent - QtGui.QLineEdit.focusOutEvent(self,event) + + def focusOutEvent(self, event): # QFocusEvent + QtGui.QLineEdit.focusOutEvent(self, event) self.valueChanged() - + def valueChanged(self): if not (self.getValue() == self._actualValue): - self.emit(QtCore.SIGNAL("valueChanged"),self._actualValue, self.getValue() ) + self.emit(QtCore.SIGNAL("valueChanged"), + self._actualValue, self.getValue()) self._actualValue = self.getValue() - self.setValue(self.getValue(), undo=False) # if value is not valid - - @classmethod + self.setValue(self.getValue(), undo=False) # if value is not valid + + @classmethod def getDefaultValue(self): return 0 - - - + + class FloatWidget(QtGui.QLineEdit, InputWidget): - + def __init__(self, parent=None): - QtGui.QLineEdit.__init__(self,parent) + QtGui.QLineEdit.__init__(self, parent) self.setValidator(QtGui.QDoubleValidator(self)) self.setValue(self.getDefaultValue(), undo=False) - + def setValue(self, value, undo=False): if (value is None): value = self.getDefaultValue() self.setText(str(value)) self._actualValue = value - + def getValue(self): try: - return float(self.text()) + return float(self.text()) except: return self.getDefaultValue() - - def focusOutEvent (self, event): #QFocusEvent - QtGui.QLineEdit.focusOutEvent(self,event) + + def focusOutEvent(self, event): # QFocusEvent + QtGui.QLineEdit.focusOutEvent(self, event) self.valueChanged() - + def valueChanged(self): if not (self.getValue() == self._actualValue): - self.emit(QtCore.SIGNAL("valueChanged"),self._actualValue, self.getValue() ) + self.emit(QtCore.SIGNAL("valueChanged"), + self._actualValue, self.getValue()) self._actualValue = self.getValue() - self.setValue(self.getValue(), undo=False) # if value is not valid - - @classmethod + self.setValue(self.getValue(), undo=False) # if value is not valid + + @classmethod def getDefaultValue(self): return 0.0 class StringWidget(QtGui.QLineEdit, InputWidget): - + def __init__(self, parent=None): - QtGui.QLineEdit.__init__(self,parent) + QtGui.QLineEdit.__init__(self, parent) self.setValue(self.getDefaultValue(), undo=False) - + def setValue(self, value, undo=False): if value is None: value = self.getDefaultValue() self.setText(str(value)) self._actualValue = value - + def getValue(self): return str(self.text()) - + def textChanged(self, string): QtGui.QLineEdit.textChanged(self, string) - - def focusOutEvent (self, event): #QFocusEvent - QtGui.QLineEdit.focusOutEvent(self,event) + + def focusOutEvent(self, event): # QFocusEvent + QtGui.QLineEdit.focusOutEvent(self, event) self.valueChanged() - + def valueChanged(self): if not (self.getValue() == self._actualValue): - self.emit(QtCore.SIGNAL("valueChanged"),self._actualValue, self.getValue() ) + self.emit(QtCore.SIGNAL("valueChanged"), + self._actualValue, self.getValue()) self._actualValue = self.getValue() - self.setValue(self.getValue(), undo=False) # if value is not valid - + self.setValue(self.getValue(), undo=False) # if value is not valid + @classmethod def getDefaultValue(self): return "" @@ -218,10 +223,10 @@ def getDefaultValue(self): class TableWidget (QtGui.QWidget): - + def __init__(self, value, format, type, parent=None): QtGui.QWidget.__init__(self, parent) - self._actualValue =self.getDefaultValue() + self._actualValue = self.getDefaultValue() self._layout = QtGui.QHBoxLayout(self) self.setLayout(self._layout) self._tableView = QtGui.QTableView() @@ -232,19 +237,23 @@ def __init__(self, value, format, type, parent=None): self._type = type self._verticalLayout = QtGui.QVBoxLayout() self._addRowButton = QtGui.QPushButton(self) - self._addRowButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-add")) + self._addRowButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-add")) self._addRowButton.setText("Add Row ") self._verticalLayout.addWidget(self._addRowButton) self._removeRowButton = QtGui.QPushButton(self) - self._removeRowButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-remove")) + self._removeRowButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-remove")) self._removeRowButton.setText("Remove Row ") self._verticalLayout.addWidget(self._removeRowButton) self._addColumnButton = QtGui.QPushButton(self) - self._addColumnButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-add")) + self._addColumnButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-add")) self._addColumnButton.setText("Add Column") self._verticalLayout.addWidget(self._addColumnButton) self._removeColumnButton = QtGui.QPushButton(self) - self._removeColumnButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("list-remove")) + self._removeColumnButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("list-remove")) self._removeColumnButton.setText("Remove Column") self._verticalLayout.addWidget(self._removeColumnButton) self._upButton = QtGui.QPushButton(self) @@ -252,20 +261,28 @@ def __init__(self, value, format, type, parent=None): self._upButton.setText("Move Up ") self._verticalLayout.addWidget(self._upButton) self._downButton = QtGui.QPushButton(self) - self._downButton.setIcon(taurus.qt.qtgui.resource.getThemeIcon("go-down")) + self._downButton.setIcon( + taurus.qt.qtgui.resource.getThemeIcon("go-down")) self._downButton.setText("Move Down") self._verticalLayout.addWidget(self._downButton) - spacerItem = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacerItem = QtGui.QSpacerItem( + 20, 20, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self._verticalLayout.addItem(spacerItem) - - QtCore.QObject.connect(self._addRowButton, QtCore.SIGNAL("clicked()"), self._addRow) - QtCore.QObject.connect(self._addColumnButton, QtCore.SIGNAL("clicked()"), self._addColumn) - QtCore.QObject.connect(self._removeRowButton, QtCore.SIGNAL("clicked()"), self._removeRow) - QtCore.QObject.connect(self._removeColumnButton, QtCore.SIGNAL("clicked()"), self._removeColumn) - QtCore.QObject.connect(self._upButton, QtCore.SIGNAL("clicked()"), self._moveUp) - QtCore.QObject.connect(self._downButton, QtCore.SIGNAL("clicked()"), self._moveDown) + + QtCore.QObject.connect( + self._addRowButton, QtCore.SIGNAL("clicked()"), self._addRow) + QtCore.QObject.connect(self._addColumnButton, + QtCore.SIGNAL("clicked()"), self._addColumn) + QtCore.QObject.connect(self._removeRowButton, + QtCore.SIGNAL("clicked()"), self._removeRow) + QtCore.QObject.connect(self._removeColumnButton, + QtCore.SIGNAL("clicked()"), self._removeColumn) + QtCore.QObject.connect( + self._upButton, QtCore.SIGNAL("clicked()"), self._moveUp) + QtCore.QObject.connect( + self._downButton, QtCore.SIGNAL("clicked()"), self._moveDown) self._layout.addLayout(self._verticalLayout) - + if self._type == "boolean": self._delegate = BooleanTableDelegate(self._tableView) elif self._type == "integer": @@ -274,10 +291,12 @@ def __init__(self, value, format, type, parent=None): self._delegate = FloatTableDelegate(self._tableView) else: self._delegate = StringTableDelegate(self._tableView) - - QtCore.QObject.connect(self._delegate, QtCore.SIGNAL("editorValueChanged"), self._valueChanged) + + QtCore.QObject.connect(self._delegate, QtCore.SIGNAL( + "editorValueChanged"), self._valueChanged) self._tableView.setItemDelegate(self._delegate) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding) + sizePolicy = QtGui.QSizePolicy( + QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding) self._tableView.setSizePolicy(sizePolicy) self._tableView.horizontalHeader().setDefaultSectionSize(80) if self._format == "1D": @@ -291,7 +310,6 @@ def __init__(self, value, format, type, parent=None): self._upButton.hide() self._downButton.hide() - def mousePressEvent(self, event): if (event.button() == QtCore.Qt.LeftButton): index = self._tableView.indexAt(event.pos()) @@ -306,71 +324,70 @@ def mousePressEvent(self, event): self._tableView.clearSelection() else: QtGui.QTableView.mousePressEvent(self._tableView, event) - + def deselectWidget(self): self._tableView.clearSelection() - - + def _addRow(self): - value = self.getValue() # stored table - defaultCellsValue = self._delegate.getDefaultValue() # default value for every new item in the table - + value = self.getValue() # stored table + # default value for every new item in the table + defaultCellsValue = self._delegate.getDefaultValue() + rows = len(value) if (self._format == "2D"): - if (rows>0): + if (rows > 0): columns = len(value[0]) else: - columns=1 + columns = 1 rowIndex = self._getSelectedIndex()[0] - + if rowIndex is None: rowIndex = rows - + if (self._format == "1D"): value.insert(rowIndex, defaultCellsValue) - + if (self._format == "2D"): row = [] for i in range(columns): row.append(defaultCellsValue) value.insert(rowIndex, row) - + self.setValue(value, undo=True) - def _getSelectedIndex(self): - if len (self._tableView.selectedIndexes()): + if len(self._tableView.selectedIndexes()): row = self._tableView.selectedIndexes()[0].row() column = self._tableView.selectedIndexes()[0].column() else: row = None column = None - - return [row,column] - + return [row, column] + def _removeRow(self): rowIndex = self._getSelectedIndex()[0] if rowIndex is not None: msgBox = QtGui.QMessageBox() msgBox.setText("Confirmation ") - msgBox.setStandardButtons(QtGui.QMessageBox().No | QtGui.QMessageBox().Yes ) - msgBox.setInformativeText("Remove row {%i} ?" % (rowIndex+1) ) + msgBox.setStandardButtons( + QtGui.QMessageBox().No | QtGui.QMessageBox().Yes) + msgBox.setInformativeText("Remove row {%i} ?" % (rowIndex + 1)) msgBox.setIcon(QtGui.QMessageBox.Question) ret = msgBox.exec_() if ret == QtGui.QMessageBox().Yes: - value = self.getValue() - self.setValue(value[:rowIndex] + value[rowIndex+1:], undo=True) - + value = self.getValue() + self.setValue(value[:rowIndex] + value[rowIndex + 1:], undo=True) def _addColumn(self): - value = self.getValue() # stored table - defaultCellsValue = self._delegate.getDefaultValue() # default value for every new item in the table + value = self.getValue() # stored table + # default value for every new item in the table + defaultCellsValue = self._delegate.getDefaultValue() rows = len(value) - - if (rows>0): - + + if (rows > 0): + columns = len(value[0]) columnIndex = self._getSelectedIndex()[1] if columnIndex is None: @@ -379,81 +396,83 @@ def _addColumn(self): row.insert(columnIndex, defaultCellsValue) self.setValue(value, undo=True) else: - self._addRow() + self._addRow() - def _removeColumn(self): - value = self.getValue() # stored table + value = self.getValue() # stored table rows = len(value) columnIndex = self._getSelectedIndex()[1] - + if columnIndex is not None: msgBox = QtGui.QMessageBox() msgBox.setText("Confirmation ") - msgBox.setStandardButtons(QtGui.QMessageBox().No | QtGui.QMessageBox().Yes ) - msgBox.setInformativeText("Remove column {%i} ?" % (columnIndex+1) ) + msgBox.setStandardButtons( + QtGui.QMessageBox().No | QtGui.QMessageBox().Yes) + msgBox.setInformativeText( + "Remove column {%i} ?" % (columnIndex + 1)) msgBox.setIcon(QtGui.QMessageBox.Question) ret = msgBox.exec_() - if (rows>0) and (columnIndex is not None) and (ret ==QtGui.QMessageBox().Yes): + if (rows > 0) and (columnIndex is not None) and (ret == QtGui.QMessageBox().Yes): columns = len(value[0]) if columns == 1: self.setValue([], undo=False) else: for i in range(len(value)): - value[i] = value[i][:columnIndex] + value[i][columnIndex+1:] - + value[i] = value[i][:columnIndex] + \ + value[i][columnIndex + 1:] + self.setValue(value, undo=True) - - + def _moveUp(self): - value = self.getValue() # stored table + value = self.getValue() # stored table rows = len(value) rowIndex = self._getSelectedIndex()[0] - - if (rows>1) and (rowIndex is not None) and (rowIndex>0) : + + if (rows > 1) and (rowIndex is not None) and (rowIndex > 0): x = value.pop(rowIndex) - value.insert(rowIndex-1,x) + value.insert(rowIndex - 1, x) self.setValue(value, undo=True) - self._tableView.setCurrentIndex(self._tableView.model().index(rowIndex-1, 0 )) + self._tableView.setCurrentIndex( + self._tableView.model().index(rowIndex - 1, 0)) - def _moveDown(self): - value = self.getValue() # stored table + value = self.getValue() # stored table rows = len(value) rowIndex = self._getSelectedIndex()[0] - - if (rows>1) and (rowIndex is not None) and (rowIndex 1) and (rowIndex is not None) and (rowIndex < rows - 1): x = value.pop(rowIndex) - value.insert(rowIndex+1,x) + value.insert(rowIndex + 1, x) self.setValue(value, undo=True) - self._tableView.setCurrentIndex(self._tableView.model().index(rowIndex+1, 0 )) - - + self._tableView.setCurrentIndex( + self._tableView.model().index(rowIndex + 1, 0)) + def setValue(self, value, undo=False): if not self._actualValue == value: if undo: - self.emit(QtCore.SIGNAL("valueChanged"),copy.deepcopy(self._actualValue), copy.deepcopy(value) ) + self.emit(QtCore.SIGNAL("valueChanged"), copy.deepcopy( + self._actualValue), copy.deepcopy(value)) self._actualValue = copy.deepcopy(value) - + rows = len(value) - if (self._format == "2D") and (rows>0): + if (self._format == "2D") and (rows > 0): columns = len(value[0]) else: - columns = 1 - + columns = 1 + self._model = QtGui.QStandardItemModel(rows, columns) for row in range(rows): for column in range(columns): - + index = self._model.index(row, column, QtCore.QModelIndex()) if (self._format == "1D"): self._model.setData(index, QtCore.QVariant(value[row])) if (self._format == "2D"): - self._model.setData(index, QtCore.QVariant(value[row][column])) + self._model.setData( + index, QtCore.QVariant(value[row][column])) self._tableView.setModel(self._model) - - + def getValue(self): rows = self._model.rowCount() columns = self._model.columnCount() @@ -461,160 +480,165 @@ def getValue(self): for row in range(rows): records = [] for column in range(columns): - index = self._model.index(row, column) + index = self._model.index(row, column) if self._type == "integer": val, bool = self._model.data(index).toInt() - records.append( val ) + records.append(val) elif self._type == "float": - val, bool =self._model.data(index).toDouble() - records.append(val ) + val, bool = self._model.data(index).toDouble() + records.append(val) elif self._type == "boolean": - records.append( self._model.data(index).toBool() ) + records.append(self._model.data(index).toBool()) else: - records.append( str(self._model.data(index).toString()) ) - + records.append(str(self._model.data(index).toString())) + if (self._format == "1D"): result.append(records[0]) if (self._format == "2D"): result.append(records) - + return copy.deepcopy(result) - - + def _valueChanged(self, value, row, column): if (self._format == "1D"): if not (value == self._actualValue[row]): self._actualValue[row] = value - self.emit(QtCore.SIGNAL("valueChanged"),self.getValue()[:], self._actualValue[:] ) - - + self.emit(QtCore.SIGNAL("valueChanged"), + self.getValue()[:], self._actualValue[:]) + if (self._format == "2D"): if not (value == self._actualValue[row][column]): self._actualValue[row][column] = value - self.emit(QtCore.SIGNAL("valueChanged"),self.getValue()[:], self._actualValue[:] ) - - + self.emit(QtCore.SIGNAL("valueChanged"), + self.getValue()[:], self._actualValue[:]) + @classmethod def getDefaultValue(self): return [] ########### DELGATES ################## + class TableDelegate(QtGui.QItemDelegate): - def __init__(self, parent = None): + def __init__(self, parent=None): QtGui.QItemDelegate.__init__(self, parent) - + @abstractmethod def createEditor(self, parent, option, index): return None - + @abstractmethod - def setEditorData( self, editor, index ): + def setEditorData(self, editor, index): pass - + @abstractmethod def getDefaultValue(self): return None def setModelData(self, editor, model, index): - self.emit(QtCore.SIGNAL("editorValueChanged"),editor.getValue(),index.row(),index.column()) + self.emit(QtCore.SIGNAL("editorValueChanged"), + editor.getValue(), index.row(), index.column()) value = editor.getValue() - model.setData( index - , QtCore.QVariant( value ) ) + model.setData(index, QtCore.QVariant(value)) - def updateEditorGeometry( self, editor, option, index ): + def updateEditorGeometry(self, editor, option, index): editor.setGeometry(option.rect) - + class BooleanTableDelegate(TableDelegate): - + def createEditor(self, parent, option, index): - editor = BooleanComboWidget( parent ) - Qt.QObject.connect(editor, Qt.SIGNAL("currentIndexChanged(int)"), self.updateValue) + editor = BooleanComboWidget(parent) + Qt.QObject.connect(editor, Qt.SIGNAL( + "currentIndexChanged(int)"), self.updateValue) editor.installEventFilter(self) return editor - + def updateValue(self, int): - self.emit(QtCore.SIGNAL("closeEditor()") ) - - def setEditorData( self, editor, index ): + self.emit(QtCore.SIGNAL("closeEditor()")) + + def setEditorData(self, editor, index): value = index.model().data(index, QtCore.Qt.DisplayRole) editor.setValue(value.toBool(), undo=True) - + def getDefaultValue(self): return BooleanComboWidget.getDefaultValue() - + + class IntegerTableDelegate(TableDelegate): - + def createEditor(self, parent, option, index): - editor = IntegerWidget( parent ) + editor = IntegerWidget(parent) editor.installEventFilter(self) return editor - - def setEditorData( self, editor, index ): + + def setEditorData(self, editor, index): value, ok = index.model().data(index, QtCore.Qt.DisplayRole).toInt() editor.setValue(value, undo=True) def getDefaultValue(self): return IntegerWidget.getDefaultValue() - + + class FloatTableDelegate(TableDelegate): - + def createEditor(self, parent, option, index): - editor = FloatWidget( parent ) + editor = FloatWidget(parent) editor.installEventFilter(self) return editor - - def setEditorData( self, editor, index ): - value,ok = index.model().data(index, QtCore.Qt.DisplayRole).toDouble() + + def setEditorData(self, editor, index): + value, ok = index.model().data(index, QtCore.Qt.DisplayRole).toDouble() editor.setValue(value, undo=True) def getDefaultValue(self): return FloatWidget.getDefaultValue() - + + class StringTableDelegate(TableDelegate): - + def createEditor(self, parent, option, index): - editor = StringWidget( parent ) + editor = StringWidget(parent) editor.installEventFilter(self) return editor - - def setEditorData( self, editor, index ): + + def setEditorData(self, editor, index): value = index.model().data(index, QtCore.Qt.DisplayRole) editor.setValue(value.toString(), undo=True) - + def getDefaultValue(self): - return StringWidget.getDefaultValue() + return StringWidget.getDefaultValue() -################## MAIN CLASS #################### +################## MAIN CLASS #################### class Save (object): - def __init__ (self, object = None,prevValue = None, nextValue = None): + + def __init__(self, object=None, prevValue=None, nextValue=None): self._object = object self._prevValue = prevValue self._nextValue = nextValue - + def getObject(self): return self._object - - def getPrevValue(self): + + def getPrevValue(self): return self._prevValue - + def getNextValue(self): - return self._nextValue + return self._nextValue class SettingsWidget(QtGui.QWidget): - + def __init__(self, parent=None): - QtGui.QWidget.__init__(self,parent) + QtGui.QWidget.__init__(self, parent) self._formLayout = QtGui.QGridLayout(self) self.setUndoHistoryStack(20) - self._inputWidgts=[] + self._inputWidgts = [] self._edited = False self._properties = None - + def clearLayout(self, layout): while layout.count() > 0: item = layout.takeAt(0) @@ -622,54 +646,57 @@ def clearLayout(self, layout): continue w = item.widget() if w: - w.deleteLater() - - def _valueChanged(self,value1,value2): + w.deleteLater() + + def _valueChanged(self, value1, value2): self._edited = True - self._undoHistoryStack.append( Save( self.sender(), copy.deepcopy(value1), copy.deepcopy(value2) ) ) - if len(self._undoHistoryStack)> self._historySize: + self._undoHistoryStack.append( + Save(self.sender(), copy.deepcopy(value1), copy.deepcopy(value2))) + if len(self._undoHistoryStack) > self._historySize: self._undoHistoryStack.pop(0) - item , position =self._historyStackPointer - if len(self._undoHistoryStack)-1 >=0: - for i in range (item+1, len(self._undoHistoryStack)-1): - self._undoHistoryStack.pop(item+1) - self._historyStackPointer = ( len(self._undoHistoryStack)-1 , 1 ) - + item, position = self._historyStackPointer + if len(self._undoHistoryStack) - 1 >= 0: + for i in range(item + 1, len(self._undoHistoryStack) - 1): + self._undoHistoryStack.pop(item + 1) + self._historyStackPointer = (len(self._undoHistoryStack) - 1, 1) + self.emit(Qt.SIGNAL("propertyValueChanged()")) - + def setUndoHistoryStack(self, size): self._undoHistoryStack = [] self._historySize = size - self._historyStackPointer = (-1,1) # item, position - + self._historyStackPointer = (-1, 1) # item, position + def undo(self): - item , position =self._historyStackPointer - if position ==1: + item, position = self._historyStackPointer + if position == 1: item = item position = 0 else: if item > 0: - item = item -1 - position =0 - - self._historyStackPointer = (item,position) - if (item >=0) and(item < len(self._undoHistoryStack)): - self._undoHistoryStack[item].getObject().setValue(self._undoHistoryStack[item].getPrevValue(), undo=False) - - def redo(self): - item , position =self._historyStackPointer - if position ==0: + item = item - 1 + position = 0 + + self._historyStackPointer = (item, position) + if (item >= 0) and(item < len(self._undoHistoryStack)): + self._undoHistoryStack[item].getObject().setValue( + self._undoHistoryStack[item].getPrevValue(), undo=False) + + def redo(self): + item, position = self._historyStackPointer + if position == 0: item = item position = 1 else: - if item < len(self._undoHistoryStack)-1: - item = item +1 - position =1 - - self._historyStackPointer = (item,position) - - if (item >=0) and(item < len(self._undoHistoryStack)): - self._undoHistoryStack[item].getObject().setValue(self._undoHistoryStack[item].getNextValue(), undo=False) + if item < len(self._undoHistoryStack) - 1: + item = item + 1 + position = 1 + + self._historyStackPointer = (item, position) + + if (item >= 0) and(item < len(self._undoHistoryStack)): + self._undoHistoryStack[item].getObject().setValue( + self._undoHistoryStack[item].getNextValue(), undo=False) # def keyPressEvent(self, event): # QtGui.QWidget.keyPressEvent(self, event) @@ -681,100 +708,108 @@ def redo(self): # self.redo() def setEdited(self, value): - self._edited=value + self._edited = value def isEdited(self): - return self._edited - + return self._edited + def deselect(self): for widget in self._inputWidgts: if widget != self.sender(): widget.deselectWidget() - + def getProperties(self): - values=[] + values = [] name = "noName" properties = self._properties - if len(self._inputWidgts)>=1: + if len(self._inputWidgts) >= 1: for inputWidget in self._inputWidgts: - values.append(inputWidget.getValue()) + values.append(inputWidget.getValue()) name = values.pop(0) - + return (properties, name, values) - + def _nameChanged(self): self.emit(Qt.SIGNAL("propertyValueChanged()")) - + def setProperties(self, properties): - + # clean memory for item in self._inputWidgts: - QtCore.QObject.disconnect(item, QtCore.SIGNAL("valueChanged"), self._valueChanged) - self._inputWidgts=[] + QtCore.QObject.disconnect(item, QtCore.SIGNAL( + "valueChanged"), self._valueChanged) + self._inputWidgts = [] self.clearLayout(self._formLayout) self.setUndoHistoryStack(self._historySize) self._edited = False # create new set of properties - + self._properties = properties - + if properties is not None: self._inputWidgts = [] - i=0 + i = 0 for property in properties: self._nameLabel = QtGui.QLabel(property.get_name()) #self._formLayout.setWidget(i, QtGui.QFormLayout.LabelRole, self._nameLabel) - self._formLayout.addWidget(self._nameLabel,i,0) - + self._formLayout.addWidget(self._nameLabel, i, 0) + if property.get_format() == "0D": if property.get_type() == "boolean": - self._inputWidgts.append( BooleanWidget() ) + self._inputWidgts.append(BooleanWidget()) elif property.get_type() == "integer": - self._inputWidgts.append( IntegerWidget() ) + self._inputWidgts.append(IntegerWidget()) elif property.get_type() == "float": - self._inputWidgts.append( FloatWidget() ) + self._inputWidgts.append(FloatWidget()) else: - self._inputWidgts.append( StringWidget() ) - - spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self._formLayout.addWidget(self._inputWidgts[i], i,1) - self._formLayout.addItem(spacerItem,i,2) - + self._inputWidgts.append(StringWidget()) + + spacerItem = QtGui.QSpacerItem( + 40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self._formLayout.addWidget(self._inputWidgts[i], i, 1) + self._formLayout.addItem(spacerItem, i, 2) + elif (property.get_format() == "1D") or (property.get_format() == "2D"): - self._inputWidgts.append( TableWidget(property.get_default_value(), property.get_format() ,property.get_type() ) ) - self._formLayout.addWidget(self._inputWidgts[i], i,1,1,10) - Qt.QObject.connect(self._inputWidgts[i], Qt.SIGNAL("selected"), self.deselect) - + self._inputWidgts.append(TableWidget( + property.get_default_value(), property.get_format(), property.get_type())) + self._formLayout.addWidget( + self._inputWidgts[i], i, 1, 1, 10) + Qt.QObject.connect(self._inputWidgts[i], Qt.SIGNAL( + "selected"), self.deselect) + self._inputWidgts[i].setValue(property.get_default_value()) - QtCore.QObject.connect(self._inputWidgts[i], QtCore.SIGNAL("valueChanged"), self._valueChanged) - i=i+1 - - QtCore.QObject.connect(self._inputWidgts[0], QtCore.SIGNAL("textChanged(QString)"), self._nameChanged) - - - + QtCore.QObject.connect(self._inputWidgts[i], QtCore.SIGNAL( + "valueChanged"), self._valueChanged) + i = i + 1 + + QtCore.QObject.connect(self._inputWidgts[0], QtCore.SIGNAL( + "textChanged(QString)"), self._nameChanged) + + if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) properties = [] properties.append(PropertyInfo("name", "string", "0D", "deviceName")) properties.append(PropertyInfo("number0", "integer", "0D", 5)) - properties.append(PropertyInfo("boollll0", "boolean", "0D", False)) + properties.append(PropertyInfo("boollll0", "boolean", "0D", False)) properties.append(PropertyInfo("number1", "float", "0D", 3.5)) properties.append(PropertyInfo("string2", "string", "0D", "hehe")) - properties.append(PropertyInfo("table0", "integer", "1D", [1,2,3])) + properties.append(PropertyInfo("table0", "integer", "1D", [1, 2, 3])) properties.append(PropertyInfo("tablestringD1", "float", "1D", [1.5])) - properties.append(PropertyInfo("tablestringD1", "string", "1D", ["aaaa","bbb","ccc"])) - properties.append(PropertyInfo("tablefloatD1", "float", "1D", [1.0,2.5,3.6])) - properties.append(PropertyInfo("tablebooleanD1", "boolean", "1D", [True,False,True])) - properties.append(PropertyInfo("tableboointD1", "integer", "1D", [1,2,3])) - properties.append(PropertyInfo("tablestringD2", "string", "2D",[ ["aaaa","bbb","ccc"],["aaaa2","bbb2","ccc2"],["aaaa3","bbb3","ccc3"] ])) - - - nds=SettingsWidget() + properties.append(PropertyInfo("tablestringD1", "string", + "1D", ["aaaa", "bbb", "ccc"])) + properties.append(PropertyInfo( + "tablefloatD1", "float", "1D", [1.0, 2.5, 3.6])) + properties.append(PropertyInfo("tablebooleanD1", + "boolean", "1D", [True, False, True])) + properties.append(PropertyInfo( + "tableboointD1", "integer", "1D", [1, 2, 3])) + properties.append(PropertyInfo("tablestringD2", "string", "2D", [ + ["aaaa", "bbb", "ccc"], ["aaaa2", "bbb2", "ccc2"], ["aaaa3", "bbb3", "ccc3"]])) + + nds = SettingsWidget() nds.setProperties(properties) nds.show() sys.exit(app.exec_()) - - \ No newline at end of file diff --git a/sardanaConfig/src/wizards/simple_tree_model.py b/sardanaConfig/src/wizards/simple_tree_model.py index 6e38a9e28e..ad722de208 100644 --- a/sardanaConfig/src/wizards/simple_tree_model.py +++ b/sardanaConfig/src/wizards/simple_tree_model.py @@ -13,13 +13,14 @@ from __future__ import print_function from __future__ import unicode_literals from future_builtins import * -import sys, os +import sys +import os import bisect import codecs import taurus.qt.qtgui.resource import PyQt4.QtGui from PyQt4.QtCore import (QAbstractItemModel, QModelIndex, QString, - QVariant, Qt, SIGNAL) + QVariant, Qt, SIGNAL) KEY, NODE = range(2) @@ -44,7 +45,7 @@ def __len__(self): def childAtRow(self, row): assert 0 <= row < len(self.children) return self.children[row][NODE] - + def rowOfChild(self, child): for i, item in enumerate(self.children): if item[NODE] == child: @@ -95,17 +96,17 @@ def __init__(self, name, data, parent=None): self.data = data def orderKey(self): - return "\t"+self.name.lower() - + return "\t" + self.name.lower() + def getName(self): return self.name def asRecord(self): return self.getName() - - def asData(self): + + def asData(self): return self.data - + class SimpleTreeModel(QAbstractItemModel): @@ -114,13 +115,13 @@ def __init__(self, parent=None): self.columns = 1 self.root = BranchNode("") self.headers = ["Type"] - + def setHeaders(self, headers): self.headers = headers - + def getHeaders(self): return self.headers - + def addNodes(self, fields, callReset=True): root = self.root branch = None @@ -134,13 +135,13 @@ def addNodes(self, fields, callReset=True): root.insertChild(branch) root = branch if callReset: - self.reset() + self.reset() self.headers = ["Type"] - + def addRecord(self, fields, data, callReset=True): root = self.root branch = None - for i in range(len(fields)-1): + for i in range(len(fields) - 1): key = fields[i].lower() branch = root.childWithKey(key) if branch is not None: @@ -150,10 +151,10 @@ def addRecord(self, fields, data, callReset=True): root.insertChild(branch) root = branch assert branch is not None - item = fields[len(fields)-1] + item = fields[len(fields) - 1] branch.insertChild(LeafNode(item, data, branch)) if callReset: - self.reset() + self.reset() self.headers = ["Type"] def asRecord(self, index): @@ -180,8 +181,8 @@ def columnCount(self, parent): def data(self, index, role): if role == Qt.TextAlignmentRole: - return QVariant(int(Qt.AlignTop|Qt.AlignLeft)) - + return QVariant(int(Qt.AlignTop | Qt.AlignLeft)) + if role == Qt.DecorationRole: node = self.nodeFromIndex(index) assert node is not None @@ -189,13 +190,13 @@ def data(self, index, role): return QVariant(node.asData().get_icon()) else: return QVariant() - + if role != Qt.DisplayRole: return QVariant() - + node = self.nodeFromIndex(index) assert node is not None - + if isinstance(node, BranchNode): if index.column() == 0: return QVariant(node.toString()) @@ -207,12 +208,11 @@ def data(self, index, role): def headerData(self, section, orientation, role): if (orientation == Qt.Horizontal and - role == Qt.DisplayRole): + role == Qt.DisplayRole): #assert 0 <= section <= len(self.headers) return QVariant(self.headers[section]) return QVariant() - def index(self, row, column, parent): assert self.root branch = self.nodeFromIndex(parent) @@ -234,14 +234,11 @@ def parent(self, child): assert row != -1 return self.createIndex(row, 0, parent) - def nodeFromIndex(self, index): if index.isValid(): return index.internalPointer() else: return self.root - - #return (index.internalPointer() + + # return (index.internalPointer() # if index.isValid() else self.root)###################### - - diff --git a/sardanaConfig/src/wizards/tango_host_page.py b/sardanaConfig/src/wizards/tango_host_page.py index 6fd4b4efeb..bfa02dc2be 100644 --- a/sardanaConfig/src/wizards/tango_host_page.py +++ b/sardanaConfig/src/wizards/tango_host_page.py @@ -1,22 +1,26 @@ -import sys, os +import sys +import os from PyQt4 import QtGui, QtCore, Qt import taurus import wiz + def get_default_tango_host(): - tg = os.environ.get('TANGO_HOST','') - if not tg or tg.count(':') != 1: return '','' + tg = os.environ.get('TANGO_HOST', '') + if not tg or tg.count(':') != 1: + return '', '' return tg.split(':') + class SelectTangoHostBasePage(wiz.SardanaBasePage): - - def __init__(self, parent = None): + + def __init__(self, parent=None): wiz.SardanaBasePage.__init__(self, parent) - + self.setSubTitle('Please select the Tango Host') - + panel = self.getPanelWidget() layout = QtGui.QFormLayout() self.hostEdit = QtGui.QLineEdit() @@ -26,21 +30,21 @@ def __init__(self, parent = None): layout.addRow("&Port", self.portEdit) host, port = get_default_tango_host() - + self.hostEdit.setText(host) self.portEdit.setText(port) - + panel.setLayout(layout) self['db'] = self._getDatabase - - self.connect(self.hostEdit, - QtCore.SIGNAL('textEdited(const QString &)'), + + self.connect(self.hostEdit, + QtCore.SIGNAL('textEdited(const QString &)'), QtCore.SIGNAL('completeChanged()')) - self.connect(self.portEdit, - QtCore.SIGNAL('textEdited(const QString &)'), + self.connect(self.portEdit, + QtCore.SIGNAL('textEdited(const QString &)'), QtCore.SIGNAL('completeChanged()')) - + def _getDatabase(self): host = str(self.hostEdit.text()).lower() port = str(self.portEdit.text()) @@ -48,7 +52,7 @@ def _getDatabase(self): def db(self): return self.wizard()['db'] - + def isComplete(self): try: db = self.db() @@ -59,7 +63,8 @@ def isComplete(self): pass self.setStatus('Invalid database') return False - + + def t1(): app = QtGui.QApplication([]) QtCore.QResource.registerResource(wiz.get_resources()) @@ -71,10 +76,9 @@ def t1(): w.show() sys.exit(app.exec_()) + def main(): t1() if __name__ == '__main__': main() - - diff --git a/sardanaConfig/src/wizards/wiz.py b/sardanaConfig/src/wizards/wiz.py index fe4bc00a30..5d5f8b1c6a 100644 --- a/sardanaConfig/src/wizards/wiz.py +++ b/sardanaConfig/src/wizards/wiz.py @@ -1,29 +1,31 @@ -import os, sys +import os +import sys from PyQt4 import QtGui, QtCore, Qt + class SardanaBasePage(QtGui.QWizardPage): - - def __init__(self, parent = None): + + def __init__(self, parent=None): QtGui.QWizardPage.__init__(self, parent) self._item_funcs = {} - + self.setPixmap(QtGui.QWizard.LogoPixmap, QtGui.QPixmap(":/logo.jpg")) - + layout = QtGui.QVBoxLayout() - + self._panel = QtGui.QWidget() - + self._status_label = QtGui.QLabel() self._status_label.setAutoFillBackground(True) palette = self._status_label.palette() gradient = QtGui.QLinearGradient(0, 0, 0, 15) - gradient.setColorAt(0.0, Qt.QColor.fromRgb( 60, 150, 255)) - gradient.setColorAt(0.5, Qt.QColor.fromRgb( 0, 85, 227)) - gradient.setColorAt(1.0, Qt.QColor.fromRgb( 60, 150, 255)) + gradient.setColorAt(0.0, Qt.QColor.fromRgb(60, 150, 255)) + gradient.setColorAt(0.5, Qt.QColor.fromRgb(0, 85, 227)) + gradient.setColorAt(1.0, Qt.QColor.fromRgb(60, 150, 255)) gradient.setSpread(QtGui.QGradient.RepeatSpread) palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush(gradient)) palette.setBrush(QtGui.QPalette.WindowText, Qt.Qt.white) - + layout.addWidget(self._panel) layout.addStretch() layout.addWidget(self._status_label) @@ -34,7 +36,7 @@ def __setitem__(self, name, value): def __getitem__(self, name): return self._item_funcs[name] - + def setStatus(self, text): self._status_label.setText(text) @@ -43,22 +45,24 @@ def getPanelWidget(self): class SardanaIntroBasePage(QtGui.QWizardPage): - - def __init__(self, parent = None): + + def __init__(self, parent=None): QtGui.QWizardPage.__init__(self, parent) - + self.setTitle('Introduction') - self.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap(":/watermark.jpg")) - + self.setPixmap(QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(":/watermark.jpg")) + label = QtGui.QLabel(self.getIntroText()) label.setWordWrap(True) layout = QtGui.QVBoxLayout() layout.addWidget(label) self.setLayout(layout) - + def getIntroText(self): return """This wizard will guide you through the Sardana configuration""" + class SardanaBaseWizard(QtGui.QWizard): def __init__(self, parent=None): @@ -68,18 +72,18 @@ def __init__(self, parent=None): def __setitem__(self, name, value): self._item_funcs[name] = value - + def __getitem__(self, name): for id in self.getPages(): p = self.page(id) if isinstance(p, SardanaBasePage): try: return p[name]() - except Exception,e: + except Exception, e: pass return self._item_funcs[name]() return None - + def addPage(self, page): id = QtGui.QWizard.addPage(self, page) self._pages[id] = page @@ -87,15 +91,17 @@ def addPage(self, page): def setPage(self, id, page): QtGui.QWizard.setPage(self, id, page) self._pages[id] = page - + def getPages(self): return self._pages + def get_resources(): res_fname = os.path.abspath(__file__) res_fname = os.path.splitext(res_fname)[0] + '.rcc' return res_fname + def t1(): app = QtGui.QApplication([]) QtCore.QResource.registerResource(get_resources()) @@ -110,6 +116,7 @@ def t1(): w.show() sys.exit(app.exec_()) + def main(): t1() diff --git a/scripts/h5toascii b/scripts/h5toascii index 4a42be1475..ceafcd1b30 100755 --- a/scripts/h5toascii +++ b/scripts/h5toascii @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -37,51 +37,57 @@ Note: only scalar values are extracted ''' import nxs -import sys,os +import sys +import os import numpy def measurement2ascii(fd, entryname, ofname): - #check if there is a measurement datagroup - tmp = "/%s/measurement"%entryname + # check if there is a measurement datagroup + tmp = "/%s/measurement" % entryname try: fd.openpath(tmp) except: - print 'Cannot open hdf5 path "%s". Skipping.'%tmp - return False - - #read the point number data - ptnb_names = ('Pt_No','point_nb','#Pt No') #possible ways of storing the point number (along different versions) - for i,ptnb_name in enumerate(ptnb_names): - try: + print 'Cannot open hdf5 path "%s". Skipping.' % tmp + return False + + # read the point number data + # possible ways of storing the point number (along different versions) + ptnb_names = ('Pt_No', 'point_nb', '#Pt No') + for i, ptnb_name in enumerate(ptnb_names): + try: fd.opendata(ptnb_name) break except: - print 'cannot open %s'%ptnb_name - if i == len(ptnb_names)-1: #if this was not the last choice + print 'cannot open %s' % ptnb_name + if i == len(ptnb_names) - 1: # if this was not the last choice print 'I give up!' - return False + return False ptnb = fd.getdata() fd.closedata() - #prepare a list with column names and a table made of data "columns" - namelist=[ptnb_name] + # prepare a list with column names and a table made of data "columns" + namelist = [ptnb_name] table = [ptnb.copy().flatten()] - for name,nxclass in fd.entries(): - if name == ptnb_name: continue - if nxclass != 'SDS': continue #not a dataset - dshape,dtype = fd.getinfo() - if tuple(dshape) != ptnb.shape: continue #not a scalar (incompatible shape) + for name, nxclass in fd.entries(): + if name == ptnb_name: + continue + if nxclass != 'SDS': + continue # not a dataset + dshape, dtype = fd.getinfo() + if tuple(dshape) != ptnb.shape: + continue # not a scalar (incompatible shape) table.append(fd.getdata().flatten()) namelist.append(name) - #write the table to a file + # write the table to a file try: - datfile = open(ofname,'w') + datfile = open(ofname, 'w') except: - print 'Cannot create file "%s". Skipping.'%ofname + print 'Cannot create file "%s". Skipping.' % ofname return False - datfile.write("\t".join(namelist)) #write a header of column names + datfile.write("\t".join(namelist)) # write a header of column names datfile.write("\n") - numpy.savetxt(datfile, numpy.vstack(table).transpose(), delimiter='\t') #write the data table + numpy.savetxt(datfile, numpy.vstack(table).transpose(), + delimiter='\t') # write the data table datfile.close() return True @@ -92,27 +98,27 @@ def main(): else: print "Usage:\nh5toascii [ [] ...] " sys.exit(1) - - entrynames = sys.argv[2:] - - fd = nxs.open(fname,'r') - - if len(entrynames)==0: - entrynames = [n for n,c in fd.entries() if c=='NXentry'] - - dirname,ext = os.path.splitext(fname) + + entrynames = sys.argv[2:] + + fd = nxs.open(fname, 'r') + + if len(entrynames) == 0: + entrynames = [n for n, c in fd.entries() if c == 'NXentry'] + + dirname, ext = os.path.splitext(fname) try: os.makedirs(dirname) except: - print 'Cannot create dir "%s". Skipping.'%dirname - + print 'Cannot create dir "%s". Skipping.' % dirname + for ename in entrynames: - ofname = os.path.join(dirname,"%s.dat"%ename) - print "Extracting %s:%s to %s"%(fname,ename,ofname) + ofname = os.path.join(dirname, "%s.dat" % ename) + print "Extracting %s:%s to %s" % (fname, ename, ofname) measurement2ascii(fd, ename, ofname) - + fd.close() if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/scripts/h5tospec b/scripts/h5tospec index 724ada0154..7b342082f0 100755 --- a/scripts/h5tospec +++ b/scripts/h5tospec @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -33,38 +33,43 @@ Note: only scalar values are extracted, Images and 1D (MCA..) are ignored (notif ''' import nxs -import sys,os,re,time +import sys +import os +import re +import time def h52spectime(mydate): ''' this function returns the time in format SPEC (from a hdf5 recorded by the sardanan recorder) ''' - #equivalent to ascii time - #return time.strftime("%a %b %d %H:%M:%S %Y",_d) - _a = time.asctime(time.strptime(mydate.split('.')[0],"%Y-%m-%dT%H:%M:%S")) + # equivalent to ascii time + # return time.strftime("%a %b %d %H:%M:%S %Y",_d) + _a = time.asctime(time.strptime(mydate.split('.')[0], "%Y-%m-%dT%H:%M:%S")) return _a + def _getMovables(mystr): ''' this internal function gets the movables from the "scan/mesh" command. Movables should go first in SPEC columns ''' - #gets the movables from the command line (starting not with a number) + # gets the movables from the command line (starting not with a number) _m = [] - _a = mystr.split(' ') + _a = mystr.split(' ') _a.pop(0) for i in _a: - if re.match('[^-_0-9\.\+\\n]',i): + if re.match('[^-_0-9\.\+\\n]', i): _m.append(i) - return _m + return _m + def getMetadata(fd, entry): ''' This gets the metatdata from the Sardana h5 file. Format is kind of free, but nevertheless is very convenient the user/scientist makes sure all motors (and motor positions) are there - ''' + ''' _mdata = {} try: fd.openpath("/%s/measurement/pre_scan_snapshot" % entry) @@ -74,11 +79,11 @@ def getMetadata(fd, entry): _mdata[i] = fd.getdata() #print >> sys.stderr, entry except: - print >> sys.stderr, 'Cannot open hdf5 path "%s/pre_scan_snapshot". Skipping.'%entry + print >> sys.stderr, 'Cannot open hdf5 path "%s/pre_scan_snapshot". Skipping.' % entry return _mdata -def processEntry(fd, entry): +def processEntry(fd, entry): ''' process one entry from a hdf5 file it creates a string with all the data and prints it to the stdout in the end. @@ -87,8 +92,10 @@ def processEntry(fd, entry): ''' - #_myMovables = [] # This gets the motors in order to write them in the first columns - mystring = "" # the string will construct the scan (and printed at the end) + # _myMovables = [] # This gets the motors in order to write them in the + # first columns + # the string will construct the scan (and printed at the end) + mystring = "" try: fd.openpath("/%s/entry_identifier" % entry) @@ -96,63 +103,67 @@ def processEntry(fd, entry): fd.openpath("/%s/title" % entry) _mycmd = str(fd.getdata()) mystring += " %s \n" % _mycmd - _myMovables= _getMovables(_mycmd) + _myMovables = _getMovables(_mycmd) fd.openpath("/%s/start_time" % entry) mystring += "#D %s \n" % h52spectime(fd.getdata()) - # need to know here the timer for the counting time. In the mean time - # I use the last value of the cmd line (usually the ct time!!, not always ojo). + # need to know here the timer for the counting time. In the mean time + # I use the last value of the cmd line (usually the ct time!!, not + # always ojo). mystring += "#T %s (seconds)\n" % _mycmd.split(' ').pop() - #print mytime + # print mytime except: - print >> sys.stderr, 'Error opening/processing hdf5 path "%s/...". Skipping.'% entry + print >> sys.stderr, 'Error opening/processing hdf5 path "%s/...". Skipping.' % entry - mystring += "#P0 " - _metadata = getMetadata(fd, entry) - for i in _metadata.values(): - mystring += ' ' + str(i) + mystring += "#P0 " + _metadata = getMetadata(fd, entry) + for i in _metadata.values(): + mystring += ' ' + str(i) mystring += '\n' tmp = "/%s/measurement/point_nb" % entry - tmp2= "/%s/measurement/Pt_No" % entry + tmp2 = "/%s/measurement/Pt_No" % entry try: fd.openpath(tmp) except: - #print 'Cannot open hdf5 path "%s". Skipping.'%tmp + # print 'Cannot open hdf5 path "%s". Skipping.'%tmp try: fd.openpath(tmp2) except: - #print 'Cannot open hdf5 path "%s". Skipping.'%tmp - return False + # print 'Cannot open hdf5 path "%s". Skipping.'%tmp + return False ptnb = fd.getdata() fd.closedata() - headers = [] - data = {} + headers = [] + data = {} - for name,nxclass in fd.entries(): - if name == 'point_nb' or name == "#Pt No": continue - if name == 'pre_scan_snapshot' : continue - dshape,dtype = fd.getinfo() + for name, nxclass in fd.entries(): + if name == 'point_nb' or name == "#Pt No": + continue + if name == 'pre_scan_snapshot': + continue + dshape, dtype = fd.getinfo() - if tuple(dshape) != ptnb.shape: - print >> sys.stderr, "Skipping (no data or not a scalar ???) %s in %s" % (name, entry), + if tuple(dshape) != ptnb.shape: + print >> sys.stderr, "Skipping (no data or not a scalar ???) %s in %s" % ( + name, entry), print >> sys.stderr, ptnb.shape - continue #not a scalar (incompatible shape) + continue # not a scalar (incompatible shape) - #insert data and headers in the rigth order (movables first) + # insert data and headers in the rigth order (movables first) mydata = fd.getdata().flatten() if name in _myMovables: headers.insert(_myMovables.index(name), name) else: headers.append(name) - data[name] = mydata - + data[name] = mydata + mystring += "#N %d \n" % len(headers) - mystring += "#L " + mystring += "#L " for i in headers: mystring += ' ' + i - mystring += "\n" + mystring += "\n" #print >>sys.stderr, headers #print >>sys.stderr, _myMovables @@ -162,9 +173,9 @@ def processEntry(fd, entry): for i in range(ptnb.size): # Movables (motors) come first. Then the other columns (exp channels) - for n in [channel for channel in _myMovables if channel in headers]: + for n in [channel for channel in _myMovables if channel in headers]: mystring += ' ' + str(data[n][i]) - for n in [channel for channel in headers if channel not in _myMovables]: + for n in [channel for channel in headers if channel not in _myMovables]: mystring += ' ' + str(data[n][i]) mystring += '\n' @@ -172,10 +183,10 @@ def processEntry(fd, entry): fd.openpath("/%s/end_time" % entry) mystring += "#C Scan ended at %s \n" % h52spectime(fd.getdata()) except: - print >> sys.stderr, 'Cannot open hdf5 path "%s/end_time". Skipping.'% entry + print >> sys.stderr, 'Cannot open hdf5 path "%s/end_time". Skipping.' % entry print mystring - + def measurement2spec(fd): """ @@ -187,29 +198,32 @@ def measurement2spec(fd): mystring = "" mystring += "#F %s\n" % fd.filename - outFileAttrs = "#CCC original Nexus hdf5 file: %s\n" % fd.getattrs() + outFileAttrs = "#CCC original Nexus hdf5 file: %s\n" % fd.getattrs() outCurrentDate = "#C conversion date: %s\n" % time.asctime() - entrynames = [name for name,c in fd.entries() if c=='NXentry'] - + entrynames = [name for name, c in fd.entries() if c == 'NXentry'] + mystring += "#E %s\n" % fd.getattrs()['epoch'] - mystring += "#D %s\n" % time.asctime(time.localtime(fd.getattrs()['epoch'])) - mystring += "#C User \n" - - # Gets metadata headers (motor names usually) from the first entry (asuming all the same!) - _metadata = getMetadata(fd,entrynames[0]) - mystring += "#O0" - for i in _metadata.keys(): - mystring += ' ' + i - - mystring += '\n' + outFileAttrs - mystring += outCurrentDate - print mystring - - #Sort entry2 before entry10 (otherwhise, it was strictly alphabetic) - for entry in sorted(entrynames, key = len): + mystring += "#D %s\n" % time.asctime( + time.localtime(fd.getattrs()['epoch'])) + mystring += "#C User \n" + + # Gets metadata headers (motor names usually) from the first entry + # (asuming all the same!) + _metadata = getMetadata(fd, entrynames[0]) + mystring += "#O0" + for i in _metadata.keys(): + mystring += ' ' + i + + mystring += '\n' + outFileAttrs + mystring += outCurrentDate + print mystring + + # Sort entry2 before entry10 (otherwhise, it was strictly alphabetic) + for entry in sorted(entrynames, key=len): processEntry(fd, entry) + def main(): ''' process the entire file (todo: many things. Do only the selected entries, convert it to a class) @@ -219,11 +233,11 @@ def main(): else: print "Usage:\npython h5tospec [> ] [2> log/error file]" sys.exit(1) - - fd = nxs.open(fname,'r') - + + fd = nxs.open(fname, 'r') + measurement2spec(fd) - + fd.close() if __name__ == "__main__": diff --git a/scripts/spectoascii b/scripts/spectoascii index 875a49395a..06ce44705e 100755 --- a/scripts/spectoascii +++ b/scripts/spectoascii @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -39,7 +39,9 @@ SPEC_FileRecorder may not be converted properly. ''' -import sys,os +import sys +import os + def main(): if len(sys.argv) > 1: @@ -47,41 +49,41 @@ def main(): else: print "Usage:\nspectoascii [ [] ...] " sys.exit(1) - + scanids = sys.argv[2:] or None - - f = open(fname,'r') + + f = open(fname, 'r') s = f.read() f.close() - - dirname,ext = os.path.splitext(fname) + + dirname, ext = os.path.splitext(fname) try: os.makedirs(dirname) except: - print 'Cannot create dir "%s". Skipping.'%dirname - + print 'Cannot create dir "%s". Skipping.' % dirname + for scan in s.split('\n\n'): lines = scan.split('\n') if not lines[0].startswith('#S '): continue scan_name = lines[0].split()[1] - if scanids is None or scan_name in scanids: #extract only selected ids - ofname = os.path.join(dirname,"%s.dat"%scan_name) - print "Extracting %s:%s to %s"%(fname,scan_name,ofname) + if scanids is None or scan_name in scanids: # extract only selected ids + ofname = os.path.join(dirname, "%s.dat" % scan_name) + print "Extracting %s:%s to %s" % (fname, scan_name, ofname) try: - ofile = open(ofname,'w') + ofile = open(ofname, 'w') except: - print 'Cannot create file "%s". Skipping.'%ofname + print 'Cannot create file "%s". Skipping.' % ofname continue for line in lines[1:]: if line.startswith('#L '): - ofile.write('\t'.join(line[3:].split(' '))+'\n') + ofile.write('\t'.join(line[3:].split(' ')) + '\n') elif line.startswith('#'): continue else: - ofile.write('\t'.join(line.split())+'\n') + ofile.write('\t'.join(line.split()) + '\n') ofile.close() if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/scripts/upgrade/from_01_to_02.py b/scripts/upgrade/from_01_to_02.py index d36902862a..2e0c04e96c 100644 --- a/scripts/upgrade/from_01_to_02.py +++ b/scripts/upgrade/from_01_to_02.py @@ -2,7 +2,9 @@ from upgrade_utils import * + class Controller: + def __init__(self, type, file, kcls, name, id): self.type = type self.file = file @@ -22,16 +24,17 @@ class Up01To02(Upgrade): def get_pool_controllers(self, db, serv): """Gets the list of Pool controllers from pool version 0.1.x""" pool_serv_name = "Pool/%s" % serv - pool_dev_name = get_pool_device_from_server(serv,db=db) - ctrls = db.get_device_property(pool_dev_name, ["Controller"])["Controller"] + pool_dev_name = get_pool_device_from_server(serv, db=db) + ctrls = db.get_device_property( + pool_dev_name, ["Controller"])["Controller"] i = 0 ret = [] while i < len(ctrls): type = ctrls[i] - file = ctrls[i+1] - kcls = ctrls[i+2] - name = ctrls[i+3] - id = ctrls[i+4] + file = ctrls[i + 1] + kcls = ctrls[i + 2] + name = ctrls[i + 3] + id = ctrls[i + 4] i += 5 ret.append(Controller(type, file, kcls, name, id)) return ret @@ -52,24 +55,23 @@ def supports_old(cls, old_vers): def supports_new(cls, new_vers): return new_vers.startswith('0.2') - def upgrade(self, db, serv, old_vers, new_vers): - + if not Up01To02.supports(old_vers, new_vers): raise Exception("Unsupported upgrade") - + yield "Upgrading %s from %s to %s... " % (serv, old_vers, new_vers), 1 id = 1 - + pending_put_properties = {} - + # map used to store elem_map, reverse_elem_map = {}, {} - + pool_serv_name = "Pool/%s" % serv - pool_dev_name = get_pool_device_from_server(serv,db=db) - + pool_dev_name = get_pool_device_from_server(serv, db=db) + # 1 - Update the controller property with unique id yield "Updating the controller property with unique id...", 5 controllers = self.get_pool_controllers(db, serv) @@ -82,16 +84,18 @@ def upgrade(self, db, serv, old_vers, new_vers): reverse_elem_map[c.name.lower()] = c.id id += 1 - db.put_device_property(pool_dev_name, { "Controller" : ctrl_prop_value }) + db.put_device_property(pool_dev_name, {"Controller": ctrl_prop_value}) # 2 - Update PoolPath: replace ':' by '\n' yield "Updating PoolPath: replace ':' by '%sn'..." % '\\', 10 - pool_path = db.get_device_property(pool_dev_name, ["PoolPath"])["PoolPath"] + pool_path = db.get_device_property( + pool_dev_name, ["PoolPath"])["PoolPath"] pool_path_prop_value = [] for p in pool_path: pool_path_prop_value.extend(p.split(":")) - db.put_device_property(pool_dev_name, { "PoolPath" : pool_path_prop_value }) + db.put_device_property( + pool_dev_name, {"PoolPath": pool_path_prop_value}) # 3 - Update the properties of all elements elems = db.get_device_class_list(pool_serv_name) @@ -99,8 +103,9 @@ def upgrade(self, db, serv, old_vers, new_vers): i = 0 elems_dict = {} while i < len(elems): - dev, kcls = elems[i], elems[i+1] - if not elems_dict.has_key(kcls): elems_dict[kcls] = [] + dev, kcls = elems[i], elems[i + 1] + if not elems_dict.has_key(kcls): + elems_dict[kcls] = [] elems_dict[kcls].append(dev) i += 2 @@ -113,18 +118,20 @@ def upgrade(self, db, serv, old_vers, new_vers): if c.name.lower() == ctrl.lower(): ctrl = c.id - props = { "id" : [str(id)], "ctrl_id" : [str(ctrl)], "axis" : [str(axis)] } + props = {"id": [str(id)], "ctrl_id": [ + str(ctrl)], "axis": [str(axis)]} db.put_device_property(m_dev_name, props) db.delete_device_property(m_dev_name, ["motor_id"]) - + m_alias = db.get_alias(m_dev_name) elem_map[id] = m_alias.lower() reverse_elem_map[m_alias.lower()] = id - + id += 1 - - # 3.2 - For Counter remove 'channel_id' and add 'id', 'ctrl_id' and 'axis' + + # 3.2 - For Counter remove 'channel_id' and add 'id', 'ctrl_id' and + # 'axis' yield "Updating counters...", 20 for expch_dev_name in elems_dict.get("CTExpChannel", []): exp, ctrl, axis = expch_dev_name.split("/") @@ -133,15 +140,16 @@ def upgrade(self, db, serv, old_vers, new_vers): if c.name.lower() == ctrl.lower(): ctrl = c.id - props = { "id" : [str(id)], "ctrl_id" : [str(ctrl)], "axis" : [str(axis)] } - + props = {"id": [str(id)], "ctrl_id": [ + str(ctrl)], "axis": [str(axis)]} + db.put_device_property(expch_dev_name, props) db.delete_device_property(expch_dev_name, ["channel_id"]) expch_alias = db.get_alias(expch_dev_name) elem_map[id] = expch_alias.lower() reverse_elem_map[expch_alias.lower()] = id - + id += 1 # 3.3 - For 0D remove 'channel_id' and add 'id', 'ctrl_id' and 'axis' @@ -153,15 +161,16 @@ def upgrade(self, db, serv, old_vers, new_vers): if c.name.lower() == ctrl.lower(): ctrl = c.id - props = { "id" : [str(id)], "ctrl_id" : [str(ctrl)], "axis" : [str(axis)] } + props = {"id": [str(id)], "ctrl_id": [ + str(ctrl)], "axis": [str(axis)]} db.put_device_property(expch_dev_name, props) db.delete_device_property(expch_dev_name, ["channel_id"]) - + expch_alias = db.get_alias(expch_dev_name) elem_map[id] = expch_alias.lower() reverse_elem_map[expch_alias.lower()] = id - + id += 1 # 3.4 - For 1D remove 'channel_id' and add 'id', 'ctrl_id' and 'axis' @@ -173,7 +182,8 @@ def upgrade(self, db, serv, old_vers, new_vers): if c.name.lower() == ctrl.lower(): ctrl = c.id - props = { "id" : [str(id)], "ctrl_id" : [str(ctrl)], "axis" : [str(axis)] } + props = {"id": [str(id)], "ctrl_id": [ + str(ctrl)], "axis": [str(axis)]} db.put_device_property(expch_dev_name, props) db.delete_device_property(expch_dev_name, ["channel_id"]) @@ -181,7 +191,7 @@ def upgrade(self, db, serv, old_vers, new_vers): expch_alias = db.get_alias(expch_dev_name) elem_map[id] = expch_alias.lower() reverse_elem_map[expch_alias.lower()] = id - + id += 1 # 3.5 - For 2D remove 'channel_id' and add 'id', 'ctrl_id' and 'axis' @@ -193,18 +203,20 @@ def upgrade(self, db, serv, old_vers, new_vers): if c.name.lower() == ctrl.lower(): ctrl = c.id - props = { "id" : [str(id)], "ctrl_id" : [str(ctrl)], "axis" : [str(axis)] } + props = {"id": [str(id)], "ctrl_id": [ + str(ctrl)], "axis": [str(axis)]} db.put_device_property(expch_dev_name, props) db.delete_device_property(expch_dev_name, ["channel_id"]) - + expch_alias = db.get_alias(expch_dev_name) elem_map[id] = expch_alias.lower() reverse_elem_map[expch_alias.lower()] = id - + id += 1 - # 3.6 - For CommunicationChannel remove 'channel_id' and add 'id', 'ctrl_id' and 'axis' + # 3.6 - For CommunicationChannel remove 'channel_id' and add 'id', + # 'ctrl_id' and 'axis' yield "Updating Communication channels...", 40 for comch_dev_name in elems_dict.get("CommunicationChannel", []): com, ctrl, axis = comch_dev_name.split("/") @@ -213,7 +225,8 @@ def upgrade(self, db, serv, old_vers, new_vers): if c.name.lower() == ctrl.lower(): ctrl = c.id - props = { "id" : [str(id)], "ctrl_id" : [str(ctrl)], "axis" : [str(axis)] } + props = {"id": [str(id)], "ctrl_id": [ + str(ctrl)], "axis": [str(axis)]} db.put_device_property(comch_dev_name, props) db.delete_device_property(comch_dev_name, ["channel_id"]) @@ -221,10 +234,11 @@ def upgrade(self, db, serv, old_vers, new_vers): comch_alias = db.get_alias(comch_dev_name) elem_map[id] = comch_alias.lower() reverse_elem_map[comch_alias.lower()] = id - + id += 1 - # 3.7 - For IORegister remove 'channel_id' and add 'id', 'ctrl_id' and 'axis' + # 3.7 - For IORegister remove 'channel_id' and add 'id', 'ctrl_id' and + # 'axis' yield "Updating IORegisters...", 45 for ior_dev_name in elems_dict.get("IORegister", []): ior, ctrl, axis = ior_dev_name.split("/") @@ -233,7 +247,8 @@ def upgrade(self, db, serv, old_vers, new_vers): if c.name.lower() == ctrl.lower(): ctrl = c.id - props = { "id" : [str(id)], "ctrl_id" : [str(ctrl)], "axis" : [str(axis)] } + props = {"id": [str(id)], "ctrl_id": [ + str(ctrl)], "axis": [str(axis)]} db.put_device_property(ior_dev_name, props) db.delete_device_property(ior_dev_name, ["channel_id"]) @@ -241,7 +256,7 @@ def upgrade(self, db, serv, old_vers, new_vers): ior_alias = db.get_alias(ior_dev_name) elem_map[id] = ior_alias.lower() reverse_elem_map[ior_alias.lower()] = id - + id += 1 # 3.8 - For MotorGroup remove 'motor_group_id' and add 'id' @@ -249,17 +264,20 @@ def upgrade(self, db, serv, old_vers, new_vers): for mg_dev_name in elems_dict.get("MotorGroup", []): mg, inst, name = mg_dev_name.split("/") - props = { "id" : [str(id)] } + props = {"id": [str(id)]} db.put_device_property(mg_dev_name, props) - db.delete_device_property(mg_dev_name, ["motor_group_id", "pool_device"]) + db.delete_device_property( + mg_dev_name, ["motor_group_id", "pool_device"]) mg_alias = db.get_alias(mg_dev_name) elem_map[id] = mg_alias.lower() reverse_elem_map[mg_alias.lower()] = id - - # change the format of some properties from list of names to list of IDs - props = ('motor_list', 'motor_group_list', 'pseudo_motor_list', 'phys_group_elt', 'user_group_elt') + + # change the format of some properties from list of names to list + # of IDs + props = ('motor_list', 'motor_group_list', + 'pseudo_motor_list', 'phys_group_elt', 'user_group_elt') props = db.get_device_property(mg_dev_name, props) pending_put_properties[mg_dev_name.lower()] = {} @@ -268,160 +286,200 @@ def upgrade(self, db, serv, old_vers, new_vers): skip = True for name in props['motor_list']: # if all are already IDs, skip the property - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_motor_list.append(reverse_elem_map.get(name.lower(), name.lower())) + new_motor_list.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'motor_list': new_motor_list}) - + pending_put_properties[mg_dev_name.lower()].update( + {'motor_list': new_motor_list}) + new_motor_group_list = [] skip = True for name in props['motor_group_list']: # if all are already IDs, skip the property - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_motor_group_list.append(reverse_elem_map.get(name.lower(), name.lower())) + new_motor_group_list.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'motor_group_list': new_motor_group_list}) + pending_put_properties[mg_dev_name.lower()].update( + {'motor_group_list': new_motor_group_list}) new_pseudo_motor_list = [] skip = True for name in props['pseudo_motor_list']: # if all are already IDs, skip the property - try: int(name) + try: + int(name) except Exception, e: skip = False - new_pseudo_motor_list.append(reverse_elem_map.get(name.lower(), name.lower())) + new_pseudo_motor_list.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'pseudo_motor_list': new_pseudo_motor_list}) + pending_put_properties[mg_dev_name.lower()].update( + {'pseudo_motor_list': new_pseudo_motor_list}) new_phys_group_elt = [] skip = True for name in props['phys_group_elt']: # if all are already IDs, skip the property - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_phys_group_elt.append(reverse_elem_map.get(name.lower(), name.lower())) + new_phys_group_elt.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'phys_group_elt': new_phys_group_elt}) + pending_put_properties[mg_dev_name.lower()].update( + {'phys_group_elt': new_phys_group_elt}) new_user_group_elt = [] skip = True for name in props['user_group_elt']: # if all are already IDs, skip the property - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_user_group_elt.append(reverse_elem_map.get(name.lower(), name.lower())) + new_user_group_elt.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'user_group_elt': new_user_group_elt}) - + pending_put_properties[mg_dev_name.lower()].update( + {'user_group_elt': new_user_group_elt}) + id += 1 - + # 3.9 - For MeasurementGroup remove 'measurement_group_id' and add 'id' yield "Updating MeasurementGroups...", 55 for mg_dev_name in elems_dict.get("MeasurementGroup", []): mg, inst, name = mg_dev_name.split("/") - props = { "id" : [str(id)] } + props = {"id": [str(id)]} db.put_device_property(mg_dev_name, props) - db.delete_device_property(mg_dev_name, ["measurement_group_id", "pool_device"]) + db.delete_device_property( + mg_dev_name, ["measurement_group_id", "pool_device"]) mg_alias = db.get_alias(mg_dev_name) elem_map[id] = mg_alias.lower() reverse_elem_map[mg_alias.lower()] = id - + props = ('ct_list', 'zerodexpchannel_list', 'onedexpchannel_list', 'twodexpchannel_list', 'pseudocounter_list', 'motor_list', 'phys_group_elt', 'user_group_elt') props = db.get_device_property(mg_dev_name, props) - + pending_put_properties[mg_dev_name.lower()] = {} - + new_ct_list = [] skip = True for name in props['ct_list']: - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_ct_list.append(reverse_elem_map.get(name.lower(), name.lower())) + new_ct_list.append(reverse_elem_map.get( + name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'ct_list': new_ct_list}) + pending_put_properties[mg_dev_name.lower()].update( + {'ct_list': new_ct_list}) new_zerodexpchannel_list = [] skip = True for name in props['zerodexpchannel_list']: - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_zerodexpchannel_list.append(reverse_elem_map.get(name.lower(), name.lower())) + new_zerodexpchannel_list.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'zerodexpchannel_list': new_zerodexpchannel_list}) + pending_put_properties[mg_dev_name.lower()].update( + {'zerodexpchannel_list': new_zerodexpchannel_list}) new_onedexpchannel_list = [] skip = True for name in props['onedexpchannel_list']: - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_onedexpchannel_list.append(reverse_elem_map.get(name.lower(), name.lower())) + new_onedexpchannel_list.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'onedexpchannel_list': new_onedexpchannel_list}) + pending_put_properties[mg_dev_name.lower()].update( + {'onedexpchannel_list': new_onedexpchannel_list}) new_twodexpchannel_list = [] skip = True for name in props['twodexpchannel_list']: - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_twodexpchannel_list.append(reverse_elem_map.get(name.lower(), name.lower())) + new_twodexpchannel_list.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'twodexpchannel_list': new_twodexpchannel_list}) + pending_put_properties[mg_dev_name.lower()].update( + {'twodexpchannel_list': new_twodexpchannel_list}) new_pseudocounter_list = [] skip = True for name in props['pseudocounter_list']: - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_pseudocounter_list.append(reverse_elem_map.get(name.lower(), name.lower())) + new_pseudocounter_list.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'pseudocounter_list': new_pseudocounter_list}) + pending_put_properties[mg_dev_name.lower()].update( + {'pseudocounter_list': new_pseudocounter_list}) new_motor_list = [] skip = True for name in props['motor_list']: - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_motor_list.append(reverse_elem_map.get(name.lower(), name.lower())) + new_motor_list.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'motor_list': new_motor_list}) + pending_put_properties[mg_dev_name.lower()].update( + {'motor_list': new_motor_list}) new_phys_group_elt = [] skip = True for name in props['phys_group_elt']: - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_phys_group_elt.append(reverse_elem_map.get(name.lower(), name.lower())) + new_phys_group_elt.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'phys_group_elt': new_phys_group_elt}) + pending_put_properties[mg_dev_name.lower()].update( + {'phys_group_elt': new_phys_group_elt}) new_user_group_elt = [] skip = True for name in props['user_group_elt']: - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_user_group_elt.append(reverse_elem_map.get(name.lower(), name.lower())) + new_user_group_elt.append( + reverse_elem_map.get(name.lower(), name.lower())) if not skip: - pending_put_properties[mg_dev_name.lower()].update({'user_group_elt': new_user_group_elt}) - + pending_put_properties[mg_dev_name.lower()].update( + {'user_group_elt': new_user_group_elt}) + id += 1 # 3.10 - For PseudoMotor remove 'pseudo_motor_id', 'motor_group', 'role' @@ -435,11 +493,12 @@ def upgrade(self, db, serv, old_vers, new_vers): if c.name.lower() == ctrl.lower(): ctrl = c.id - props = { "id" : [str(id)], - "ctrl_id" : [str(ctrl)], - "axis" : [str(axis)] } - - prop_values = db.get_device_property(pm_dev_name, ["motor_group", "motor_group_id", "motor_list"]) + props = {"id": [str(id)], + "ctrl_id": [str(ctrl)], + "axis": [str(axis)]} + + prop_values = db.get_device_property( + pm_dev_name, ["motor_group", "motor_group_id", "motor_list"]) motor_group = prop_values["motor_group"] if not motor_group: @@ -449,26 +508,29 @@ def upgrade(self, db, serv, old_vers, new_vers): else: motor_group = motor_group[0] motor_group_dev_name = db.get_device_alias(motor_group) - motor_group_id = db.get_device_property(motor_group_dev_name,["id"])["id"][0] + motor_group_id = db.get_device_property( + motor_group_dev_name, ["id"])["id"][0] props["motor_group_id"] = [str(motor_group_id)] db.put_device_property(pm_dev_name, props) - db.delete_device_property(pm_dev_name, ["pseudo_motor_id", "motor_group", "role", "role_idx"]) + db.delete_device_property( + pm_dev_name, ["pseudo_motor_id", "motor_group", "role", "role_idx"]) skip = True motor_ids = [] for name in prop_values["motor_list"]: - try: int(name) - except Exception,e: + try: + int(name) + except Exception, e: skip = False motor_ids.append(reverse_elem_map[name.lower()]) if not skip: - db.put_device_property(pm_dev_name, { "motor_list" : motor_ids }) + db.put_device_property(pm_dev_name, {"motor_list": motor_ids}) pm_alias = db.get_alias(pm_dev_name) elem_map[id] = pm_alias.lower() reverse_elem_map[pm_alias.lower()] = id - + id += 1 # 3.11 - For PseudoCounter remove 'pseudo_counter_id', 'role' and @@ -482,29 +544,33 @@ def upgrade(self, db, serv, old_vers, new_vers): if c.name.lower() == ctrl.lower(): ctrl = c.id - props = { "id" : [str(id)], - "ctrl_id" : [str(ctrl)], - "axis" : [str(axis)] } + props = {"id": [str(id)], + "ctrl_id": [str(ctrl)], + "axis": [str(axis)]} db.put_device_property(pc_dev_name, props) - db.delete_device_property(pc_dev_name, ["pseudo_counter_id", "role", "role_idx"]) + db.delete_device_property( + pc_dev_name, ["pseudo_counter_id", "role", "role_idx"]) + + channel_list = db.get_device_property( + pc_dev_name, "channel_list")["channel_list"] - channel_list = db.get_device_property(pc_dev_name, "channel_list")["channel_list"] - skip = True channel_ids = [] for name in channel_list: - try: int(name) - except Exception,e: + try: + int(name) + except Exception, e: skip = False channel_ids.append(reverse_elem_map[name.lower()]) if not skip: - db.put_device_property(pm_dev_name, { "channel_list" : channel_ids }) - + db.put_device_property( + pm_dev_name, {"channel_list": channel_ids}) + pc_alias = db.get_alias(pc_dev_name) elem_map[id] = pc_alias.lower() reverse_elem_map[pc_alias.lower()] = id - + id += 1 # 4. - Apply pending properties @@ -518,7 +584,7 @@ def upgrade(self, db, serv, old_vers, new_vers): # 5. - Finally update the version property in the database yield "Updating the version property in the database...", 85 - db.put_device_property(pool_dev_name, { "Version" : [new_vers] }) + db.put_device_property(pool_dev_name, {"Version": [new_vers]}) # 6. - Check if the service is already registered yield "Checking if the service is already registered...", 95 @@ -527,4 +593,3 @@ def upgrade(self, db, serv, old_vers, new_vers): db.register_service("Sardana", serv, pool_dev_name) yield "Finished", 100 - diff --git a/scripts/upgrade/from_02_to_03.py b/scripts/upgrade/from_02_to_03.py index f54a17212e..36e1f23635 100644 --- a/scripts/upgrade/from_02_to_03.py +++ b/scripts/upgrade/from_02_to_03.py @@ -4,7 +4,9 @@ import PyTango from upgrade_utils import * + class Controller: + def __init__(self, type, file, kcls, name, id): self.type = type self.file = file @@ -26,15 +28,16 @@ def get_pool_controllers(self, serv, db=None): pool_serv_name = "Pool/%s" % serv pool_dev_name = get_pool_device_from_server(serv) db = db or get_db() - ctrls = db.get_device_property(pool_dev_name, ["Controller"])["Controller"] + ctrls = db.get_device_property( + pool_dev_name, ["Controller"])["Controller"] i = 0 ret = [] while i < len(ctrls): type = ctrls[i] - file = ctrls[i+1] - kcls = ctrls[i+2] - name = ctrls[i+3] - id = ctrls[i+4] + file = ctrls[i + 1] + kcls = ctrls[i + 2] + name = ctrls[i + 3] + id = ctrls[i + 4] i += 5 ret.append(Controller(type, file, kcls, name, id)) return ret @@ -56,21 +59,21 @@ def supports_new(cls, new_vers): return new_vers.startswith('0.3') def upgrade(self, db, serv, old_vers, new_vers): - + if not Up02To03.supports(old_vers, new_vers): raise Exception("Unsupported upgrade") yield "Upgrading %s from %s to %s... " % (serv, old_vers, new_vers), 1 id = 1 - + pending_put_properties = {} - + # map used to store elem_map, reverse_elem_map = {}, {} pool_serv_name = "Pool/%s" % serv - pool_dev_name = get_pool_device_from_server(serv,db=db) + pool_dev_name = get_pool_device_from_server(serv, db=db) # 1 - get controllers @@ -80,24 +83,27 @@ def upgrade(self, db, serv, old_vers, new_vers): i = 0 elems_dict = {} while i < len(elems): - dev, kcls = elems[i], elems[i+1] - if not elems_dict.has_key(kcls): elems_dict[kcls] = [] + dev, kcls = elems[i], elems[i + 1] + if not elems_dict.has_key(kcls): + elems_dict[kcls] = [] elems_dict[kcls].append(dev) i += 2 # 3.1 - store motors yield "Storing motor information...", 5 for m_dev_name in elems_dict.get("Motor", []): - props = db.get_device_property(m_dev_name, ("id", "ctrl_id", "axis")) + props = db.get_device_property( + m_dev_name, ("id", "ctrl_id", "axis")) id = int(props["id"][0]) m_alias = db.get_alias(m_dev_name).lower() elem_map[id] = m_alias reverse_elem_map[m_alias] = id - + # 3.2 - store counter timers yield "Storing counter information...", 10 for expch_dev_name in elems_dict.get("CTExpChannel", []): - props = db.get_device_property(expch_dev_name, ("id", "ctrl_id", "axis")) + props = db.get_device_property( + expch_dev_name, ("id", "ctrl_id", "axis")) id = int(props["id"][0]) expch_alias = db.get_alias(expch_dev_name).lower() elem_map[id] = expch_alias @@ -106,7 +112,8 @@ def upgrade(self, db, serv, old_vers, new_vers): # 3.3 - store 0D yield "Storing 0D information...", 15 for expch_dev_name in elems_dict.get("ZeroDExpChannel", []): - props = db.get_device_property(expch_dev_name, ("id", "ctrl_id", "axis")) + props = db.get_device_property( + expch_dev_name, ("id", "ctrl_id", "axis")) id = int(props["id"][0]) expch_alias = db.get_alias(expch_dev_name).lower() elem_map[id] = expch_alias @@ -115,7 +122,8 @@ def upgrade(self, db, serv, old_vers, new_vers): # 3.4 - store 1D yield "Storing 1D information...", 20 for expch_dev_name in elems_dict.get("OneDExpChannel", []): - props = db.get_device_property(expch_dev_name, ("id", "ctrl_id", "axis")) + props = db.get_device_property( + expch_dev_name, ("id", "ctrl_id", "axis")) id = int(props["id"][0]) expch_alias = db.get_alias(expch_dev_name).lower() elem_map[id] = expch_alias @@ -124,7 +132,8 @@ def upgrade(self, db, serv, old_vers, new_vers): # 3.5 - store 2D yield "Storing 2D information...", 25 for expch_dev_name in elems_dict.get("TwoDExpChannel", []): - props = db.get_device_property(expch_dev_name, ("id", "ctrl_id", "axis")) + props = db.get_device_property( + expch_dev_name, ("id", "ctrl_id", "axis")) id = int(props["id"][0]) expch_alias = db.get_alias(expch_dev_name).lower() elem_map[id] = expch_alias @@ -133,7 +142,8 @@ def upgrade(self, db, serv, old_vers, new_vers): # 3.6 - store communication channels yield "Storing communication channel information...", 30 for comch_dev_name in elems_dict.get("CommunicationChannel", []): - props = db.get_device_property(comch_dev_name, ("id", "ctrl_id", "axis")) + props = db.get_device_property( + comch_dev_name, ("id", "ctrl_id", "axis")) id = int(props["id"][0]) comch_alias = db.get_alias(comch_dev_name).lower() elem_map[id] = comch_alias @@ -142,7 +152,8 @@ def upgrade(self, db, serv, old_vers, new_vers): # 3.7 - store IO register yield "Storing ioregister information...", 35 for ior_dev_name in elems_dict.get("IORegister", []): - props = db.get_device_property(ior_dev_name, ("id", "ctrl_id", "axis")) + props = db.get_device_property( + ior_dev_name, ("id", "ctrl_id", "axis")) id = int(props["id"][0]) ior_alias = db.get_alias(ior_dev_name).lower() elem_map[id] = ior_alias @@ -152,7 +163,8 @@ def upgrade(self, db, serv, old_vers, new_vers): yield "Storing MotorGroup information...", 40 for mg_dev_name in elems_dict.get("MotorGroup", []): mg_dev_name = mg_dev_name.lower() - props = ('id', 'motor_list', 'motor_group_list', 'pseudo_motor_list', 'phys_group_elt', 'user_group_elt') + props = ('id', 'motor_list', 'motor_group_list', + 'pseudo_motor_list', 'phys_group_elt', 'user_group_elt') props = db.get_device_property(mg_dev_name, props) id = int(props["id"][0]) mg_alias = db.get_alias(mg_dev_name).lower() @@ -166,61 +178,73 @@ def upgrade(self, db, serv, old_vers, new_vers): for name in props['motor_list']: name = name.lower() # if all are already IDs, skip the property - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False new_motor_list.append(reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'motor_list': new_motor_list}) - + pending_put_properties[mg_dev_name].update( + {'motor_list': new_motor_list}) + new_motor_group_list = [] skip = True for name in props['motor_group_list']: name = name.lower() # if all are already IDs, skip the property - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_motor_group_list.append(reverse_elem_map.get(name, name)) + new_motor_group_list.append( + reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'motor_group_list': new_motor_group_list}) + pending_put_properties[mg_dev_name].update( + {'motor_group_list': new_motor_group_list}) new_pseudo_motor_list = [] skip = True for name in props['pseudo_motor_list']: name = name.lower() # if all are already IDs, skip the property - try: int(name) + try: + int(name) except Exception, e: skip = False - new_pseudo_motor_list.append(reverse_elem_map.get(name, name)) + new_pseudo_motor_list.append( + reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'pseudo_motor_list': new_pseudo_motor_list}) + pending_put_properties[mg_dev_name].update( + {'pseudo_motor_list': new_pseudo_motor_list}) new_phys_group_elt = [] skip = True for name in props['phys_group_elt']: name = name.lower() # if all are already IDs, skip the property - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False new_phys_group_elt.append(reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'phys_group_elt': new_phys_group_elt}) + pending_put_properties[mg_dev_name].update( + {'phys_group_elt': new_phys_group_elt}) new_user_group_elt = [] skip = True for name in props['user_group_elt']: name = name.lower() # if all are already IDs, skip the property - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False new_user_group_elt.append(reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'user_group_elt': new_user_group_elt}) - + pending_put_properties[mg_dev_name].update( + {'user_group_elt': new_user_group_elt}) + # 3.9 - For MeasurementGroup remove 'measurement_group_id' and add 'id' yield "Storing MeasurementGroup information...", 45 for mg_dev_name in elems_dict.get("MeasurementGroup", []): @@ -233,108 +257,129 @@ def upgrade(self, db, serv, old_vers, new_vers): mg_alias = db.get_alias(mg_dev_name).lower() elem_map[id] = mg_alias reverse_elem_map[mg_alias] = id - + pending_put_properties[mg_dev_name] = {} - + new_ct_list = [] skip = True for name in props['ct_list']: name = name.lower() - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False new_ct_list.append(reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'ct_list': new_ct_list}) + pending_put_properties[mg_dev_name].update( + {'ct_list': new_ct_list}) new_zerodexpchannel_list = [] skip = True for name in props['zerodexpchannel_list']: name = name.lower() - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_zerodexpchannel_list.append(reverse_elem_map.get(name, name)) + new_zerodexpchannel_list.append( + reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'zerodexpchannel_list': new_zerodexpchannel_list}) + pending_put_properties[mg_dev_name].update( + {'zerodexpchannel_list': new_zerodexpchannel_list}) new_onedexpchannel_list = [] skip = True for name in props['onedexpchannel_list']: name = name.lower() - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_onedexpchannel_list.append(reverse_elem_map.get(name, name)) + new_onedexpchannel_list.append( + reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'onedexpchannel_list': new_onedexpchannel_list}) + pending_put_properties[mg_dev_name].update( + {'onedexpchannel_list': new_onedexpchannel_list}) new_twodexpchannel_list = [] skip = True for name in props['twodexpchannel_list']: name = name.lower() - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_twodexpchannel_list.append(reverse_elem_map.get(name, name)) + new_twodexpchannel_list.append( + reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'twodexpchannel_list': new_twodexpchannel_list}) + pending_put_properties[mg_dev_name].update( + {'twodexpchannel_list': new_twodexpchannel_list}) new_pseudocounter_list = [] skip = True for name in props['pseudocounter_list']: name = name.lower() - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False - new_pseudocounter_list.append(reverse_elem_map.get(name, name)) + new_pseudocounter_list.append( + reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'pseudocounter_list': new_pseudocounter_list}) + pending_put_properties[mg_dev_name].update( + {'pseudocounter_list': new_pseudocounter_list}) new_motor_list = [] skip = True for name in props['motor_list']: name = name.lower() - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False new_motor_list.append(reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'motor_list': new_motor_list}) + pending_put_properties[mg_dev_name].update( + {'motor_list': new_motor_list}) new_phys_group_elt = [] skip = True for name in props['phys_group_elt']: name = name.lower() - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False new_phys_group_elt.append(reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'phys_group_elt': new_phys_group_elt}) + pending_put_properties[mg_dev_name].update( + {'phys_group_elt': new_phys_group_elt}) new_user_group_elt = [] skip = True for name in props['user_group_elt']: name = name.lower() - try: int(name) - except Exception, e: + try: + int(name) + except Exception, e: skip = False new_user_group_elt.append(reverse_elem_map.get(name, name)) if not skip: - pending_put_properties[mg_dev_name].update({'user_group_elt': new_user_group_elt}) + pending_put_properties[mg_dev_name].update( + {'user_group_elt': new_user_group_elt}) - # 3.10 - For PseudoMotor replace motor_list from a list of names to a list of IDs + # 3.10 - For PseudoMotor replace motor_list from a list of names to a + # list of IDs yield "Storing PseudoMotor information...", 50 for pm_dev_name in elems_dict.get("PseudoMotor", []): pm_dev_name = pm_dev_name.lower() - props = db.get_device_property(pm_dev_name, ("id", "ctrl_id", "axis", - "motor_group", "motor_group_id", "motor_list")) + props = db.get_device_property(pm_dev_name, ("id", "ctrl_id", "axis", + "motor_group", "motor_group_id", "motor_list")) id = int(props["id"][0]) pm_alias = db.get_alias(pm_dev_name).lower() elem_map[id] = pm_alias reverse_elem_map[pm_alias] = id - + motor_group = props["motor_group"] if not motor_group: motor_group_id = motor_group = props["motor_group_id"] @@ -345,44 +390,50 @@ def upgrade(self, db, serv, old_vers, new_vers): motor_group_id = reverse_elem_map[motor_group] props["motor_group_id"] = [str(motor_group_id)] db.put_device_property(pm_dev_name, props) - - db.delete_device_property(pm_dev_name, ["pseudo_motor_id", "motor_group", "role", "role_idx"]) + + db.delete_device_property( + pm_dev_name, ["pseudo_motor_id", "motor_group", "role", "role_idx"]) skip = True motor_ids = [] for name in props["motor_list"]: name = name.lower() - try: int(name) - except Exception,e: + try: + int(name) + except Exception, e: skip = False motor_ids.append(reverse_elem_map[name]) if not skip: - db.put_device_property(pm_dev_name, { "motor_list" : motor_ids }) + db.put_device_property(pm_dev_name, {"motor_list": motor_ids}) - # 3.11 - For PseudoCounter replace channel_list from a list of names to a list of IDs + # 3.11 - For PseudoCounter replace channel_list from a list of names to + # a list of IDs yield "Storing PseudoCounter information...", 60 for pc_dev_name in elems_dict.get("PseudoCounter", []): pc_dev_name = pc_dev_name.lower() - props = db.get_device_property(pc_dev_name, ("id", "ctrl_id", "axis", - "channel_list")) + props = db.get_device_property(pc_dev_name, ("id", "ctrl_id", "axis", + "channel_list")) id = int(props["id"][0]) pc_alias = db.get_alias(pc_dev_name).lower() elem_map[id] = pc_alias reverse_elem_map[pc_alias] = id - - db.delete_device_property(pc_dev_name, ["pseudo_counter_id", "role", "role_idx"]) + + db.delete_device_property( + pc_dev_name, ["pseudo_counter_id", "role", "role_idx"]) skip = True channel_ids = [] for name in props["channel_list"]: name = name.lower() - try: int(name) - except Exception,e: + try: + int(name) + except Exception, e: skip = False channel_ids.append(reverse_elem_map[name]) if not skip: - db.put_device_property(pc_dev_name, { "channel_list" : channel_ids }) - + db.put_device_property( + pc_dev_name, {"channel_list": channel_ids}) + # 4. - Apply pending properties yield "Applying pending properties...", 75 for dev, props in pending_put_properties.iteritems(): @@ -394,7 +445,7 @@ def upgrade(self, db, serv, old_vers, new_vers): # 5. - Finally update the version property in the database yield "Updating the version property in the database...", 85 - db.put_device_property(pool_dev_name, { "Version" : [new_vers] }) + db.put_device_property(pool_dev_name, {"Version": [new_vers]}) # 6. - Check if the service is already registered yield "Checking if the service is already registered...", 95 @@ -404,6 +455,7 @@ def upgrade(self, db, serv, old_vers, new_vers): yield "Finished", 100 + class Up01To03(Upgrade): @classmethod @@ -413,7 +465,7 @@ def fromTo(cls): @classmethod def supports(cls, old_vers, new_vers): return old_vers.startswith('0.1') and new_vers.startswith('0.3') - + @classmethod def supports_old(cls, old_vers): return old_vers.startswith('0.1') @@ -426,12 +478,12 @@ def upgrade(self, db, serv, old_vers, new_vers): if not Up01To03.supports(old_vers, new_vers): raise Exception("Unsupported upgrade") - + from from_01_to_02 import Up01To02 up = Up01To02() for msg, perc in up.upgrade(db, serv, old_vers, '0.2.0'): yield msg, perc / 2 up = Up02To03() - + for msg, perc in up.upgrade(db, serv, '0.2.0', new_vers): - yield msg, (perc/2) + 50 + yield msg, (perc / 2) + 50 diff --git a/scripts/upgrade/upgradeCLI.py b/scripts/upgrade/upgradeCLI.py index 207a9138e6..5e64baf713 100644 --- a/scripts/upgrade/upgradeCLI.py +++ b/scripts/upgrade/upgradeCLI.py @@ -1,10 +1,12 @@ #!/usr/bin/env python -import sys, time +import sys +import time import PyTango from upgrade_utils import * + def upgrade(serv, old_vers, new_vers): u_kcls = get_suitable_upgrade(old_vers, new_vers) u_obj = u_kcls() @@ -15,36 +17,40 @@ def upgrade(serv, old_vers, new_vers): msg = "%s [ %03d%s ]" % (msg, perc, '%') print msg time.sleep(0.1) - + + def main(): - + serv = "" vers = "0.0.0" - if len(sys.argv) > 1: serv = sys.argv[1] - if len(sys.argv) > 2: vers = sys.argv[2] + if len(sys.argv) > 1: + serv = sys.argv[1] + if len(sys.argv) > 2: + vers = sys.argv[2] pool_serv_list = get_server_list() - + while not serv in pool_serv_list: print_list(pool_serv_list) serv = raw_input("Which instance you want to upgrade? ") - + old_vers = get_pool_server_version(serv) print "Current version of %s is %s" % (serv, old_vers) - + possible_upgrades = get_possible_upgrades(serv) - + if not possible_upgrades: print "Could not find a suitable upgrade plugin for version %s.\nUpgrade FAILED" % old_vers return while not get_suitable_upgrade(old_vers, vers): print_list(possible_upgrades) - vers = raw_input("To which version you want to upgrade %s (bigger than %s)? " % (serv, old_vers)) - + vers = raw_input( + "To which version you want to upgrade %s (bigger than %s)? " % (serv, old_vers)) + upgrade(serv, old_vers, vers) - + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/scripts/upgrade/upgradeGUI.py b/scripts/upgrade/upgradeGUI.py index 5407ec0454..ceb431a438 100644 --- a/scripts/upgrade/upgradeGUI.py +++ b/scripts/upgrade/upgradeGUI.py @@ -1,67 +1,72 @@ #!/usr/bin/env python -import sys, os +import sys +import os import PyTango from PyQt4 import QtGui, QtCore, Qt import upgrade_utils + def get_default_tango_host(): tg = os.environ.get('TANGO_HOST') - if tg is None: return '', '' + if tg is None: + return '', '' return tg.split(':') + class BaseUpgradePage(QtGui.QWizardPage): - + host_key = 'tango_host' port_key = 'tango_port' p_instance_key = 'pool_instance' p_version_key = 'pool_version' - - def __init__(self, parent = None): + + def __init__(self, parent=None): QtGui.QWizardPage.__init__(self, parent) self.setPixmap(QtGui.QWizard.LogoPixmap, QtGui.QPixmap(":/logo.jpg")) - + def db(self): return self.wizard().db() - + def pool(self): return self.wizard().pool() - + def version(self): return self.wizard().version() - - + + class IntroPage(QtGui.QWizardPage): - - def __init__(self, parent = None): + + def __init__(self, parent=None): QtGui.QWizardPage.__init__(self, parent) - + self.setTitle('Introduction') - self.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap(":/watermark.jpg")) - - label = QtGui.QLabel('This wizard will upgrade your device pool to ' \ - 'the desired version. You simply need to specify ' \ - 'the tango host, the pool instance and the new ' \ + self.setPixmap(QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(":/watermark.jpg")) + + label = QtGui.QLabel('This wizard will upgrade your device pool to ' + 'the desired version. You simply need to specify ' + 'the tango host, the pool instance and the new ' 'version you which to upgrade to') label.setWordWrap(True) layout = QtGui.QVBoxLayout() layout.addWidget(label) self.setLayout(layout) - - + + class SelectTangoHostPage(BaseUpgradePage): - - def __init__(self, parent = None): + + def __init__(self, parent=None): BaseUpgradePage.__init__(self, parent) self.setTitle('Tango Host') self.setSubTitle('Please select the Tango Host') - + #panel = QtGui.QWidget(self) panel = self layout = QtGui.QGridLayout(panel) - + hostEdit = QtGui.QLineEdit(panel) portEdit = QtGui.QLineEdit(panel) @@ -73,25 +78,27 @@ def __init__(self, parent = None): hostEdit.setText(host) portEdit.setText(port) - self.connect(hostEdit, - QtCore.SIGNAL('textEdited(const QString &)'), + self.connect(hostEdit, + QtCore.SIGNAL('textEdited(const QString &)'), QtCore.SIGNAL('completeChanged()')) - self.connect(portEdit, - QtCore.SIGNAL('textEdited(const QString &)'), + self.connect(portEdit, + QtCore.SIGNAL('textEdited(const QString &)'), QtCore.SIGNAL('completeChanged()')) - + hostLabel = QtGui.QLabel('&Host:', panel) portLabel = QtGui.QLabel('&Port:', panel) - spacer = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacer = QtGui.QSpacerItem( + 20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.statusLabel = QtGui.QLabel(panel) - + self.statusLabel.setAutoFillBackground(True) palette = self.statusLabel.palette() - palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush(Qt.QColor.fromRgb(200,200,200))) - + palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush( + Qt.QColor.fromRgb(200, 200, 200))) + hostLabel.setBuddy(hostEdit) portLabel.setBuddy(portEdit) - + layout.addWidget(hostLabel, 0, 0, Qt.Qt.AlignRight) layout.addWidget(portLabel, 1, 0, Qt.Qt.AlignRight) layout.addWidget(hostEdit, 0, 1, Qt.Qt.AlignLeft) @@ -102,7 +109,7 @@ def __init__(self, parent = None): layout.setColumnStretch(0, 0) layout.setColumnStretch(1, 1) - + def initializePage(self): BaseUpgradePage.initializePage(self) @@ -116,29 +123,32 @@ def isComplete(self): self.statusLabel.setText(txt) return False + class SelectInstancePage(BaseUpgradePage): - - def __init__(self, parent = None): + + def __init__(self, parent=None): BaseUpgradePage.__init__(self, parent) self.setTitle('Pool Instance') self.setSubTitle('Please select the Pool Server instance') - + #panel = QtGui.QWidget(self) panel = self - + self.instanceCB = QtGui.QComboBox(panel) self.instanceCB.setDuplicatesEnabled(False) self.instanceCB.setEditable(False) self.registerField(self.p_instance_key, self.instanceCB) - + layout = QtGui.QGridLayout(panel) instanceLabel = QtGui.QLabel('instance:', panel) - spacer = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacer = QtGui.QSpacerItem( + 20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.statusLabel = QtGui.QLabel(panel) self.statusLabel.setAutoFillBackground(True) palette = self.statusLabel.palette() - palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush(Qt.QColor.fromRgb(200,200,200))) + palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush( + Qt.QColor.fromRgb(200, 200, 200))) layout.setColumnStretch(0, 0) layout.setColumnStretch(1, 1) @@ -147,9 +157,9 @@ def __init__(self, parent = None): layout.addItem(spacer, 1, 0, 1, 2) layout.addWidget(self.statusLabel, 2, 0, 1, 2) - - self.connect(self.instanceCB, - QtCore.SIGNAL('currentIndexChanged(int)'), + + self.connect(self.instanceCB, + QtCore.SIGNAL('currentIndexChanged(int)'), QtCore.SIGNAL('completeChanged()')) def isComplete(self): @@ -159,7 +169,8 @@ def isComplete(self): serv = str(self.instanceCB.currentText()) curr_vers = upgrade_utils.get_pool_server_version(serv, db=db) txt = 'Current version is %s' % curr_vers - possible_upgrades = upgrade_utils.get_possible_upgrades(serv, db=db) + possible_upgrades = upgrade_utils.get_possible_upgrades( + serv, db=db) if not possible_upgrades: txt += ". There are no possible upgrades for this version" self.statusLabel.setText(txt) @@ -167,35 +178,38 @@ def isComplete(self): else: self.statusLabel.setText('No instance selected') return False - + def initializePage(self): BaseUpgradePage.initializePage(self) db = self.db() self.instanceCB.clear() self.instanceCB.addItems(upgrade_utils.get_server_list(db=db)) + class SelectVersionPage(BaseUpgradePage): - - def __init__(self, parent = None): + + def __init__(self, parent=None): BaseUpgradePage.__init__(self, parent) self.setTitle('Version') self.setSubTitle('Please select the version to upgrade to') - + panel = self - + self.versionCB = QtGui.QComboBox(panel) self.versionCB.setDuplicatesEnabled(False) self.versionCB.setEditable(False) self.registerField(self.p_version_key, self.versionCB) - + layout = QtGui.QGridLayout(panel) versionLabel = QtGui.QLabel('version:', panel) - spacer = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacer = QtGui.QSpacerItem( + 20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.statusLabel = QtGui.QLabel(panel) self.statusLabel.setAutoFillBackground(True) palette = self.statusLabel.palette() - palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush(Qt.QColor.fromRgb(200,200,200))) + palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush( + Qt.QColor.fromRgb(200, 200, 200))) layout.setColumnStretch(0, 0) layout.setColumnStretch(1, 1) @@ -208,22 +222,26 @@ def __init__(self, parent = None): def initializePage(self): serv = self.pool() db = self.db() - self.setSubTitle('Please select to which version you want to upgrade %s to' % serv) + self.setSubTitle( + 'Please select to which version you want to upgrade %s to' % serv) self.versionCB.clear() curr_vers = upgrade_utils.get_pool_server_version(serv, db=db) possible_new_vers = upgrade_utils.get_possible_upgrades(serv, db=db) - + if not possible_new_vers: - self.statusLabel.setText('There are no suitable upgrades for version %s' % curr_vers) + self.statusLabel.setText( + 'There are no suitable upgrades for version %s' % curr_vers) else: self.versionCB.addItems(possible_new_vers) + class ConclusionPage(BaseUpgradePage): - def __init__(self, parent = None): + def __init__(self, parent=None): BaseUpgradePage.__init__(self, parent) self.setTitle('Upgrade') - self.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap(":/watermark.jpg")) + self.setPixmap(QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(":/watermark.jpg")) layout = QtGui.QVBoxLayout(self) self.label = QtGui.QLabel(self) self.label.setWordWrap(True) @@ -233,18 +251,19 @@ def initializePage(self): finishText = self.wizard().buttonText(QtGui.QWizard.FinishButton) finishText.remove('&') txt = "You are now ready to upgrade '%s' to version '%s'. Click on " \ - "'%s' to proceed with the upgrade" % (self.pool(), self.version(), finishText) + "'%s' to proceed with the upgrade" % ( + self.pool(), self.version(), finishText) self.label.setText(txt) - + + class SardanaUpgradeWizard(QtGui.QWizard): - + host_key = 'tango_host' port_key = 'tango_port' p_instance_key = 'pool_instance' p_version_key = 'pool_version' - - - def __init__(self, parent = None): + + def __init__(self, parent=None): QtGui.QWizard.__init__(self, parent) self._db = None self.setWindowTitle("Sardana Upgrade Tool") @@ -254,10 +273,11 @@ def __init__(self, parent = None): self.pool_page_idx = self.addPage(SelectInstancePage()) self.version_page_idx = self.addPage(SelectVersionPage()) self.addPage(ConclusionPage()) - + def pool(self): pool_instance_idx = int(self.pool_index()) - p = self.page(self.pool_page_idx).instanceCB.itemText(pool_instance_idx) + p = self.page(self.pool_page_idx).instanceCB.itemText( + pool_instance_idx) return str(p) def pool_index(self): @@ -265,12 +285,13 @@ def pool_index(self): def version(self): pool_version_idx = int(self.pool_version_index()) - v = self.page(self.version_page_idx).versionCB.itemText(pool_version_idx) + v = self.page(self.version_page_idx).versionCB.itemText( + pool_version_idx) return str(v) - + def pool_version_index(self): return str(self.field(self.p_version_key).toString()) - + def db(self): host = str(self.field(self.host_key).toString()).lower() port = str(self.field(self.port_key).toString()).lower() @@ -282,7 +303,7 @@ def db(self): self._db = None raise df return self._db - + def accept(self): pool = self.pool() new_version = self.version() @@ -292,15 +313,15 @@ def accept(self): self.restart() else: QtGui.QWizard.accept(self) - def upgrade(self, serv, new_vers): db = self.db() old_vers = upgrade_utils.get_pool_server_version(serv, db=db) u_kcls = upgrade_utils.get_suitable_upgrade(old_vers, new_vers) u_obj = u_kcls() - - dialog = QtGui.QProgressDialog("Upgrading %s to %s..." % (serv, new_vers), "Abort", 0, 100, self) + + dialog = QtGui.QProgressDialog("Upgrading %s to %s..." % ( + serv, new_vers), "Abort", 0, 100, self) dialog.setAutoClose(True) dialog.setMinimumDuration(0) @@ -309,7 +330,7 @@ def upgrade(self, serv, new_vers): dialog.setLabelText(msg) dialog.setValue(percentage) time.sleep(0.1) - + dialog = QtGui.QMessageBox() dialog.setWindowTitle("Success!!!") dialog.setText("Do you wish to upgrade another Sardana?") @@ -320,6 +341,7 @@ def upgrade(self, serv, new_vers): dialog.setDefaultButton(QtGui.QMessageBox.Yes) return dialog.exec_() == QtGui.QMessageBox.Yes + def main(): app = QtGui.QApplication([]) res_fname = os.path.abspath(__file__) @@ -328,6 +350,6 @@ def main(): wizard = SardanaUpgradeWizard() wizard.show() sys.exit(app.exec_()) - + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/scripts/upgrade/upgrade_sardana.py b/scripts/upgrade/upgrade_sardana.py index 254b0bb349..08aff535de 100644 --- a/scripts/upgrade/upgrade_sardana.py +++ b/scripts/upgrade/upgrade_sardana.py @@ -1,6 +1,7 @@ #!/usr/bin/env python -import sys, time +import sys +import time import PyTango from upgrade_utils import * @@ -13,4 +14,3 @@ except Exception, e: import upgradeCLI upgradeCLI.main() - diff --git a/scripts/upgrade/upgrade_utils.py b/scripts/upgrade/upgrade_utils.py index 6a3186671a..2248a52f8a 100644 --- a/scripts/upgrade/upgrade_utils.py +++ b/scripts/upgrade/upgrade_utils.py @@ -1,64 +1,82 @@ -import sys, os, imp +import sys +import os +import imp import PyTango + class Upgrade: - + def upgrade(self, db, serv, old, new): - raise RuntimeError("Invalid Upgrade class. Must define a upgrade method") - + raise RuntimeError( + "Invalid Upgrade class. Must define a upgrade method") + @classmethod def fromTo(cls): - raise RuntimeError("Invalid Upgrade class. Must define a fromTo method") + raise RuntimeError( + "Invalid Upgrade class. Must define a fromTo method") @classmethod def supports(cls, old, new): - raise RuntimeError("Invalid Upgrade class. Must define a supports method") - + raise RuntimeError( + "Invalid Upgrade class. Must define a supports method") + @classmethod def supports_old(cls, old): - raise RuntimeError("Invalid Upgrade class. Must define a supports_old method") + raise RuntimeError( + "Invalid Upgrade class. Must define a supports_old method") @classmethod def supports_new(cls, new): - raise RuntimeError("Invalid Upgrade class. Must define a supports_new method") + raise RuntimeError( + "Invalid Upgrade class. Must define a supports_new method") + def print_list(l): - for i in l: print i + for i in l: + print i + -def get_db(host = None, port = None): +def get_db(host=None, port=None): if host is None or port is None: return PyTango.Database() return PyTango.Database(host, port) -def get_server_list(type = "Pool", host = None, port = None, db = None): + +def get_server_list(type="Pool", host=None, port=None, db=None): type += '/' db = db or get_db(host, port) - return [ s[s.index('/')+1:] for s in db.get_server_list() if s.startswith(type) ] + return [s[s.index('/') + 1:] for s in db.get_server_list() if s.startswith(type)] + def print_server_list(): for s in get_server_list(): print s -def get_pool_device_from_server(serv, host = None, port = None, db = None): + +def get_pool_device_from_server(serv, host=None, port=None, db=None): db = db or get_db(host, port) return db.get_device_name("Pool/%s" % serv, "Pool")[0] -def get_pool_server_version(serv, host = None, port = None, db = None): + +def get_pool_server_version(serv, host=None, port=None, db=None): db = db or get_db(host, port) pool_dev_name = get_pool_device_from_server(serv, db=db) - if not len(db.get_device_property_list(pool_dev_name,"Version")): + if not len(db.get_device_property_list(pool_dev_name, "Version")): # if not in database it means it is version 0.1.0 return "0.1.0" else: return db.get_device_property(pool_dev_name, ["Version"])["Version"][0] + def to_version_nb(v_str): - m,n,r = v_str.split('.') - return int(m)*10000 + int(n)*100 + int(r) + m, n, r = v_str.split('.') + return int(m) * 10000 + int(n) * 100 + int(r) + def strip_old_versions(v_list, thresold): thresold = to_version_nb(thresold) - return [ v for v in v_list if to_version_nb(v) > thresold ] + return [v for v in v_list if to_version_nb(v) > thresold] + def get_suitable_upgrade(old_vers, new_vers): upgrades = get_supported_upgrades() @@ -67,25 +85,31 @@ def get_suitable_upgrade(old_vers, new_vers): return u_kcls return None + def get_supported_upgrades(): upgrade_classes = [] curr_dir = os.path.abspath(os.path.dirname(__file__)) for mod_name in os.listdir(curr_dir): - if not mod_name.endswith(".py"): continue + if not mod_name.endswith(".py"): + continue mod_name = mod_name[:mod_name.rindex(".py")] - if mod_name == __name__: continue - if mod_name.startswith("upgrade_"): continue + if mod_name == __name__: + continue + if mod_name.startswith("upgrade_"): + continue m = imp.load_module(mod_name, *imp.find_module(mod_name)) for s in m.__dict__.values(): if type(s) == type(Upgrade): - if s == Upgrade: continue + if s == Upgrade: + continue if issubclass(s, Upgrade): upgrade_classes.append(s) - + return upgrade_classes -def get_possible_upgrades(serv, host = None, port = None, db = None): - curr_vers = get_pool_server_version(serv, host = host, port = port, db = db) + +def get_possible_upgrades(serv, host=None, port=None, db=None): + curr_vers = get_pool_server_version(serv, host=host, port=port, db=db) upgrades = get_supported_upgrades() possible_upgrades = [] for u_kcls in upgrades: diff --git a/setup.py b/setup.py index dccf7373ea..1ea4d89f75 100644 --- a/setup.py +++ b/setup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -75,26 +75,26 @@ def get_release_info(): "ubmatrix = sardana.taurus.qt.qtgui.extra_hkl.ubmatrix:main" ] -entry_points={'console_scripts': console_scripts, - 'gui_scripts': gui_scripts, -} +entry_points = {'console_scripts': console_scripts, + 'gui_scripts': gui_scripts, + } classifiers = [ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Environment :: No Input/Output (Daemon)', - 'Environment :: Win32 (MS Windows)', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Operating System :: POSIX :: Linux', - 'Operating System :: Unix', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Topic :: Scientific/Engineering', - 'Topic :: Software Development :: Libraries', + 'Development Status :: 4 - Beta', + 'Environment :: Console', + 'Environment :: No Input/Output (Daemon)', + 'Environment :: Win32 (MS Windows)', + 'Intended Audience :: Developers', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Operating System :: POSIX :: Linux', + 'Operating System :: Unix', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Topic :: Scientific/Engineering', + 'Topic :: Software Development :: Libraries', ] setup(name='sardana', @@ -117,4 +117,4 @@ def get_release_info(): provides=provides, requires=requires, test_suite='sardana.test.testsuite.get_sardana_unitsuite', -) + ) diff --git a/src/sardana/__init__.py b/src/sardana/__init__.py index 0a81cd24c6..7c72456212 100644 --- a/src/sardana/__init__.py +++ b/src/sardana/__init__.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,6 +31,7 @@ __requirements.check_requirements() + class Release: pass @@ -38,4 +39,4 @@ class Release: Release.__doc__ = __release.__doc__ from .sardanadefs import * -from .sardanavalue import SardanaValue \ No newline at end of file +from .sardanavalue import SardanaValue diff --git a/src/sardana/macroserver/__init__.py b/src/sardana/macroserver/__init__.py index dfea2d0bf6..a8008a07ab 100644 --- a/src/sardana/macroserver/__init__.py +++ b/src/sardana/macroserver/__init__.py @@ -2,29 +2,27 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """This is the main macro server module""" __docformat__ = 'restructuredtext' - - diff --git a/src/sardana/macroserver/basetypes.py b/src/sardana/macroserver/basetypes.py index e9dc752489..0a7058aa17 100644 --- a/src/sardana/macroserver/basetypes.py +++ b/src/sardana/macroserver/basetypes.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,8 +29,8 @@ __all__ = ["Integer", "Float", "Boolean", "String", "User", "Filename", "File", "Macro", "MacroLibrary", "Env", "Motor", "MotorParam", "MotorGroup", "ExpChannel", "MeasurementGroup", "ComChannel", - "IORegister", "Controller", "Instrument", "ControllerClass", - "TriggerGate" ] + "IORegister", "Controller", "Instrument", "ControllerClass", + "TriggerGate"] __docformat__ = 'restructuredtext' @@ -39,82 +39,96 @@ ElementParamInterface # Basic types + + class Any(ParamType): - type_class = lambda p : p + type_class = lambda p: p + class Integer(ParamType): type_class = int + class Float(ParamType): type_class = float + class Boolean(ParamType): type_class = bool def getObj(self, str_repr): return str_repr.lower() == "true" - + + class String(ParamType): type_class = str + class User(ParamType): type_class = str + class Filename(ParamType): type_class = str + class File(ParamType): type_class = str - + def __init__(self, macro_server, name): ParamType.__init__(self, macro_server, name) self.filename = None - #self.data is supposed to be an array.array object + # self.data is supposed to be an array.array object self.data = None - + def set(self, filename, data): self.filename = filename self.data = data + class JSON(ParamType): def getObj(self, str_repr): import json return json.loads(str_repr) - + + class Env(ParamType): type_class = str + class TangoDevice(ParamType): def getObj(self, str_repr): import PyTango return PyTango.DeviceProxy(str_repr) + class Device(ParamType): def getObj(self, str_repr): import taurus return taurus.Device(str_repr) - + # Hardware types + class MotorParam(AttrParamType): """Class designed to represent a motor parameter name. Usual values are acceleration,deceleration,velocity,backlash,steps_per_unit,etc""" - + def __init__(self, macro_server, name): AttrParamType.__init__(self, macro_server, name) - self.attr_item_list = ["Acceleration","Backlash","Base_rate","Step_per_unit", - "Deceleration","Velocity","Offset"] + self.attr_item_list = ["Acceleration", "Backlash", "Base_rate", "Step_per_unit", + "Deceleration", "Velocity", "Offset"] self.non_attr_item_list = ["Controller"] - + def getItemList(self): return self.non_attr_item_list + self.attr_item_list - + def getAttrItemList(self): return self.attr_item_list - + def getNonAttrItemList(self): return self.non_attr_item_list @@ -122,6 +136,7 @@ def getNonAttrItemList(self): def __build_base_types(): for sardana_type, info in INTERFACES.items(): _, doc = info + class _I(ElementParamInterface): __doc__ = doc __name__ = sardana_type diff --git a/src/sardana/macroserver/macro.py b/src/sardana/macroserver/macro.py index 18c5f311a8..cee9369951 100644 --- a/src/sardana/macroserver/macro.py +++ b/src/sardana/macroserver/macro.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -95,9 +95,10 @@ def flush(self): b = self._accum if b is None or len(b) == 0: return - #take the '\n' because the output is a list of strings, each to be - #interpreted as a separate line in the client - if b[-1] == '\n': b = b[:-1] + # take the '\n' because the output is a list of strings, each to be + # interpreted as a separate line in the client + if b[-1] == '\n': + b = b[:-1] self._macro.output(b) self._accum = "" @@ -140,17 +141,18 @@ def resumeForAbort(self): self._wait_for_abort_exception = True self._event.set() - def wait(self,timeout=None): + def wait(self, timeout=None): pauseit = not self._event.isSet() if pauseit and self._pause_cb is not None: self._pause_cb(self.macro_obj) self._event.wait(timeout) # if an event is set because an abort has been issued during a paused - # macro wait for the ashyncronous AbortException to arrive at this thread + # macro wait for the ashyncronous AbortException to arrive at this + # thread if self._wait_for_abort_exception: self._wait_for_abort_exception = False time.sleep(self._wait_for_abort_timeout) - self.debug('Abort exception did not occured in pause for %ss.' \ + self.debug('Abort exception did not occured in pause for %ss.' 'Performing a Forced Abort.' % self._wait_for_abort_timeout) raise AbortException("Forced") if pauseit and self._resume_cb is not None: @@ -175,7 +177,7 @@ def _getHookHintsDict(self): try: return self._hookHintsDict except: - self._hookHintsDict = {'_ALL_':[], '_NOHINTS_':[]} + self._hookHintsDict = {'_ALL_': [], '_NOHINTS_': []} return self._hookHintsDict def getAllowedHookHints(self): @@ -220,19 +222,22 @@ def set(self, hooks): hooks that don't provide hints ''' if not isinstance(hooks, list): - self.error('the hooks must be passed as a list>') + self.error( + 'the hooks must be passed as a list>') return - #store self._hooks, making sure it is of type: list> + # store self._hooks, making sure it is of type: + # list> self._hooks = [] for h in hooks: - if isinstance(h, (tuple, list)) and len(h) == 2: + if isinstance(h, (tuple, list)) and len(h) == 2: self._hooks.append(h) - else: #we assume that hooks is a list + else: # we assume that hooks is a list self._hooks.append((h, [])) - self.info('Deprecation warning: hooks should be set with a list of hints. See Hookable API docs') + self.info( + 'Deprecation warning: hooks should be set with a list of hints. See Hookable API docs') - #create _hookHintsDict + # create _hookHintsDict self._getHookHintsDict()['_ALL_'] = zip(*self._hooks)[0] nohints = self._hookHintsDict['_NOHINTS_'] for hook, hints in self._hooks: @@ -244,7 +249,7 @@ def set(self, hooks): self._hookHintsDict[hint].append(hook) except KeyError: self._hookHintsDict[hint] = [hook] - return get,set + return get, set class ExecMacroHook(object): @@ -278,8 +283,8 @@ def __getattr__(self, name): def f(*args, **kwargs): p_m = self.macro_obj p_m.syncLog() - opts = { 'parent_macro' : p_m, - 'executor' : p_m.executor } + opts = {'parent_macro': p_m, + 'executor': p_m.executor} kwargs.update(opts) eargs = [name] eargs.extend(args) @@ -289,6 +294,7 @@ def f(*args, **kwargs): return f + def mAPI(fn): """Wraps the given Macro method as being protected by the stop procedure. To be used by the :class:`Macro` as a decorator for all methods. @@ -442,7 +448,7 @@ class Macro(Logger): #: a set of mandatory environment variable names without which your macro #: cannot run env = () - + #: decide if the macro should be able to receive input from the user #: [default: False]. A macro which asks input but has this flag set to False #: will print a warning message each time it is executed @@ -463,16 +469,16 @@ def __init__(self, *args, **kwargs): self._macro_thread = None self._id = kwargs.get('id') self._desc = "Macro '%s'" % self._macro_line - self._macro_status = { 'id' : self._id, - 'range' : (0.0, 100.0), - 'state' : 'start', - 'step' : 0.0 } + self._macro_status = {'id': self._id, + 'range': (0.0, 100.0), + 'state': 'start', + 'step': 0.0} self._pause_event = PauseEvent(self) log_parent = self.parent_macro or self.door Logger.__init__(self, "Macro[%s]" % self._name, log_parent) self._reserveObjs(args) - ## @name Official Macro API + # @name Official Macro API # This list contains the set of methods that are part of the official macro # API. This means that they can be safely used inside any macro. #@{ @@ -486,7 +492,8 @@ def run(self, *args): raises RuntimeError. :raises: RuntimeError""" - raise RuntimeError("Macro %s does not implement run method" % self.getName()) + raise RuntimeError( + "Macro %s does not implement run method" % self.getName()) def prepare(self, *args, **kwargs): """**Macro API**. Prepare phase. Overwrite as necessary. @@ -751,13 +758,14 @@ def getData(self): :return: the data produced by the macro :rtype: object""" if not hasattr(self, "_data"): - raise Exception("Macro '%s' does not produce any data" % self.getName()) + raise Exception( + "Macro '%s' does not produce any data" % self.getName()) return self._data @mAPI def setData(self, data): """**Macro API**. Sets the data for this macro - + :param object data: new data to be associated with this macro""" self._data = data @@ -770,11 +778,11 @@ def print(self, *args, **kwargs): *kwargs* are the same as :func:`print`. Example:: self.print("this is a print for macro", self.getName()) - + .. note:: you will need python >= 3.0. If you have python 2.x then you must include at the top of your file the statement:: - + from __future__ import print_function """ fd = kwargs.get('file', sys.stdout) @@ -817,13 +825,13 @@ def input(self, msg, *args, **kwargs): - maximum : [default: None] When given, must be compatible with data_type (useful for GUIs) - step : [default: None] When given, must be compatible with data_type (useful for GUIs) - decimals : [default: None] When given, must be compatible with data_type (useful for GUIs) - + Examples:: device_name = self.input("Which device name (%s)?", "tab separated") - + point_nb = self.input("How many points?", data_type=Type.Integer) - + calc_mode = self.input("Which algorithm?", data_type=["Average", "Integral", "Sum"], default_value="Average", allow_multiple=False)""" if not self.interactive: @@ -1113,7 +1121,7 @@ def prepareMacroObj(self, macro_name_or_klass, *args, **kwargs): # sync our log before calling the child macro prepare in order to avoid # mixed outputs between this macro and the child macro self.syncLog() - init_opts = { 'parent_macro' : self } + init_opts = {'parent_macro': self} return self.executor.prepareMacroObj(macro_name_or_klass, args, init_opts, kwargs) @@ -1167,7 +1175,7 @@ def prepareMacro(self, *args, **kwargs): # sync our log before calling the child macro prepare in order to avoid # mixed outputs between this macro and the child macro self.syncLog() - init_opts = { 'parent_macro' : self } + init_opts = {'parent_macro': self} return self.executor.prepareMacro(args, init_opts, kwargs) @mAPI @@ -1261,14 +1269,16 @@ def execMacro(self, *args, **kwargs): macro_name = None arg0 = args[0] if len(args) == 1: - if type(arg0) in types.StringTypes : + if type(arg0) in types.StringTypes: # dealing with sth like args = ('ascan th 0 100 10 1.0',) macro_name = arg0.split()[0] elif operator.isSequenceType(arg0): - # dealing with sth like args = (['ascan', 'th', '0', '100', '10', '1.0'],) + # dealing with sth like args = (['ascan', 'th', '0', '100', + # '10', '1.0'],) macro_name = arg0[0] else: - # dealing with sth like args = ('ascan', 'th', '0', '100', '10', '1.0') + # dealing with sth like args = ('ascan', 'th', '0', '100', '10', + # '1.0') macro_name = args[0] self.debug("Executing macro: %s" % macro_name) macro_obj, _ = self.prepareMacro(*args, **kwargs) @@ -1512,7 +1522,7 @@ def getMacroLibraries(self, filter=None): ret.sort() return ret - @mAPI + @mAPI def getMacroLibrary(self, lib_name): """**Macro API**. Returns a :class:`~sardana.macroserver.msmetamacro.MacroLibrary` object for the @@ -1567,7 +1577,7 @@ def getMotion(self, elems, motion_source=None, read_only=False, cache=True): :return: a Motion object """ - decoupled=False + decoupled = False try: decoupled = self.getEnv("MotionDecoupled") except UnknownEnv: @@ -1775,7 +1785,7 @@ def unsetEnv(self, key): #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Reload API #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- - + @mAPI def reloadLibrary(self, lib_name): """**Macro API**. Reloads the given library(=module) names @@ -1788,7 +1798,7 @@ def reloadLibrary(self, lib_name): :return: the reloaded python module object""" - return self.door.reload_lib(lib_name) + return self.door.reload_lib(lib_name) @mAPI def reloadMacro(self, macro_name): @@ -1845,10 +1855,10 @@ def reloadMacroLibraries(self, lib_names): objects for the reloaded libraries :rtype: seq<:class:`~sardana.macroserver.metamacro.MacroLibrary`\>""" return self.door.reload_macro_libs(lib_names) - + reloadMacroLib = reloadMacroLibrary reloadMacroLibs = reloadMacroLibraries - + @mAPI def getViewOption(self, name): return self._getViewOption(name) @@ -1857,7 +1867,7 @@ def getViewOption(self, name): def getViewOptions(self): vo = self._getViewOptions() # ensure that all view options known by sardana are present, in case - # there were missing ones, update _ViewOptions dictionary after + # there were missing ones, update _ViewOptions dictionary after # initializing missing options with the default values ivo = copy.deepcopy(vo) ViewOption.init_options(ivo) @@ -1880,7 +1890,7 @@ def resetViewOption(self, name): #@} - ## @name Unofficial Macro API + # @name Unofficial Macro API # This list contains the set of methods that are NOT part of the # the macro developer knows what he is doing. # Please check before is there is an official API that does the samething @@ -1936,13 +1946,13 @@ def _input(self, msg, *args, **kwargs): - maximum : [default: None] When given, must be compatible with data_type (useful for GUIs) - step : [default: None] When given, must be compatible with data_type (useful for GUIs) - decimals : [default: None] When given, must be compatible with data_type (useful for GUIs) - + Examples:: device_name = self.input("Which device name (%s)?", "tab separated") - + point_nb = self.input("How many points?", data_type=Type.Integer) - + calc_mode = self.input("Which algorithm?", data_type=["Average", "Integral", "Sum"], default_value="Average", allow_multiple=False)""" if not self.interactive: @@ -2188,7 +2198,7 @@ def setResult(self, result): :param result: (object) the result for this macro""" self._out_pars = result - ## @name Internal methods + # @name Internal methods # This list contains the set of methods that are for INTERNAL macro usage. # Macro developers should never call any of these methods #@{ @@ -2237,8 +2247,9 @@ def _reserveObjs(self, args): macro""" for obj in args: # isiterable - if not type(obj) in map(type,([],())): - #if not operator.isSequenceType(obj) or type(obj) in types.StringTypes: + if not type(obj) in map(type, ([], ())): + # if not operator.isSequenceType(obj) or type(obj) in + # types.StringTypes: obj = (obj,) for sub_obj in obj: if isinstance(sub_obj, PoolElement): @@ -2254,8 +2265,8 @@ def exec_(self): # allow any macro to be paused at the beginning of its execution self.pausePoint() - - # Run the macro or obtain a generator + + # Run the macro or obtain a generator res = self.run(*self._in_pars) # If macro returns a generator then running the macro means go through @@ -2282,7 +2293,7 @@ def exec_(self): macro_status['state'] = 'finish' yield macro_status - def __prepareResult(self,out): + def __prepareResult(self, out): """**Internal method**. Decodes the given output in order to be able to send to the result channel @@ -2293,7 +2304,7 @@ def __prepareResult(self,out): if out is None: out = () if operator.isSequenceType(out) and not type(out) in types.StringTypes: - out = map(str,out) + out = map(str, out) else: out = (str(out),) return out @@ -2304,7 +2315,8 @@ def _stopOnError(self): try: self.on_stop() except Exception: - Logger.error(self, "Error in on_stop(): %s", traceback.format_exc()) + Logger.error(self, "Error in on_stop(): %s", + traceback.format_exc()) Logger.debug(self, "Details: ", exc_info=1) def _abortOnError(self): @@ -2313,7 +2325,8 @@ def _abortOnError(self): try: self.on_abort() except Exception: - Logger.error(self, "Error in on_abort(): %s", traceback.format_exc()) + Logger.error(self, "Error in on_abort(): %s", + traceback.format_exc()) Logger.debug(self, "Details: ", exc_info=1) def _pausePoint(self, timeout=None): @@ -2348,9 +2361,11 @@ def abort(self): time.sleep(0.1) if ret > 1: # if it returns a number greater than one, you're in trouble, - # and you should call it again with exc=NULL to revert the effect + # and you should call it again with exc=NULL to revert the + # effect asyncexc(th_id, None) - Logger.error(self, "Failed to abort (unknown error code %d)" % ret) + Logger.error( + self, "Failed to abort (unknown error code %d)" % ret) break def setProcessingStop(self, yesno): @@ -2387,6 +2402,7 @@ def __getattr__(self, name): except UnknownMacro: raise AttributeError("%r object has no attribute %r" % (type(self).__name__, name)) + def f(*args, **kwargs): self.syncLog() opts = dict(parent_macro=self, executor=self.executor) @@ -2421,7 +2437,6 @@ def __init__(self, *args, **kwargs): if function.interactive is not None: self.interactive = function.interactive Macro.__init__(self, *args, **kwargs) - + def run(self, *args): return self._function(self, *args) - diff --git a/src/sardana/macroserver/macros/__init__.py b/src/sardana/macroserver/macros/__init__.py index e5599a8d7b..024b442554 100644 --- a/src/sardana/macroserver/macros/__init__.py +++ b/src/sardana/macroserver/macros/__init__.py @@ -2,29 +2,27 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """This package contains the standard macroserver macros""" __docformat__ = 'restructuredtext' - - diff --git a/src/sardana/macroserver/macros/communication.py b/src/sardana/macroserver/macros/communication.py index cac68e74af..39d6e66f64 100644 --- a/src/sardana/macroserver/macros/communication.py +++ b/src/sardana/macroserver/macros/communication.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,13 +31,15 @@ import array + class put(Macro): """Sends a string to the communication channel""" param_def = [ - ['communication channel', Type.ComChannel, None, 'the communication channel'], - ['data', Type.String, None, 'data to be sent'] + ['communication channel', Type.ComChannel, + None, 'the communication channel'], + ['data', Type.String, None, 'data to be sent'] ] - + def run(self, comch, data): name = comch.getName() nb = comch.write(data) @@ -47,16 +49,17 @@ def run(self, comch, data): class get(Macro): """Reads and outputs the data from the communication channel""" - + param_def = [ - ['communication channel', Type.ComChannel, None, 'the communication channel'], - ['maximum length', Type.String, -1, 'maximum number of bytes to read'] + ['communication channel', Type.ComChannel, + None, 'the communication channel'], + ['maximum length', Type.String, -1, 'maximum number of bytes to read'] ] - + def run(self, comch, maxlen): name = comch.getName() - data = comch.command_inout("read",maxlen) - - datastr = array.array('B',data).tostring() + data = comch.command_inout("read", maxlen) + + datastr = array.array('B', data).tostring() self.output("'" + datastr + "'") - self.output(data) \ No newline at end of file + self.output(data) diff --git a/src/sardana/macroserver/macros/demo.py b/src/sardana/macroserver/macros/demo.py index a6d7e624f6..c273c3d553 100644 --- a/src/sardana/macroserver/macros/demo.py +++ b/src/sardana/macroserver/macros/demo.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -36,6 +36,7 @@ _ENV_HKL = "_SAR_DEMO_HKL" + def get_free_names(db, prefix, nb, start_at=1): ret = [] i = start_at @@ -53,6 +54,7 @@ def get_free_names(db, prefix, nb, start_at=1): "Please try using a different tango system") return ret + @macro() def clear_sar_demo(self): """Undoes changes done with sar_demo""" @@ -73,33 +75,34 @@ def clear_sar_demo(self): if mg == _ActiveMntGrp: self.print("Unsetting ActiveMntGrp (was: %s)" % _ActiveMntGrp) self.unsetEnv("ActiveMntGrp") - + self.print("Removing elements...") - elements = SAR_DEMO.get("elements", ()) + elements = SAR_DEMO.get("elements", ()) if len(elements) > 0: self.udefelem(elements) - + self.print("Removing controllers...") for ctrl in SAR_DEMO.get("controllers", ()): self.udefctrl(ctrl) - + self.unsetEnv(_ENV) - + self.print("DONE!") - + + @macro() def sar_demo(self): """Sets up a demo environment. It creates many elements for testing""" - + try: SAR_DEMO = self.getEnv(_ENV) self.error("A demo has already been prepared on this sardana") return except: pass - + db = PyTango.Database() - + mot_ctrl_name = get_free_names(db, "motctrl", 1)[0] ct_ctrl_name = get_free_names(db, "ctctrl", 1)[0] zerod_ctrl_name = get_free_names(db, "zerodctrl", 1)[0] @@ -115,10 +118,11 @@ def sar_demo(self): oned_names = get_free_names(db, "oned", 1) twod_names = get_free_names(db, "twod", 1) tg_names = get_free_names(db, "tg", 1) - gap, offset = get_free_names(db, "gap", 1) + get_free_names(db, "offset", 1) + gap, offset = get_free_names(db, "gap", 1) + \ + get_free_names(db, "offset", 1) ior_names = get_free_names(db, "ior", 2) mg_name = get_free_names(db, "mntgrp", 1)[0] - + pools = self.getPools() if not len(pools): self.error('This is not a valid sardana demonstration system.\n' @@ -126,54 +130,54 @@ def sar_demo(self): 'one Pool') return pool = pools[0] - + self.print("Creating motor controller", mot_ctrl_name, "...") self.defctrl("DummyMotorController", mot_ctrl_name) for axis, motor_name in enumerate(motor_names, 1): self.print("Creating motor", motor_name, "...") - self.defelem(motor_name , mot_ctrl_name, axis) - + self.defelem(motor_name, mot_ctrl_name, axis) + self.print("Creating counter controller", ct_ctrl_name, "...") self.defctrl("DummyCounterTimerController", ct_ctrl_name) for axis, ct_name in enumerate(ct_names, 1): self.print("Creating counter channel", ct_name, "...") - self.defelem(ct_name , ct_ctrl_name, axis) - + self.defelem(ct_name, ct_ctrl_name, axis) + self.print("Creating 0D controller", zerod_ctrl_name, "...") self.defctrl("DummyZeroDController", zerod_ctrl_name) for axis, zerod_name in enumerate(zerod_names, 1): self.print("Creating 0D channel", zerod_name, "...") - self.defelem(zerod_name , zerod_ctrl_name, axis) + self.defelem(zerod_name, zerod_ctrl_name, axis) self.print("Creating 1D controller", oned_ctrl_name, "...") self.defctrl("DummyOneDController", oned_ctrl_name) for axis, oned_name in enumerate(oned_names, 1): self.print("Creating 1D channel", oned_name, "...") - self.defelem(oned_name , oned_ctrl_name, axis) + self.defelem(oned_name, oned_ctrl_name, axis) self.print("Creating 2D controller", twod_ctrl_name, "...") self.defctrl("DummyTwoDController", twod_ctrl_name) for axis, twod_name in enumerate(twod_names, 1): self.print("Creating 2D channel", twod_name, "...") - self.defelem(twod_name , twod_ctrl_name, axis) - + self.defelem(twod_name, twod_ctrl_name, axis) + self.print("Creating Slit", pm_ctrl_name, "with", gap, ",", offset, "...") sl2t, sl2b = motor_names[:2] - self.defctrl("Slit", pm_ctrl_name, ["sl2t="+sl2t, "sl2b="+sl2b, - "Gap="+gap, "Offset="+offset]) + self.defctrl("Slit", pm_ctrl_name, ["sl2t=" + sl2t, "sl2b=" + sl2b, + "Gap=" + gap, "Offset=" + offset]) self.print("Creating trigger controller", tg_ctrl_name, "...") self.defctrl("DummyTriggerGateController", tg_ctrl_name) for axis, tg_name in enumerate(tg_names, 1): self.print("Creating trigger element", tg_name, "...") - self.defelem(tg_name , tg_ctrl_name, axis) + self.defelem(tg_name, tg_ctrl_name, axis) self.print("Creating IORegister controller", ior_ctrl_name, "...") self.defctrl("DummyIORController", ior_ctrl_name) for axis, ior_name in enumerate(ior_names, 1): self.print("Creating IORegister", ior_name, "...") self.defelem(ior_name, ior_ctrl_name, axis) - + self.print("Creating measurement group", mg_name, "...") self.defmeas(mg_name, ct_names) @@ -184,18 +188,19 @@ def sar_demo(self): self.setEnv("ActiveMntGrp", mg_name) controllers = pm_ctrl_name, mot_ctrl_name, ct_ctrl_name, \ - zerod_ctrl_name, oned_ctrl_name, twod_ctrl_name, \ - tg_ctrl_name, ior_ctrl_name + zerod_ctrl_name, oned_ctrl_name, twod_ctrl_name, \ + tg_ctrl_name, ior_ctrl_name elements = [gap, offset] + motor_names + ct_names + \ - zerod_names + oned_names + twod_names + tg_names + \ - ior_names + zerod_names + oned_names + twod_names + tg_names + \ + ior_names d = dict(controllers=controllers, elements=elements, measurement_groups=[mg_name]) - + self.setEnv(_ENV, d) - + self.print("DONE!") + @macro([["motor", Type.Moveable, None, '']]) def mym2(self, pm): self.output(pm.getMotorNames()) @@ -203,7 +208,7 @@ def mym2(self, pm): self.output(elements) self.output(type(pm)) self.output(type(elements[0])) - + @macro() def clear_sar_demo_hkl(self): diff --git a/src/sardana/macroserver/macros/env.py b/src/sardana/macroserver/macros/env.py index 8d7abb530b..fee7fda265 100644 --- a/src/sardana/macroserver/macros/env.py +++ b/src/sardana/macroserver/macros/env.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -30,14 +30,15 @@ from taurus.console.list import List from sardana.macroserver.macro import * -################################################################################ +########################################################################## # # Environment related macros # -################################################################################ +########################################################################## from lxml import etree + def reprValue(v, max=74): # cut long strings v = str(v) @@ -48,11 +49,11 @@ def reprValue(v, max=74): class dumpenv(Macro): """Dumps the complete environment""" - + def run(self): env = self.getGlobalEnv() - out = List(['Name','Value','Type']) - for k,v in env.iteritems(): + out = List(['Name', 'Value', 'Type']) + for k, v in env.iteritems(): str_v = reprValue(v) type_v = type(v).__name__ out.appendRow([str(k), str_v, type_v]) @@ -63,6 +64,7 @@ def run(self): class lsvo(Macro): """Lists the view options""" + def run(self): vo = self.getViewOptions() out = List(['View option', 'Value']) @@ -89,25 +91,25 @@ def run(self, name, value): class usetvo(Macro): """Resets the value of the given view option""" - + param_def = [['name', Type.String, None, 'View option name']] def run(self, name): self.resetViewOption(name) - + class lsenv(Macro): """Lists the environment in alphabetical order""" - + param_def = [ ['macro_list', ParamRepeat(['macro', Type.MacroClass, None, 'macro name'], min=0), None, 'List of macros to show environment'], ] - + def prepare(self, macro_list, **opts): self.table_opts = opts - + def run(self, macro_list): # list the environment for the current door if len(macro_list) == 0: @@ -121,8 +123,8 @@ def run(self, macro_list): type_name = type(env[k]).__name__ out.appendRow([k, str_val, type_name]) # list the environment for the current door for the given macros - else: - out = List(['Macro', 'Name', 'Value', 'Type']) + else: + out = List(['Macro', 'Name', 'Value', 'Type']) for macro in macro_list: env = self.getEnv(key=None, macro_name=macro.name) names_list = list(env.keys()) @@ -138,49 +140,55 @@ def run(self, macro_list): def reprValue(self, v, max=54): # cut long strings v = str(v) - if len(v) > max: v = '%s [...]' % v[:max] + if len(v) > max: + v = '%s [...]' % v[:max] return v + class senv(Macro): """Sets the given environment variable to the given value""" param_def = [['name', Type.Env, None, - 'Environment variable name. Can be one of the following:\n' \ - ' - - global variable\n' \ - ' - . - variable value for a specific door\n' \ - ' - . - variable value for a specific macro\n' \ + 'Environment variable name. Can be one of the following:\n' + ' - - global variable\n' + ' - . - variable value for a specific door\n' + ' - . - variable value for a specific macro\n' ' - .. - variable value for a specific macro running on a specific door'], ['value_list', - ParamRepeat(['value', Type.String, None, 'environment value item'], min=1), + ParamRepeat(['value', Type.String, None, + 'environment value item'], min=1), None, 'value(s). one item will eval to a single element. More than one item will eval to a tuple of elements'], - ] + ] def run(self, env, value): - if len(value) == 1: + if len(value) == 1: value = value[0] else: value = '(%s)' % ', '.join(value) - k,v = self.setEnv(env, value) + k, v = self.setEnv(env, value) line = '%s = %s' % (k, str(v)) self.output(line) + class usenv(Macro): """Unsets the given environment variable""" param_def = [ ['environment_list', - ParamRepeat(['env', Type.Env, None, 'Environment variable name'], min=1), + ParamRepeat( + ['env', Type.Env, None, 'Environment variable name'], min=1), None, 'List of environment items to be removed'], - ] - + ] + def run(self, env): self.unsetEnv(env) self.output("Success!") - + + class load_env(Macro): """ Read environment variables from config_env.xml file""" - + def run(self): - doc = etree.parse("config_env.xml") + doc = etree.parse("config_env.xml") root = doc.getroot() for element in root: if element.find("./name").text == "auto_filter": @@ -279,10 +287,9 @@ def run(self): self.setEnv("ExafsRegions", exafs_regions) self.output("ExafsRegions loaded") else: - self.output("ExafsRegions not found") + self.output("ExafsRegions not found") misc_tree = root.find("./miscellaneous") if misc_tree is not None: for parameter in misc_tree: if parameter.tag != "name": - self.setEnv(parameter.tag, parameter.text) - + self.setEnv(parameter.tag, parameter.text) diff --git a/src/sardana/macroserver/macros/examples/__init__.py b/src/sardana/macroserver/macros/examples/__init__.py index 37cca569f8..b72708e48d 100644 --- a/src/sardana/macroserver/macros/examples/__init__.py +++ b/src/sardana/macroserver/macros/examples/__init__.py @@ -2,28 +2,27 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """This package contains the macroserver example macros""" __docformat__ = 'restructuredtext' - diff --git a/src/sardana/macroserver/macros/examples/debug.py b/src/sardana/macroserver/macros/examples/debug.py index e2c26a6e9c..01e6334472 100644 --- a/src/sardana/macroserver/macros/examples/debug.py +++ b/src/sardana/macroserver/macros/examples/debug.py @@ -2,24 +2,24 @@ ############################################################################# ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################# @@ -35,4 +35,4 @@ @macro() def raise_exception(self): '''A macro that raises an exception (useful for debugging)''' - raise Exception('here is your exception!') + raise Exception('here is your exception!') diff --git a/src/sardana/macroserver/macros/examples/funcs.py b/src/sardana/macroserver/macros/examples/funcs.py index 4751f66952..2d3d69fecc 100644 --- a/src/sardana/macroserver/macros/examples/funcs.py +++ b/src/sardana/macroserver/macros/examples/funcs.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -36,33 +36,39 @@ def mfunc1(self): """First macro function. No parameters whatsoever""" self.output("Executing %s", self.getName()) - self.print("Hello",1) + self.print("Hello", 1) self.wa() + @macro() def mfunc2(self, p1): """Second macro function. One parameter of unknown type""" self.output("parameter: %s", p1) -@macro([ ["moveable", Type.Moveable, None, "motor to watch"] ]) + +@macro([["moveable", Type.Moveable, None, "motor to watch"]]) def mfunc3(self, moveable): """Third macro function. A proper moveable parameter""" - self.output("Moveable %s is at %s", moveable.getName(), moveable.getPosition()) + self.output("Moveable %s is at %s", + moveable.getName(), moveable.getPosition()) self.ascan(moveable, 0, 10, 10, 0.1) self.mfunc1() - + + @macro() def mfunc4(self, *args): """Fourth macro function. A list of parameters of unknown type""" self.output("parameters %s", args) - + + @macro() def mfunc5(self, *args): """Fifth macro function. A list of parameters of unknown type""" self.output("parameters %s", args) -@macro([ ["moveable", Type.Moveable, None, "moveable to move"], - ["position", Type.Float, None, "absolute position"] ]) + +@macro([["moveable", Type.Moveable, None, "moveable to move"], + ["position", Type.Float, None, "absolute position"]]) def move(self, moveable, position): """This macro moves a motor to the specified position""" moveable.move(position) diff --git a/src/sardana/macroserver/macros/examples/hooks.py b/src/sardana/macroserver/macros/examples/hooks.py index 707f74e5ba..a65c69027c 100644 --- a/src/sardana/macroserver/macros/examples/hooks.py +++ b/src/sardana/macroserver/macros/examples/hooks.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,33 +29,35 @@ __docformat__ = 'restructuredtext' from sardana.macroserver.macro import * - + + class loop(Macro, Hookable): """A macro that executes a for loop. It accepts hooks. This macro is part of the examples package. It was written for demonstration purposes""" - - hints = { 'allowsHooks':('pre-move', 'post-move', 'pre-acq', 'post-acq') } - + + hints = {'allowsHooks': ('pre-move', 'post-move', 'pre-acq', 'post-acq')} + param_def = [['start', Type.Integer, None, 'start point'], ['stop', Type.Integer, None, 'end point'], ['step', Type.Integer, 1, 'step']] def hook1(self): self.output("En hook 1") - + def run(self, start, stop, step): self.info("Starting loop") - self.hooks = [ (self.hook1, ["pre-acq"])] + self.hooks = [(self.hook1, ["pre-acq"])] for i in xrange(start, stop, step): self.output("At step %d" % i) self.flushOutput() - - for hook,hints in self.hooks: - self.info("running hook with hints="+repr(hints)) + + for hook, hints in self.hooks: + self.info("running hook with hints=" + repr(hints)) hook() self.info("Finished loop") + class captain_hook(Macro): """A macro that executes a loop macro. A hook was attached so that in each step of the loop this hook is executed. @@ -65,15 +67,16 @@ class captain_hook(Macro): param_def = [['start', Type.Integer, None, 'start point'], ['stop', Type.Integer, None, 'end point'], ['step', Type.Integer, 1, 'step']] - + def hook(self): self.info("\thook execution") - + def run(self, start, stop, step): - loop_macro = self.createMacro("loop",start,stop,step) - loop_macro.hooks = [ self.hook ] + loop_macro = self.createMacro("loop", start, stop, step) + loop_macro.hooks = [self.hook] self.runMacro(loop_macro) + class captain_hook2(Macro): """A macro that executes a loop macro. A hook was attached so that in each step of the loop this hook is executed. @@ -83,50 +86,55 @@ class captain_hook2(Macro): param_def = [['start', Type.Integer, None, 'start point'], ['stop', Type.Integer, None, 'end point'], ['step', Type.Integer, 1, 'step']] - + def hook(self): self.execMacroStr(["lsm"]) - + def run(self, start, stop, step): - loop_macro = self.createMacro("loop",start,stop,step) + loop_macro = self.createMacro("loop", start, stop, step) #h = self.createExecMacroHook(["lsm"]) - loop_macro.hooks = [ self.hook ] #it gives the "pre-acq" hint to the hook + # it gives the "pre-acq" hint to the hook + loop_macro.hooks = [self.hook] self.runMacro(loop_macro) + class hooked_scan(Macro): """An example on how to attach hooks to the various hook points of a scan. This macro is part of the examples package. It was written for demonstration purposes""" - + param_def = [ - ['motor', Type.Moveable,None, 'Motor to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor', Type.Moveable, None, 'Motor to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] + def hook1(self): self.info("\thook1 execution") - + def hook2(self): self.info("\thook2 execution") - + def hook3(self): self.info("\thook3 execution") - + def hook4(self): self.info("\thook4 execution") - + def hook5(self): self.info("\thook5 execution") - + def hook6(self): self.info("\thook6 execution") - + def run(self, motor, start_pos, final_pos, nr_interv, integ_time): - ascan, pars = self.createMacro("ascan",motor, start_pos, final_pos, nr_interv, integ_time) - ascan.hooks = [ (self.hook1, ["pre-acq"]), - (self.hook2, ["pre-acq","post-acq","pre-move", "post-move","aaaa"]), + ascan, pars = self.createMacro( + "ascan", motor, start_pos, final_pos, nr_interv, integ_time) + ascan.hooks = [(self.hook1, ["pre-acq"]), + (self.hook2, ["pre-acq", "post-acq", + "pre-move", "post-move", "aaaa"]), self.hook3, (self.hook4, ["pre-scan"]), (self.hook5, ["pre-scan", "post-scan"]), @@ -138,24 +146,26 @@ class hooked_dummyscan(Macro): """An example on how to attach hooks to the various hook points of a scan. This macro is part of the examples package. It was written for demonstration purposes""" - + param_def = [ - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] + def hook1(self): self.info("\thook1 execution") - + def hook2(self): self.info("\thook2 execution") - + def hook3(self): self.info("\thook3 execution") - + def run(self, start_pos, final_pos, nr_interv, integ_time): - dummyscan,pars = self.createMacro("dummyscan",start_pos, final_pos, nr_interv, integ_time) - dummyscan.hooks = [ (self.hook1, ["pre-scan"]), (self.hook2, ["pre-acq","post-acq","pre-move", "post-move","aaaa"]),(self.hook3, ["post-scan"])] + dummyscan, pars = self.createMacro( + "dummyscan", start_pos, final_pos, nr_interv, integ_time) + dummyscan.hooks = [(self.hook1, ["pre-scan"]), (self.hook2, ["pre-acq", + "post-acq", "pre-move", "post-move", "aaaa"]), (self.hook3, ["post-scan"])] self.runMacro(dummyscan) - diff --git a/src/sardana/macroserver/macros/examples/motion.py b/src/sardana/macroserver/macros/examples/motion.py index e1b2e1d521..3e80e8fe27 100755 --- a/src/sardana/macroserver/macros/examples/motion.py +++ b/src/sardana/macroserver/macros/examples/motion.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -53,4 +53,4 @@ def run(self, moveable, pos): motion.waitMove(id=_id) # this line will not be printed in case of abort (Ctrl-C) # due to https://sourceforge.net/p/sardana/tickets/9/ - self.info('final position: %s' % motion.readPosition()) \ No newline at end of file + self.info('final position: %s' % motion.readPosition()) diff --git a/src/sardana/macroserver/macros/examples/parameters.py b/src/sardana/macroserver/macros/examples/parameters.py index a625e9cd35..09ad01e370 100644 --- a/src/sardana/macroserver/macros/examples/parameters.py +++ b/src/sardana/macroserver/macros/examples/parameters.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,6 +29,7 @@ "pt7d1", "pt7d2", "pt8", "pt9", "pt10", "pt11", "pt12", "pt13", "pt14", "pt14d", "twice"] + class pt0(Macro): """Macro without parameters. Pretty dull. Usage from Spock, ex.: @@ -36,10 +37,11 @@ class pt0(Macro): """ param_def = [] - + def run(self): pass - + + class pt1(Macro): """Macro with one float parameter: Each parameter is described in the param_def sequence as being a sequence of four elements: name, type, @@ -47,12 +49,13 @@ class pt1(Macro): Usage from Spock, ex.: pt1 1 """ - - param_def = [ [ 'value', Type.Float, None, 'some bloody float'] ] - + + param_def = [['value', Type.Float, None, 'some bloody float']] + def run(self, f): pass + class pt2(Macro): """Macro with one Motor parameter: Each parameter is described in the param_def sequence as being a sequence of four elements: name, type, @@ -61,11 +64,12 @@ class pt2(Macro): pt2 mot1 """ - param_def = [ [ 'motor', Type.Motor, None, 'some bloody motor'] ] - + param_def = [['motor', Type.Motor, None, 'some bloody motor']] + def run(self, m): pass + class pt3(Macro): """Macro with a list of numbers as parameter: the type is a sequence of parameter types which is repeated. In this case it is a repetition of a @@ -77,12 +81,13 @@ class pt3(Macro): """ param_def = [ - [ 'numb_list', [ [ 'pos', Type.Float, None, 'value'] ], None, 'List of values'], + ['numb_list', [['pos', Type.Float, None, 'value']], None, 'List of values'], ] - + def run(self, *args, **kwargs): pass - + + class pt3d(Macro): """Macro with a list of numbers as parameter: the type is a sequence of parameter types which is repeated. In this case it is a repetition of a @@ -96,12 +101,13 @@ class pt3d(Macro): """ param_def = [ - [ 'numb_list', [ [ 'pos', Type.Float, 21, 'value'] ], None, 'List of values'], + ['numb_list', [['pos', Type.Float, 21, 'value']], None, 'List of values'], ] - + def run(self, *args, **kwargs): pass + class pt4(Macro): """Macro with a list of motors as parameter: the type is a sequence of parameter types which is repeated. In this case it is a repetition of a @@ -113,12 +119,14 @@ class pt4(Macro): """ param_def = [ - [ 'motor_list', [ [ 'motor', Type.Motor, None, 'motor name'] ], None, 'List of motors'], + ['motor_list', [['motor', Type.Motor, None, 'motor name']], + None, 'List of motors'], ] - + def run(self, *args, **kwargs): pass + class pt5(Macro): """Macro with a motor parameter followed by a list of numbers. Usages from Spock, ex.: @@ -127,13 +135,14 @@ class pt5(Macro): """ param_def = [ - [ 'motor', Type.Motor, None, 'Motor to move'], - [ 'numb_list', [ [ 'pos', Type.Float, None, 'value'] ], None, 'List of values'], + ['motor', Type.Motor, None, 'Motor to move'], + ['numb_list', [['pos', Type.Float, None, 'value']], None, 'List of values'], ] - + def run(self, *args, **kwargs): pass - + + class pt6(Macro): """Macro with a motor parameter followed by a list of numbers. The list as explicitly stated an optional last element which is a dictionary that defines the @@ -144,13 +153,15 @@ class pt6(Macro): """ param_def = [ - [ 'motor', Type.Motor, None, 'Motor to move'], - [ 'numb_list', [ [ 'pos', Type.Float, None, 'value'], { 'min' : 1, 'max' : None } ], None, 'List of values'], + ['motor', Type.Motor, None, 'Motor to move'], + ['numb_list', [['pos', Type.Float, None, 'value'], { + 'min': 1, 'max': None}], None, 'List of values'], ] - + def run(self, *args, **kwargs): pass - + + class pt7(Macro): """Macro with a list of pair Motor,Float. Usages from Spock, ex.: @@ -159,14 +170,15 @@ class pt7(Macro): """ param_def = [ - [ 'm_p_pair', [ [ 'motor', Type.Motor, None, 'Motor to move'], - [ 'pos', Type.Float, None, 'Position to move to'] ], + ['m_p_pair', [['motor', Type.Motor, None, 'Motor to move'], + ['pos', Type.Float, None, 'Position to move to']], None, 'List of motor/position pairs'] ] - + def run(self, *args, **kwargs): pass - + + class pt7d1(Macro): """Macro with a list of pair Motor,Float. Default value for last ParamRepeat element. Usages from Spock, ex.: @@ -174,19 +186,19 @@ class pt7d1(Macro): pt7d1 mot1 1 mot2 3 Using default value, ex.: pt7d1 [[mot1] [mot2 3]] # at any repetition - + """ param_def = [ - [ 'm_p_pair', [ [ 'motor', Type.Motor, None, 'Motor to move'], - [ 'pos', Type.Float, 2, 'Position to move to'] ], + ['m_p_pair', [['motor', Type.Motor, None, 'Motor to move'], + ['pos', Type.Float, 2, 'Position to move to']], None, 'List of motor/position pairs'] ] - + def run(self, *args, **kwargs): pass - + class pt7d2(Macro): """Macro with a list of pair Motor,Float. Default value for both ParamRepeat elements. Usages from Spock, ex.: @@ -197,13 +209,14 @@ class pt7d2(Macro): """ param_def = [ - [ 'm_p_pair', [ [ 'motor', Type.Motor, 'mot1', 'Motor to move'], - [ 'pos', Type.Float, 2, 'Position to move to'] ], + ['m_p_pair', [['motor', Type.Motor, 'mot1', 'Motor to move'], + ['pos', Type.Float, 2, 'Position to move to']], None, 'List of motor/position pairs'] ] - + def run(self, *args, **kwargs): - pass + pass + class pt8(Macro): """Macro with a list of pair Motor,Float. The min and max elements have been @@ -212,17 +225,18 @@ class pt8(Macro): pt8 [[mot1 1] [mot2 3]] pt8 mot1 1 mot2 3 """ - + param_def = [ - [ 'm_p_pair', [ [ 'motor', Type.Motor, None, 'Motor to move'], - [ 'pos', Type.Float, None, 'Position to move to'], - { 'min' : 1, 'max' : 2 } ], + ['m_p_pair', [['motor', Type.Motor, None, 'Motor to move'], + ['pos', Type.Float, None, 'Position to move to'], + {'min': 1, 'max': 2}], None, 'List of motor/position pairs'] ] - + def run(self, *args, **kwargs): pass + class pt9(Macro): """Same as macro pt7 but with old style ParamRepeat. If you are writing a macro with variable number of parameters for the first time don't even @@ -233,15 +247,16 @@ class pt9(Macro): """ param_def = [ - ['m_p_pair', - ParamRepeat(['motor', Type.Motor, None, 'Motor to move'], - ['pos', Type.Float, None, 'Position to move to'], min=1, max= 2), - None, 'List of motor/position pairs'], + ['m_p_pair', + ParamRepeat(['motor', Type.Motor, None, 'Motor to move'], + ['pos', Type.Float, None, 'Position to move to'], min=1, max=2), + None, 'List of motor/position pairs'], ] - + def run(self, *args, **kwargs): pass + class pt10(Macro): """Macro with list of numbers followed by a motor parameter. The repeat parameter may be defined as first one. @@ -250,13 +265,13 @@ class pt10(Macro): """ param_def = [ - ['numb_list', [['pos', Type.Float, None, 'value']], None, 'List of values'], - ['motor', Type.Motor, None, 'Motor to move'] + ['numb_list', [['pos', Type.Float, None, 'value']], None, 'List of values'], + ['motor', Type.Motor, None, 'Motor to move'] ] def run(self, *args, **kwargs): pass - + class pt11(Macro): """Macro with counter parameter followed by a list of numbers, followed by @@ -267,9 +282,9 @@ class pt11(Macro): """ param_def = [ - ['counter', Type.ExpChannel, None, 'Counter to count'], - ['numb_list', [['pos', Type.Float, None, 'value']], None, 'List of values'], - ['motor', Type.Motor, None, 'Motor to move'] + ['counter', Type.ExpChannel, None, 'Counter to count'], + ['numb_list', [['pos', Type.Float, None, 'value']], None, 'List of values'], + ['motor', Type.Motor, None, 'Motor to move'] ] def run(self, *args, **kwargs): @@ -284,8 +299,9 @@ class pt12(Macro): """ param_def = [ - ['numb_list', [['pos', Type.Float, None, 'value']], None, 'List of values'], - ['motor_list', [['motor', Type.Motor, None, 'Motor to move']], None, 'List of motors'] + ['numb_list', [['pos', Type.Float, None, 'value']], None, 'List of values'], + ['motor_list', [['motor', Type.Motor, None, 'Motor to move']], + None, 'List of motors'] ] def run(self, *args, **kwargs): @@ -300,15 +316,16 @@ class pt13(Macro): """ param_def = [ - ['motor_group_list', - [['motor_list', [['motor', Type.Motor, None, 'Motor to move']], None, 'List of motors']], - None, 'Motor groups'] + ['motor_group_list', + [['motor_list', [['motor', Type.Motor, None, 'Motor to move']], + None, 'List of motors']], + None, 'Motor groups'] ] def run(self, *args, **kwargs): pass - + class pt14(Macro): """Macro with list of motors groups, where each motor group is a list of motors and a float. Repeat parameters may be defined as nested. @@ -317,15 +334,16 @@ class pt14(Macro): """ param_def = [ - ['motor_group_list', - [['motor_list', [['motor', Type.Motor, None, 'Motor to move']], None, 'List of motors'], - ['float', Type.Float, None, 'Number']], - None, 'Motor groups'] + ['motor_group_list', + [['motor_list', [['motor', Type.Motor, None, 'Motor to move']], None, 'List of motors'], + ['float', Type.Float, None, 'Number']], + None, 'Motor groups'] ] def run(self, *args, **kwargs): - pass - + pass + + class pt14d(Macro): """Macro with list of motors groups, where each motor group is a list of motors and a float. Repeat parameters may be defined as nested. @@ -337,31 +355,33 @@ class pt14d(Macro): """ param_def = [ - ['motor_group_list', - [['motor_list', [['motor', Type.Motor, 'mot1', 'Motor to move']], None, 'List of motors'], - ['float', Type.Float, 33, 'Number']], - None, 'Motor groups'] + ['motor_group_list', + [['motor_list', [['motor', Type.Motor, 'mot1', 'Motor to move']], None, 'List of motors'], + ['float', Type.Float, 33, 'Number']], + None, 'Motor groups'] ] def run(self, *args, **kwargs): pass - + + class twice(Macro): """A macro that returns a float that is twice its input. It also sets its data to be a dictionary with 'in','out' as keys and value,result as values, respectively""" # uncomment the following lines as necessary. Otherwise you may delete them - param_def = [ [ "value", Type.Float, 23, "value to be doubled" ] ] - result_def = [ [ "result", Type.Float, None, "the double of the given value" ] ] + param_def = [["value", Type.Float, 23, "value to be doubled"]] + result_def = [["result", Type.Float, None, + "the double of the given value"]] #hints = {} - #env = (,) - + # env = (,) + # uncomment the following lines if need prepare. Otherwise you may delete them - #def prepare(self): + # def prepare(self): # pass - + def run(self, n): - ret = 2*n - self.setData({'in':n, 'out':ret}) + ret = 2 * n + self.setData({'in': n, 'out': ret}) return ret diff --git a/src/sardana/macroserver/macros/examples/plotting.py b/src/sardana/macroserver/macros/examples/plotting.py index 71fa3df173..750c2c56cc 100644 --- a/src/sardana/macroserver/macros/examples/plotting.py +++ b/src/sardana/macroserver/macros/examples/plotting.py @@ -5,11 +5,13 @@ from sardana.macroserver.macro import macro, Type + def j0i(x): """Integral form of J_0(x)""" def integrand(phi): return math.cos(x * math.sin(phi)) - return (1.0/math.pi) * quad(integrand, 0, math.pi)[0] + return (1.0 / math.pi) * quad(integrand, 0, math.pi)[0] + @macro() def J0_plot(self): @@ -18,15 +20,17 @@ def J0_plot(self): y = j0(x) x1 = x[::10] y1 = map(j0i, x1) - self.pyplot.plot(x, y, label=r'$J_0(x)$') # + self.pyplot.plot(x, y, label=r'$J_0(x)$') self.pyplot.plot(x1, y1, 'ro', label=r'$J_0^{integ}(x)$') - self.pyplot.title(r'Verify $J_0(x)=\frac{1}{\pi}\int_0^{\pi}\cos(x \sin\phi)\,d\phi$') + self.pyplot.title( + r'Verify $J_0(x)=\frac{1}{\pi}\int_0^{\pi}\cos(x \sin\phi)\,d\phi$') self.pyplot.xlabel('$x$') self.pyplot.legend() from numpy import random + @macro() def random_image(self): """Shows a random image 32x32""" @@ -34,22 +38,23 @@ def random_image(self): self.pyplot.matshow(img) import numpy - + + @macro([["interactions", Type.Integer, None, ""], ["density", Type.Integer, None, ""]]) def mandelbrot(self, interactions, density): x_min, x_max = -2, 1 y_min, y_max = -1.5, 1.5 - + x, y = numpy.meshgrid(numpy.linspace(x_min, x_max, density), numpy.linspace(y_min, y_max, density)) - + c = x + 1j * y z = c.copy() - + fractal = numpy.zeros(z.shape, dtype=numpy.uint8) + 255 - + finteractions = float(interactions) for n in range(interactions): z *= z diff --git a/src/sardana/macroserver/macros/examples/scans.py b/src/sardana/macroserver/macros/examples/scans.py index 649e51ee0f..9288b7f125 100644 --- a/src/sardana/macroserver/macros/examples/scans.py +++ b/src/sardana/macroserver/macros/examples/scans.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,7 +31,8 @@ """ -__all__ = ["ascan_demo", "ascanr", "toothedtriangle", "regscan", "reg2scan", "reg3scan", "a2scan_mod"] +__all__ = ["ascan_demo", "ascanr", "toothedtriangle", + "regscan", "reg2scan", "reg3scan", "a2scan_mod"] __docformat__ = 'restructuredtext' @@ -41,6 +42,7 @@ from sardana.macroserver.macro import * from sardana.macroserver.scan import * + class ascan_demo(Macro): """ This is a basic reimplementation of the ascan` macro for demonstration @@ -49,47 +51,53 @@ class ascan_demo(Macro): :class:`sardana.macroserver.macros.aNscan` and provides some extra features. """ - hints = { 'scan' : 'ascan_demo'} #this is used to indicate other codes that the macro is a scan - env = ('ActiveMntGrp',) #this hints that the macro requires the ActiveMntGrp environment variable to be set + # this is used to indicate other codes that the macro is a scan + hints = {'scan': 'ascan_demo'} + # this hints that the macro requires the ActiveMntGrp environment variable + # to be set + env = ('ActiveMntGrp',) param_def = [ - ['motor', Type.Moveable, None, 'Motor to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor', Type.Moveable, None, 'Motor to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): - #parse the user parameters + # parse the user parameters self.start = numpy.array([start_pos], dtype='d') self.final = numpy.array([final_pos], dtype='d') self.integ_time = integ_time - self.nr_points = nr_interv+1 - self.interv_size = ( self.final - self.start) / nr_interv - self.name='ascan_demo' - env = opts.get('env',{}) #the "env" dictionary may be passed as an option - - #create an instance of GScan (in this case, of its child, SScan - self._gScan=SScan(self, generator=self._generator, moveables=[motor], env=env) - + self.nr_points = nr_interv + 1 + self.interv_size = (self.final - self.start) / nr_interv + self.name = 'ascan_demo' + # the "env" dictionary may be passed as an option + env = opts.get('env', {}) + + # create an instance of GScan (in this case, of its child, SScan + self._gScan = SScan(self, generator=self._generator, + moveables=[motor], env=env) def _generator(self): step = {} - step["integ_time"] = self.integ_time #integ_time is the same for all steps + # integ_time is the same for all steps + step["integ_time"] = self.integ_time for point_no in xrange(self.nr_points): - step["positions"] = self.start + point_no * self.interv_size #note that this is a numpy array + step["positions"] = self.start + point_no * \ + self.interv_size # note that this is a numpy array step["point_id"] = point_no yield step - - def run(self,*args): - for step in self._gScan.step_scan(): #just go through the steps + + def run(self, *args): + for step in self._gScan.step_scan(): # just go through the steps yield step - + @property def data(self): - return self._gScan.data #the GScan provides scan data + return self._gScan.data # the GScan provides scan data class ascanr(Macro, Hookable): @@ -98,7 +106,7 @@ class ascanr(Macro, Hookable): It could be implemented deriving from aNscan, but I do it like this for clarity. Look for the comments with "!!!" for tips specific to the extra info columns I do not support constrains in this one for simplicity (see ascan for that) - + Do an absolute scan of the specified motor, repeating measurements in each step. ascanr scans one motor, as specified by motor. The motor starts at the position given by start_pos and ends at the position given by final_pos. @@ -107,66 +115,67 @@ class ascanr(Macro, Hookable): will be (nr_interv+1)*repeat. Count time for each acquisition is given by time which if positive, specifies seconds and if negative, specifies monitor counts. """ - hints = { 'scan' : 'ascanr', 'allowsHooks':('pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step') } + hints = {'scan': 'ascanr', 'allowsHooks': ( + 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step')} env = ('ActiveMntGrp',) param_def = [ - ['motor', Type.Moveable, None, 'Motor to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'], - ['repeat', Type.Integer, None, 'Number of Repetitions'] + ['motor', Type.Moveable, None, 'Motor to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'], + ['repeat', Type.Integer, None, 'Number of Repetitions'] ] - def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, repeat, **opts): - + self.starts = numpy.array([start_pos], dtype='d') self.finals = numpy.array([final_pos], dtype='d') self.nr_interv = nr_interv self.integ_time = integ_time - self.repeat=repeat + self.repeat = repeat self.opts = opts - self.nr_points = nr_interv+1 - self.interv_sizes = ( self.finals - self.starts) / nr_interv - self.name='ascanr' - - generator=self._generator - moveables=[motor] - env=opts.get('env',{}) - constrains=[] - extrainfodesc=[ColumnDesc(name='repetition', - dtype='int64', shape=(1,))] #!!! - - self._gScan=SScan(self, generator, moveables, env, constrains, extrainfodesc) #!!! - + self.nr_points = nr_interv + 1 + self.interv_sizes = (self.finals - self.starts) / nr_interv + self.name = 'ascanr' + + generator = self._generator + moveables = [motor] + env = opts.get('env', {}) + constrains = [] + extrainfodesc = [ColumnDesc(name='repetition', + dtype='int64', shape=(1,))] # !!! + + self._gScan = SScan(self, generator, moveables, env, + constrains, extrainfodesc) # !!! def _generator(self): step = {} - step["integ_time"] = self.integ_time - step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINT_') + step["integ_time"] = self.integ_time + step[ + "post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINT_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] - extrainfo = {"repetition":0} #!!! - step['extrainfo'] = extrainfo #!!! + extrainfo = {"repetition": 0} # !!! + step['extrainfo'] = extrainfo # !!! for point_no in xrange(self.nr_points): step["positions"] = self.starts + point_no * self.interv_sizes step["point_id"] = point_no for i in xrange(self.repeat): - extrainfo["repetition"] = i #!!! + extrainfo["repetition"] = i # !!! yield step - - def run(self,*args): + + def run(self, *args): for step in self._gScan.step_scan(): yield step - + @property def data(self): return self._gScan.data - + class toothedtriangle(Macro, Hookable): """toothedtriangle macro implemented with the gscan framework. @@ -177,25 +186,25 @@ class toothedtriangle(Macro, Hookable): At each step, nr_samples acquisitions are performed. The total number of points in the scan is nr_interv*2*nr_cycles*nr_samples+1""" - hints = { 'scan' : 'toothedtriangle', - 'allowsHooks':('pre-scan', 'pre-move', 'post-move', 'pre-acq', - 'post-acq', 'post-step', 'post-scan') + hints = {'scan': 'toothedtriangle', + 'allowsHooks': ('pre-scan', 'pre-move', 'post-move', 'pre-acq', + 'post-acq', 'post-step', 'post-scan') } env = ('ActiveMntGrp',) param_def = [ - ['motor', Type.Moveable, None, 'Motor to move'], - ['start_pos', Type.Float, None, 'start position'], - ['final_pos', Type.Float, None, 'position after half cycle'], - ['nr_interv', Type.Integer, None, 'Number of intervals in half cycle'], - ['integ_time', Type.Float, None, 'Integration time'], - ['nr_cycles', Type.Integer, None, 'Number of cycles'], - ['nr_samples', Type.Integer, 1 , 'Number of samples at each point'] + ['motor', Type.Moveable, None, 'Motor to move'], + ['start_pos', Type.Float, None, 'start position'], + ['final_pos', Type.Float, None, 'position after half cycle'], + ['nr_interv', Type.Integer, None, 'Number of intervals in half cycle'], + ['integ_time', Type.Float, None, 'Integration time'], + ['nr_cycles', Type.Integer, None, 'Number of cycles'], + ['nr_samples', Type.Integer, 1, 'Number of samples at each point'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, nr_cycles, nr_samples, **opts): - + self.start_pos = start_pos self.final_pos = final_pos self.nr_interv = nr_interv @@ -203,67 +212,70 @@ def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, self.nr_cycles = nr_cycles self.nr_samples = nr_samples self.opts = opts - cycle_nr_points = self.nr_interv+1 + (self.nr_interv+1)-2 - self.nr_points = cycle_nr_points*nr_samples*nr_cycles+nr_samples - - self.interv_size = ( self.final_pos - self.start_pos) / nr_interv - self.name='toothedtriangle' - - generator=self._generator + cycle_nr_points = self.nr_interv + 1 + (self.nr_interv + 1) - 2 + self.nr_points = cycle_nr_points * nr_samples * nr_cycles + nr_samples + + self.interv_size = (self.final_pos - self.start_pos) / nr_interv + self.name = 'toothedtriangle' + + generator = self._generator moveables = [] moveable = MoveableDesc(moveable=motor, is_reference=True, - min_value=min(start_pos,final_pos), - max_value=max(start_pos,final_pos)) - moveables=[moveable] - env=opts.get('env',{}) - constrains=[] - extrainfodesc=[ColumnDesc(name='cycle', dtype='int64', shape=(1,)), - ColumnDesc(name='interval', dtype='int64', shape=(1,)), - ColumnDesc(name='sample', dtype='int64', shape=(1,))] #!!! - - self._gScan=SScan(self, generator, moveables, env, constrains, extrainfodesc) #!!! - + min_value=min(start_pos, final_pos), + max_value=max(start_pos, final_pos)) + moveables = [moveable] + env = opts.get('env', {}) + constrains = [] + extrainfodesc = [ColumnDesc(name='cycle', dtype='int64', shape=(1,)), + ColumnDesc(name='interval', + dtype='int64', shape=(1,)), + ColumnDesc(name='sample', dtype='int64', shape=(1,))] # !!! + + self._gScan = SScan(self, generator, moveables, env, + constrains, extrainfodesc) # !!! def _generator(self): step = {} - step["integ_time"] = self.integ_time + step["integ_time"] = self.integ_time step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["pre-acq-hooks"] = self.getHooks('pre-acq') - step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINT_') + step[ + "post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINT_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] - extrainfo = {"cycle":None, "interval":None, "sample":None, } + extrainfo = {"cycle": None, "interval": None, "sample": None, } step['extrainfo'] = extrainfo - halfcycle1=range(self.nr_interv+1) - halfcycle2=halfcycle1[1:-1] + halfcycle1 = range(self.nr_interv + 1) + halfcycle2 = halfcycle1[1:-1] halfcycle2.reverse() - intervallist=halfcycle1+halfcycle2 - point_no=0 + intervallist = halfcycle1 + halfcycle2 + point_no = 0 for cycle in xrange(self.nr_cycles): extrainfo["cycle"] = cycle for interval in intervallist: extrainfo["interval"] = interval - step["positions"] = numpy.array([self.start_pos + (interval) * self.interv_size] ,dtype='d') + step["positions"] = numpy.array( + [self.start_pos + (interval) * self.interv_size], dtype='d') for sample in xrange(self.nr_samples): extrainfo["sample"] = sample - step["point_id"] = point_no + step["point_id"] = point_no yield step - point_no+=1 - - #last step for closing the loop + point_no += 1 + + # last step for closing the loop extrainfo["interval"] = 0 - step["positions"] = numpy.array([self.start_pos] ,dtype='d') + step["positions"] = numpy.array([self.start_pos], dtype='d') for sample in xrange(self.nr_samples): extrainfo["sample"] = sample - step["point_id"] = point_no + step["point_id"] = point_no yield step - point_no+=1 - - def run(self,*args): + point_no += 1 + + def run(self, *args): for step in self._gScan.step_scan(): yield step - + @property def data(self): return self._gScan.data @@ -275,7 +287,7 @@ class regscan(Macro): It uses the gscan framework. """ - hints = {'scan' : 'regscan'} + hints = {'scan': 'regscan'} env = ('ActiveMntGrp',) param_def = [ @@ -289,30 +301,33 @@ class regscan(Macro): ] def prepare(self, motor, integ_time, start_pos, regions, **opts): - self.name='regscan' + self.name = 'regscan' self.integ_time = integ_time self.start_pos = start_pos self.regions = regions - self.regions_count = len(self.regions)/2 - - generator=self._generator - moveables=[motor] - env=opts.get('env',{}) - constrains=[] - self._gScan=SScan(self, generator, moveables, env, constrains) + self.regions_count = len(self.regions) / 2 + + generator = self._generator + moveables = [motor] + env = opts.get('env', {}) + constrains = [] + self._gScan = SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} - step["integ_time"] = self.integ_time - + step["integ_time"] = self.integ_time + point_id = 0 region_start = self.start_pos for r in range(len(self.regions)): - region_stop, region_nr_intervals = self.regions[r][0], self.regions[r][1] - positions = numpy.linspace(region_start, region_stop, region_nr_intervals+1) + region_stop, region_nr_intervals = self.regions[ + r][0], self.regions[r][1] + positions = numpy.linspace( + region_start, region_stop, region_nr_intervals + 1) if region_start != self.start_pos: # positions must be calculated from the start to the end of the region - # but after the first region, the 'start' point must not be repeated + # but after the first region, the 'start' point must not be + # repeated positions = positions[1:] for p in positions: step['positions'] = [p] @@ -321,7 +336,7 @@ def _generator(self): yield step region_start = region_stop - def run(self,*args): + def run(self, *args): for step in self._gScan.step_scan(): yield step @@ -332,7 +347,7 @@ class reg2scan(Macro): It uses the gscan framework. All the motors will be drived to the same position in each step """ - hints = {'scan' : 'reg2scan'} + hints = {'scan': 'reg2scan'} env = ('ActiveMntGrp',) param_def = [ @@ -347,30 +362,33 @@ class reg2scan(Macro): ] def prepare(self, motor1, motor2, integ_time, start_pos, regions, **opts): - self.name='reg2scan' + self.name = 'reg2scan' self.integ_time = integ_time self.start_pos = start_pos self.regions = regions - self.regions_count = len(self.regions)/2 + self.regions_count = len(self.regions) / 2 - generator=self._generator - moveables=[motor1, motor2] - env=opts.get('env',{}) - constrains=[] - self._gScan=SScan(self, generator, moveables, env, constrains) + generator = self._generator + moveables = [motor1, motor2] + env = opts.get('env', {}) + constrains = [] + self._gScan = SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} - step["integ_time"] = self.integ_time + step["integ_time"] = self.integ_time point_id = 0 region_start = self.start_pos for r in range(len(self.regions)): - region_stop, region_nr_intervals = self.regions[r][0], self.regions[r][1] - positions = numpy.linspace(region_start, region_stop, region_nr_intervals+1) + region_stop, region_nr_intervals = self.regions[ + r][0], self.regions[r][1] + positions = numpy.linspace( + region_start, region_stop, region_nr_intervals + 1) if region_start != self.start_pos: # positions must be calculated from the start to the end of the region - # but after the first region, the 'start' point must not be repeated + # but after the first region, the 'start' point must not be + # repeated positions = positions[1:] for p in positions: step['positions'] = [p, p] @@ -379,7 +397,7 @@ def _generator(self): yield step region_start = region_stop - def run(self,*args): + def run(self, *args): for step in self._gScan.step_scan(): yield step @@ -393,7 +411,7 @@ class reg3scan(Macro): specified before the regions. """ - hints = {'scan' : 'reg3scan'} + hints = {'scan': 'reg3scan'} env = ('ActiveMntGrp',) param_def = [ @@ -409,30 +427,33 @@ class reg3scan(Macro): ] def prepare(self, motor1, motor2, motor3, integ_time, start_pos, regions, **opts): - self.name='reg3scan' + self.name = 'reg3scan' self.integ_time = integ_time self.start_pos = start_pos self.regions = regions - self.regions_count = len(self.regions)/2 + self.regions_count = len(self.regions) / 2 - generator=self._generator - moveables=[motor1, motor2, motor3] - env=opts.get('env',{}) - constrains=[] - self._gScan=SScan(self, generator, moveables, env, constrains) + generator = self._generator + moveables = [motor1, motor2, motor3] + env = opts.get('env', {}) + constrains = [] + self._gScan = SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} - step["integ_time"] = self.integ_time + step["integ_time"] = self.integ_time point_id = 0 region_start = self.start_pos for r in range(len(self.regions)): - region_stop, region_nr_intervals = self.regions[r][0], self.regions[r][1] - positions = numpy.linspace(region_start, region_stop, region_nr_intervals+1) + region_stop, region_nr_intervals = self.regions[ + r][0], self.regions[r][1] + positions = numpy.linspace( + region_start, region_stop, region_nr_intervals + 1) if region_start != self.start_pos: # positions must be calculated from the start to the end of the region - # but after the first region, the 'start' point must not be repeated + # but after the first region, the 'start' point must not be + # repeated positions = positions[1:] for p in positions: step['positions'] = [p, p, p] @@ -441,7 +462,7 @@ def _generator(self): yield step region_start = region_stop - def run(self,*args): + def run(self, *args): for step in self._gScan.step_scan(): yield step @@ -453,24 +474,24 @@ class a2scan_mod(Macro): It uses the gscan framework. """ - hints = {'scan' : 'a2scan_mod'} + hints = {'scan': 'a2scan_mod'} env = ('ActiveMntGrp',) param_def = [ - ['motor1', Type.Moveable, None, 'Motor 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['nr_interv1', Type.Integer, None, 'Number of scan intervals of Motor 1'], - ['motor2', Type.Moveable, None, 'Motor 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['nr_interv2', Type.Integer, None, 'Number of scan intervals of Motor 2'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor1', Type.Moveable, None, 'Motor 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['nr_interv1', Type.Integer, None, 'Number of scan intervals of Motor 1'], + ['motor2', Type.Moveable, None, 'Motor 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['nr_interv2', Type.Integer, None, 'Number of scan intervals of Motor 2'], + ['integ_time', Type.Float, None, 'Integration time'] ] - + def prepare(self, motor1, start_pos1, final_pos1, nr_interv1, motor2, start_pos2, final_pos2, nr_interv2, integ_time, **opts): - self.name='a2scan_mod' + self.name = 'a2scan_mod' self.integ_time = integ_time self.start_pos1 = start_pos1 self.final_pos1 = final_pos1 @@ -478,37 +499,39 @@ def prepare(self, motor1, start_pos1, final_pos1, nr_interv1, motor2, start_pos2 self.start_pos2 = start_pos2 self.final_pos2 = final_pos2 self.nr_interv2 = nr_interv2 - + generator = self._generator moveables = [motor1, motor2] - env = opts.get('env',{}) + env = opts.get('env', {}) constraints = [] - self._gScan=SScan(self, generator, moveables, env, constraints) + self._gScan = SScan(self, generator, moveables, env, constraints) def _generator(self): step = {} - step["integ_time"] = self.integ_time + step["integ_time"] = self.integ_time start1, end1, interv1 = self.start_pos1, self.final_pos1, self.nr_interv1 start2, end2, interv2 = self.start_pos2, self.final_pos2, self.nr_interv2 - + # Prepare the positions - positions_m1 = numpy.linspace(start1, end1, interv1+1) - positions_m2 = numpy.linspace(start2, end2, interv2+1) + positions_m1 = numpy.linspace(start1, end1, interv1 + 1) + positions_m2 = numpy.linspace(start2, end2, interv2 + 1) if interv1 > interv2: - positions_m2 = start2+(float(end2-start2)/interv2)*(numpy.arange(interv1+1)//(float(interv1)/float(interv2))) + positions_m2 = start2 + (float(end2 - start2) / interv2) * ( + numpy.arange(interv1 + 1) // (float(interv1) / float(interv2))) elif interv2 > interv1: - positions_m1 = start1+(float(end1-start1)/interv1)*(numpy.arange(interv2+1)//(float(interv2)/float(interv1))) + positions_m1 = start1 + (float(end1 - start1) / interv1) * ( + numpy.arange(interv2 + 1) // (float(interv2) / float(interv1))) point_id = 0 - for pos1,pos2 in zip(positions_m1,positions_m2): + for pos1, pos2 in zip(positions_m1, positions_m2): step['point_id'] = point_id step['positions'] = [pos1, pos2] yield step point_id += 1 - - def run(self,*args): + + def run(self, *args): for step in self._gScan.step_scan(): yield step @@ -521,52 +544,54 @@ class ascanc_demo(Macro): :class:`sardana.macroserver.macros.aNscan` and provides some extra features. """ - hints = { 'scan' : 'ascanc_demo'} #this is used to indicate other codes that the macro is a scan - env = ('ActiveMntGrp',) #this hints that the macro requires the ActiveMntGrp environment variable to be set + # this is used to indicate other codes that the macro is a scan + hints = {'scan': 'ascanc_demo'} + # this hints that the macro requires the ActiveMntGrp environment variable + # to be set + env = ('ActiveMntGrp',) param_def = [ - ['motor', Type.Moveable, None, 'Motor to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor', Type.Moveable, None, 'Motor to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, integ_time, **opts): - self.name='ascanc_demo' - #parse the user parameters + self.name = 'ascanc_demo' + # parse the user parameters self.start = numpy.array([start_pos], dtype='d') self.final = numpy.array([final_pos], dtype='d') self.integ_time = integ_time - env = opts.get('env',{}) #the "env" dictionary may be passed as an option - - #create an instance of GScan (in this case, of its child, CScan - self._gScan = CScan(self, - waypointGenerator=self._waypoint_generator, - periodGenerator=self._period_generator, - moveables=[motor], + # the "env" dictionary may be passed as an option + env = opts.get('env', {}) + + # create an instance of GScan (in this case, of its child, CScan + self._gScan = CScan(self, + waypointGenerator=self._waypoint_generator, + periodGenerator=self._period_generator, + moveables=[motor], env=env) - + def _waypoint_generator(self): - #a very simple waypoint generator! only start and stop points! - yield {"positions":self.start, "waypoint_id": 0} - yield {"positions":self.final, "waypoint_id": 1} - + # a very simple waypoint generator! only start and stop points! + yield {"positions": self.start, "waypoint_id": 0} + yield {"positions": self.final, "waypoint_id": 1} def _period_generator(self): step = {} - step["integ_time"] = self.integ_time + step["integ_time"] = self.integ_time point_no = 0 - while(True): #infinite generator. The acquisition loop is started/stopped at begin and end of each waypoint + while(True): # infinite generator. The acquisition loop is started/stopped at begin and end of each waypoint point_no += 1 step["point_id"] = point_no yield step - - def run(self,*args): + + def run(self, *args): for step in self._gScan.step_scan(): yield step - class ascan_with_addcustomdata(ascan_demo): ''' example of an ascan-like macro where we demonstrate how to pass custom data to the data handler. @@ -577,29 +602,34 @@ class ascan_with_addcustomdata(ascan_demo): - NXscan_FileRecorder - SPEC_FileRecorder (this will ignore array data) ''' + def run(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): - #we get the datahandler + # we get the datahandler dh = self._gScan._data_handler - #at this point the entry name is not yet set, so we give it explicitly (otherwise it would default to "entry") - dh.addCustomData('Hello world1', 'dummyChar1', nxpath='/custom_entry:NXentry/customdata:NXcollection') - #this is the normal scan loop + # at this point the entry name is not yet set, so we give it explicitly + # (otherwise it would default to "entry") + dh.addCustomData('Hello world1', 'dummyChar1', + nxpath='/custom_entry:NXentry/customdata:NXcollection') + # this is the normal scan loop for step in self._gScan.step_scan(): yield step - #the entry number is known and the default nxpath is used "//custom_data") if none given + # the entry number is known and the default nxpath is used + # "//custom_data") if none given dh.addCustomData('Hello world1', 'dummyChar1') - #you can pass arrays (but not all recorders will handle them) - dh.addCustomData(range(10), 'dummyArray1') - #you can pass a custom nxpath *relative* to the current entry - dh.addCustomData('Hello world2', 'dummyChar2', nxpath='sample:NXsample') - - #calculate a linear fit to the timestamps VS motor positions and store it - x = [r.data [motor.getName()] for r in self.data.records] + # you can pass arrays (but not all recorders will handle them) + dh.addCustomData(range(10), 'dummyArray1') + # you can pass a custom nxpath *relative* to the current entry + dh.addCustomData('Hello world2', 'dummyChar2', + nxpath='sample:NXsample') + + # calculate a linear fit to the timestamps VS motor positions and store + # it + x = [r.data[motor.getName()] for r in self.data.records] y = [r.data['timestamp'] for r in self.data.records] - fitted_y = numpy.polyval(numpy.polyfit(x,y,1), x) - dh.addCustomData(fitted_y, 'fittedtime', nxpath='measurement:NXcollection') - - #as a bonus, plot the fit + fitted_y = numpy.polyval(numpy.polyfit(x, y, 1), x) + dh.addCustomData(fitted_y, 'fittedtime', + nxpath='measurement:NXcollection') + + # as a bonus, plot the fit self.pyplot.plot(x, y, 'ro') self.pyplot.plot(x, fitted_y, 'b-') - - \ No newline at end of file diff --git a/src/sardana/macroserver/macros/examples/specific_experiments.py b/src/sardana/macroserver/macros/examples/specific_experiments.py index 5650376b28..bc09219eb8 100644 --- a/src/sardana/macroserver/macros/examples/specific_experiments.py +++ b/src/sardana/macroserver/macros/examples/specific_experiments.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -30,84 +30,93 @@ __docformat__ = 'restructuredtext' import numpy - + from sardana.macroserver.macro import * from sardana.macroserver.scan import * + class xas_acq(Macro, Hookable): """ .. warning:: This macro is still under development. It may change. - + Perform an X-ray absorption scan experiment. Data is stored in a NXxas-compliant file. """ - hints = { 'FileRecorder':'NXxas_FileRecorder', 'scan' : 'xas_acq', 'allowsHooks':('pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step') } - #env = ('MonochromatorEnergy', )#'AbsorbedBeam', 'IncomingBeam', 'Monitor') #this hints that the macro requires the ActiveMntGrp environment variable to be set + hints = {'FileRecorder': 'NXxas_FileRecorder', 'scan': 'xas_acq', 'allowsHooks': ( + 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step')} + # env = ('MonochromatorEnergy', )#'AbsorbedBeam', 'IncomingBeam', + # 'Monitor') #this hints that the macro requires the ActiveMntGrp + # environment variable to be set param_def = [ - ['start', Type.Float, None, 'start energy in keV'], - ['final', Type.Float, None, 'final energy in keV'], - ['nr_interv', Type.Integer, None, 'Number of energy intervals'], - ['integ_time', Type.Float, None, 'Integration time in s'] + ['start', Type.Float, None, 'start energy in keV'], + ['final', Type.Float, None, 'final energy in keV'], + ['nr_interv', Type.Integer, None, 'Number of energy intervals'], + ['integ_time', Type.Float, None, 'Integration time in s'] ] def prepare(self, start, final, nr_interv, integ_time, **opts): - #parse the user parameters + # parse the user parameters self.starts = numpy.array([start], dtype='d') self.finals = numpy.array([final], dtype='d') self.integ_time = integ_time - self.nr_points = nr_interv+1 - self.interv_sizes = ( self.finals - self.starts) / nr_interv - self.name='xas_acq' - env = opts.get('env',{}) #the "env" dictionary may be passed as an option + self.nr_points = nr_interv + 1 + self.interv_sizes = (self.finals - self.starts) / nr_interv + self.name = 'xas_acq' + # the "env" dictionary may be passed as an option + env = opts.get('env', {}) env['integ_time'] = integ_time - - #print "!!!!!", type(self.getInstrument('/instrument/monochromator')), self.getEnv('MonochromatorEnergy', macro_name=self.name) - #ElementWithInterface('Instrument','monochromator') - for n,e in self.getElementsWithInterface('Instrument').iteritems(): - inst=e.getObj() - print n, e.name, inst.getFullName(), type(e), type(inst), type(inst.getPoolObj())#,inst.getElements() - - #maybe I should use the instrument interface to obtain the right counters - - env['monochromator'] = monochromator = self.getEnv('MonochromatorEnergy', macro_name=self.name) + + # print "!!!!!", type(self.getInstrument('/instrument/monochromator')), self.getEnv('MonochromatorEnergy', macro_name=self.name) + # ElementWithInterface('Instrument','monochromator') + for n, e in self.getElementsWithInterface('Instrument').iteritems(): + inst = e.getObj() + # ,inst.getElements() + print n, e.name, inst.getFullName(), type(e), type(inst), type(inst.getPoolObj()) + + # maybe I should use the instrument interface to obtain the right + # counters + + env['monochromator'] = monochromator = self.getEnv( + 'MonochromatorEnergy', macro_name=self.name) energymotor = self.getMoveable(monochromator) - xasMntGrp = self.getMeasurementGroup(self.getEnv('xasMntGrp', macro_name=self.name)) - - xasMntGrp=xasMntGrp.getObj() - monitor,incbeam,absbeam = xasMntGrp.getChannelNames()[:3] + xasMntGrp = self.getMeasurementGroup( + self.getEnv('xasMntGrp', macro_name=self.name)) + + xasMntGrp = xasMntGrp.getObj() + monitor, incbeam, absbeam = xasMntGrp.getChannelNames()[:3] env['monitor'] = monitor env['absbeam'] = absbeam env['incbeam'] = incbeam - + # print "!!!!!!!!",xasMntGrp.getObj().getElements() - - + + # absbeam = self.getExpChannel(self.getEnv('AbsorbedBeam')) #this should be get measurement group (e.g., second channel?) # incbeam = self.getExpChannel(self.getEnv('IncomingBeam')) #this should be get measurement group (e.g., first channel?) -# monitor = self.getExpChannel(self.getEnv('Monitor')) #this should be get from the monitor of the measurement group - - - #create an instance of GScan (in this case, of its child, SScan - self._gScan=SScan(self, generator=self._generator, moveables=[energymotor], env=env) - +# monitor = self.getExpChannel(self.getEnv('Monitor')) #this should be +# get from the monitor of the measurement group + + # create an instance of GScan (in this case, of its child, SScan + self._gScan = SScan(self, generator=self._generator, + moveables=[energymotor], env=env) + def _generator(self): step = {} - step["integ_time"] = self.integ_time - step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINT_') + step["integ_time"] = self.integ_time + step[ + "post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINT_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] for point_no in xrange(self.nr_points): step["positions"] = self.starts + point_no * self.interv_sizes step["point_id"] = point_no yield step - - def run(self,*args): - for step in self._gScan.step_scan(): #just go through the steps + + def run(self, *args): + for step in self._gScan.step_scan(): # just go through the steps yield step - + @property def data(self): - return self._gScan.data #the GScan provides scan data - - \ No newline at end of file + return self._gScan.data # the GScan provides scan data diff --git a/src/sardana/macroserver/macros/examples/submacros.py b/src/sardana/macroserver/macros/examples/submacros.py index 90445e10f2..e859c7baf4 100644 --- a/src/sardana/macroserver/macros/examples/submacros.py +++ b/src/sardana/macroserver/macros/examples/submacros.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -37,11 +37,13 @@ # The 'subsubm' macro itself calls a short ascan macro #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~--~-~- + class call_wa(Macro): - + def run(self): self.macros.wa() - + + class call_wm(Macro): param_def = [ @@ -52,10 +54,12 @@ class call_wm(Macro): def run(self, m): self.macros.wm(m) - + + class subsubm(Macro): """this macro just calls the 'subm' macro This macro is part of the examples package. It was written for demonstration purposes""" + def run(self): self.output("Starting %s" % self.getName()) m = self.macros @@ -63,19 +67,21 @@ def run(self): m.ascan(motors[0], 0, 100, 10, 0.2) self.output("Finished %s" % self.getName()) + class subm(Macro): """this macro just calls the 'subsubm' macro This macro is part of the examples package. It was written for demonstration purposes""" - + def run(self): self.output("Starting %s" % self.getName()) self.macros.subsubm() self.output("Finished %s" % self.getName()) + class mainmacro(Macro): """this macro just calls the 'subm' macro This macro is part of the examples package. It was written for demonstration purposes""" - + def run(self): self.output("Starting %s" % self.getName()) self.macros.subm() @@ -87,11 +93,12 @@ def run(self): # another macro #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~--~-~- + class runsubs(Macro): """ A macro that calls a ascan macro using the motor given as first parameter. - + This macro is part of the examples package. It was written for demonstration purposes - + Call type will allow to choose to format in which the ascan macro is called from this macro: 1 - m.ascan(motor.getName(), '0', '10', '4', '0.2') @@ -111,17 +118,17 @@ class runsubs(Macro): macro, prep = self.createMacro(params) macro.hooks = [ self.hook ] self.runMacro(macro) - + Options 7,8 and 9 use the lower level macro API in order to be able to attach hooks to the ascan macro.""" param_def = [ - ['motor', Type.Motor, None, 'Motor to move'], - ['call_type', Type.Integer, 2, 'type of run to execute internally'], + ['motor', Type.Motor, None, 'Motor to move'], + ['call_type', Type.Integer, 2, 'type of run to execute internally'], ] - + def hook(self): self.info("executing hook in a step of a scan...") - + def run(self, motor, call_type): m = self.macros self.output("Using type %d" % call_type) @@ -139,18 +146,16 @@ def run(self, motor, call_type): elif call_type == 6: self.execMacro("ascan %s 0 10 4 0.2" % motor.getName()) elif call_type == 7: - macro, prep = self.createMacro("ascan %s 0 10 4 0.2" % \ - motor.getName()) - macro.hooks = [ self.hook ] + macro, prep = self.createMacro("ascan %s 0 10 4 0.2" % + motor.getName()) + macro.hooks = [self.hook] self.runMacro(macro) elif call_type == 8: macro, prep = self.createMacro('ascan', motor, 0, 10, 4, 0.2) - macro.hooks = [ self.hook ] + macro.hooks = [self.hook] self.runMacro(macro) elif call_type == 9: params = 'ascan', motor, 0, 10, 4, 0.2 macro, prep = self.createMacro(params) - macro.hooks = [ self.hook ] + macro.hooks = [self.hook] self.runMacro(macro) - - diff --git a/src/sardana/macroserver/macros/examples/user_input.py b/src/sardana/macroserver/macros/examples/user_input.py index 26467a2cae..26157280d9 100644 --- a/src/sardana/macroserver/macros/examples/user_input.py +++ b/src/sardana/macroserver/macros/examples/user_input.py @@ -1,84 +1,93 @@ from sardana.macroserver.macro import imacro, Type + @imacro() def ask_number_of_points(self): """asks user for the number of points""" - + nb_points = self.input("How many points?", data_type=Type.Integer) - + @imacro() def ask_for_moveable(self): """asks user for a motor""" - + moveable = self.input("Which moveable?", data_type=Type.Moveable) - self.output("You selected %s which is at %f", moveable, moveable.getPosition()) + self.output("You selected %s which is at %f", + moveable, moveable.getPosition()) + @imacro() def ask_for_car_brand(self): """asks user for a car brand""" - + car_brands = "Mazda", "Citroen", "Renault" car_brand = self.input("Which car brand?", data_type=car_brands) self.output("You selected %s", car_brand) - + + @imacro() def ask_for_multiple_car_brands(self): """asks user for several car brands""" - + car_brands = "Mazda", "Citroen", "Renault", "Ferrari", "Porche", "Skoda" car_brands = self.input("Which car brand(s)?", data_type=car_brands, allow_multiple=True, title="Favorites") self.output("You selected %s", ", ".join(car_brands)) + @imacro() def ask_peak(self): """asks user for peak current of points with a custom title""" - + peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection") self.output("You selected a peak of %f A", peak) - + + @imacro() def ask_peak_v2(self): """asks user for peak current of points with a custom title, default value, label and units""" - + label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4) self.output("You selected a %s of %f %s", label, peak, unit) - + + @imacro() def ask_peak_v3(self): """asks user for peak current of points with a custom title, default value, label, units and ranges""" - + label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4, minimum=0.0, maximum=200.0) self.output("You selected a %s of %f %s", label, peak, unit) + @imacro() def ask_peak_v4(self): """asks user for peak current of points with a custom title, default value, label, units, ranges and step size""" - + label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, default_value=123.4, minimum=0.0, maximum=200.0, step=5) self.output("You selected a %s of %f %s", label, peak, unit) - + + @imacro() def ask_peak_v5(self): """asks user for peak current of points with a custom title, default value, label, units, ranges, step size and decimal places""" - + label, unit = "peak", "mA" peak = self.input("What is the peak current?", data_type=Type.Float, title="Peak selection", key=label, unit=unit, diff --git a/src/sardana/macroserver/macros/expert.py b/src/sardana/macroserver/macros/expert.py index 15133c67ca..1fc807408f 100644 --- a/src/sardana/macroserver/macros/expert.py +++ b/src/sardana/macroserver/macros/expert.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -39,11 +39,11 @@ from sardana.macroserver.msparameter import WrongParam from sardana.macroserver.macro import Macro, Type, ParamRepeat, Table, LibraryError -################################################################################ +########################################################################## # # Configuration related macros # -################################################################################ +########################################################################## class defm(Macro): @@ -51,7 +51,7 @@ class defm(Macro): param_def = [['motor name', Type.String, None, 'motor name'], ['controller', Type.Controller, None, 'Controller name'], - ['axis', Type.Integer, None, 'motor axis'],] + ['axis', Type.Integer, None, 'motor axis'], ] def run(self, name, controller, axis): pool = controller.getPoolObj() @@ -60,6 +60,7 @@ def run(self, name, controller, axis): elem = pool.createElement(name, controller, axis) self.print("Created %s" % str(elem)) + class defmeas(Macro): """Create a new measurement group. First channel in channel_list MUST be an internal sardana channel. At least one channel MUST be a @@ -67,9 +68,10 @@ class defmeas(Macro): become the master).""" param_def = [ - ['name', Type.String, None, 'Measurement group name'], - ['channel_list', - ParamRepeat(['channel', Type.String, None, 'Measurement Channel'],), + ['name', Type.String, None, 'Measurement group name'], + ['channel_list', + ParamRepeat(['channel', Type.String, None, + 'Measurement Channel'],), None, 'List of measurement channels'], ] @@ -78,7 +80,8 @@ def prepare(self, name, channel_list, **opts): mntgrp_list = self.findObjs(name, type_class=Type.MeasurementGroup) if len(mntgrp_list) != 0: - raise Exception('A measurement group with that name already exists') + raise Exception( + 'A measurement group with that name already exists') def run(self, name, channel_list): channel0 = self.getObj(channel_list[0]) @@ -90,7 +93,8 @@ def run(self, name, channel_list): class udefmeas(Macro): """Deletes an existing measurement group""" - param_def = [ ['name', Type.MeasurementGroup, None, 'Measurement group name'],] + param_def = [['name', Type.MeasurementGroup, + None, 'Measurement group name'], ] def run(self, mntgrp): pool = mntgrp.getPoolObj() @@ -100,9 +104,9 @@ def run(self, mntgrp): class defelem(Macro): """Creates an element on a controller with an axis""" - param_def = [ ['name', Type.String, None, 'new element name'], - ['ctrl', Type.Controller, None, 'existing controller'], - ['axis', Type.Integer, -1, 'axis in the controller (default is -1, meaning add to the end)'],] + param_def = [['name', Type.String, None, 'new element name'], + ['ctrl', Type.Controller, None, 'existing controller'], + ['axis', Type.Integer, -1, 'axis in the controller (default is -1, meaning add to the end)'], ] def run(self, name, ctrl, axis): pool = ctrl.getPoolObj() @@ -115,8 +119,8 @@ def run(self, name, ctrl, axis): class renameelem(Macro): """Renames any type of Pool elements apart of Pools.""" - param_def = [ ['element', Type.PoolElement, None, 'element to be renamed'], - ['new_name', Type.String, None, 'new name']] + param_def = [['element', Type.PoolElement, None, 'element to be renamed'], + ['new_name', Type.String, None, 'new name']] def prepare(self, elem, new_name): if elem.getType() == "Pool": @@ -133,9 +137,9 @@ class udefelem(Macro): """Deletes an existing element(s)""" param_def = [ - ['elements', - ParamRepeat(['element', Type.Element, None, 'element name'], min=1), - None, 'List of element(s) name'], + ['elements', + ParamRepeat(['element', Type.Element, None, 'element name'], min=1), + None, 'List of element(s) name'], ] def run(self, elements): @@ -144,31 +148,30 @@ def run(self, elements): pool.deleteElement(element.getName()) - class defctrl(Macro): """Creates a new controller 'role_prop' is a sequence of roles and/or properties. - A role is defined as = (only applicable to pseudo controllers) - A property is defined as - + If both roles and properties are supplied, all roles must come before properties. All controller properties that don't have default values must be given. - + Example of creating a motor controller (with a host and port properties): - + [1]: defctrl SuperMotorController myctrl host homer.springfield.com port 5000 - + Example of creating a Slit pseudo motor (sl2t and sl2b motor roles, Gap and Offset pseudo motor roles): - + [1]: defctrl Slit myslit sl2t=mot01 sl2b=mot02 Gap=gap01 Offset=offset01""" - param_def = [ ['class', Type.ControllerClass, None, 'controller class'], - ['name', Type.String, None, 'new controller name'], - ['roles_props', - ParamRepeat(['role_prop', Type.String, None, - 'a role or property item'],min=0), - None, 'roles and/or properties'] ] + param_def = [['class', Type.ControllerClass, None, 'controller class'], + ['name', Type.String, None, 'new controller name'], + ['roles_props', + ParamRepeat(['role_prop', Type.String, None, + 'a role or property item'], min=0), + None, 'roles and/or properties']] def run(self, ctrl_class, name, props): pool = ctrl_class.getPoolObj() @@ -179,17 +182,18 @@ def run(self, ctrl_class, name, props): class udefctrl(Macro): """Deletes an existing controller""" - param_def = [ ['controller', Type.Controller, None, 'existing controller'],] + param_def = [['controller', Type.Controller, + None, 'existing controller'], ] def run(self, controller): pool = controller.getPoolObj() pool.deleteController(controller.getName()) -################################################################################ +########################################################################## # # Controller related macros # -################################################################################ +########################################################################## class send2ctrl(Macro): @@ -197,21 +201,23 @@ class send2ctrl(Macro): param_def = [['controller', Type.Controller, None, 'Controller name'], ['data', - ParamRepeat(['string item', Type.String, None, 'a string item'],), + ParamRepeat(['string item', Type.String, + None, 'a string item'],), None, 'data to be sent']] def run(self, controller, data): name = controller.getName() pool = controller.getPoolObj() str_data = " ".join(data) - res = pool.SendToController([name,str_data]) + res = pool.SendToController([name, str_data]) self.output(res) -################################################################################ +########################################################################## # # Library handling related macros # -################################################################################ +########################################################################## + class edctrl(Macro): """Returns the contents of the library file which contains the given @@ -225,27 +231,28 @@ class edctrl(Macro): ['filedata', Type.File, None, 'The file data object.'] ] - hints = { 'commit_cmd' : 'commit_ctrllib' } + hints = {'commit_cmd': 'commit_ctrllib'} - def run(self,ctrlclass): + def run(self, ctrlclass): f_name = ctrlclass.file pool = ctrlclass.getPool() data = pool.GetFile(f_name) - data = array.array('B',data).tostring() + data = array.array('B', data).tostring() line_nb = 1 for line in data.splitlines(): line = line.strip(' \t') - if line.startswith('class') and line.find(ctrlclass.name)>0 and \ - line.endswith(":"): + if line.startswith('class') and line.find(ctrlclass.name) > 0 and \ + line.endswith(":"): break line_nb = line_nb + 1 - return [f_name,data,line_nb] + return [f_name, data, line_nb] + class edctrllib(Macro): """Returns the contents of the given library file""" param_def = [ - ['filename', Type.Filename, None, 'Absolute path and file name or '\ + ['filename', Type.Filename, None, 'Absolute path and file name or ' 'simple filename. Relative paths are not allowed.'] ] @@ -253,12 +260,13 @@ class edctrllib(Macro): ['filedata', Type.File, None, 'The file data object'] ] - hints = { 'commit_cmd' : 'commit_ctrllib' } + hints = {'commit_cmd': 'commit_ctrllib'} - def run(self,filename): + def run(self, filename): pool = self.getManager().getPool() data = pool.GetFile(filename) - return [filename,array.array('B',data).tostring(),0] + return [filename, array.array('B', data).tostring(), 0] + class commit_ctrllib(Macro): """Puts the contents of the given data in a file inside the pool""" @@ -266,42 +274,42 @@ class commit_ctrllib(Macro): param_def = [ ['filename', Type.Filename, None, 'Absolute path and file name'], ['username', Type.User, None, 'The user name'], - ['comment', Type.String, None, 'A description of the changes made to '\ + ['comment', Type.String, None, 'A description of the changes made to ' 'the file'], ['filedata', Type.File, None, 'The file data object'] ] - def run(self,filename,username,comment,filedata): + def run(self, filename, username, comment, filedata): pool = self.getManager().getPool() meta = filename + '\0' + username + '\0' + comment + '\0' - data = array.array('B',meta) - data.extend(array.array('B',filedata)) + data = array.array('B', meta) + data.extend(array.array('B', filedata)) pool.PutFile(data.tolist()) -################################################################################ +########################################################################## # # Macro handling related macros # -################################################################################ +########################################################################## class prdef(Macro): """Returns the the macro code for the given macro name.""" param_def = [ - ['macro_name', Type.MacroCode, None, 'macro name'] + ['macro_name', Type.MacroCode, None, 'macro name'] ] - def run(self,macro_data): + def run(self, macro_data): code_lines, _ = macro_data.code for code_line in code_lines: self.output(code_line.strip('\n')) class rellib(Macro): - + """Reloads the given python library code from the macro server filesystem. - + .. warning:: use with extreme care! Accidentally reloading a system module or an installed python module may lead to unpredictable behavior @@ -332,12 +340,12 @@ def run(self, module_name): self.reloadLibrary(module_name) self.output("%s successfully (re)loaded", module_name) except LibraryError: - self.error("Cannot use rellib to reload a macro library. " \ + self.error("Cannot use rellib to reload a macro library. " "Use 'relmaclib' instead") except ImportError: msg = "".join(traceback.format_exception_only(*sys.exc_info()[:2])) self.error(msg) - + class relmaclib(Macro): """Reloads the given macro library code from the macro server filesystem.""" @@ -358,7 +366,8 @@ def run(self, macro_library): self.warning("The old %s macro library is still available.", name) else: macros = new_macro_library.get_macros() - self.output("%s successfully (re)loaded (found %d macros)", name, len(macros)) + self.output( + "%s successfully (re)loaded (found %d macros)", name, len(macros)) class addmaclib(Macro): @@ -370,7 +379,7 @@ class addmaclib(Macro): param_def = [ ['macro_library_name', Type.String, None, 'The module name to be loaded (without extension)'] - ] + ] def prepare(self, macro_library_name): try: @@ -399,7 +408,7 @@ def run(self, macro_library_name): overridden_macros = list(set(old_macros) & set(new_macros)) if len(overridden_macros) > 0: msg = ('%s macro library has overridden the following ' + - 'macros: %s' ) % (macro_library_name, overridden_macros) + 'macros: %s') % (macro_library_name, overridden_macros) self.warning(msg) @@ -425,7 +434,7 @@ def run(self, macro_code): maclibname = macro_library_name self.output("%s macro successfully (re)loaded", name) macros_in_lib = macro_library.get_macros() - self.output("\nAll macros from macro library %s have " + \ + self.output("\nAll macros from macro library %s have " + "been reloaded:", maclibname) self.output([macro.name for macro in macros_in_lib]) @@ -439,8 +448,8 @@ class sar_info(Macro): def run(self, obj): self.dump_properties(obj) - #self.output("") - #self.dump_attributes(obj) + # self.output("") + # self.dump_attributes(obj) def dump_properties(self, obj): data = obj.serialize() @@ -476,4 +485,3 @@ def dump_attributes(self, obj): self.output("-----------") for line in table.genOutput(): self.output(line) - diff --git a/src/sardana/macroserver/macros/hkl.py b/src/sardana/macroserver/macros/hkl.py index 2cde50e252..46eec21b3b 100644 --- a/src/sardana/macroserver/macros/hkl.py +++ b/src/sardana/macroserver/macros/hkl.py @@ -33,7 +33,8 @@ logger = Logger.getLogger("MacroManager") -logger.info("Diffractometer macros are at early stage. They can slightly change. Macro luppsi is not tested.") +logger.info( + "Diffractometer macros are at early stage. They can slightly change. Macro luppsi is not tested.") class _diffrac: @@ -172,6 +173,7 @@ def fl(self, ch, if mat: return regx.sub(repl, ch) + class br(Macro, _diffrac): """Move the diffractometer to the reciprocal space coordinates given by H, K and L. @@ -194,7 +196,9 @@ def prepare(self, H, K, L, AnglesIndex, FlagNotBlocking, FlagPrinting): _diffrac.prepare(self) def run(self, H, K, L, AnglesIndex, FlagNotBlocking, FlagPrinting): - h_idx = 0; k_idx = 1; l_idx = 2 + h_idx = 0 + k_idx = 1 + l_idx = 2 if AnglesIndex != -1: sel_tr = AnglesIndex @@ -290,7 +294,7 @@ def run(self, H, K, L, Trajectory): else: start_range = Trajectory end_range = Trajectory + 1 - + for i in range(int(start_range), int(end_range)): angles_list = self.diffrac.trajectorylist[i] self.output("") @@ -306,7 +310,7 @@ def run(self, H, K, L, Trajectory): except: self.warning( "Not able to read psi. Check if environment Psi is defined") - + self.output("Wavelength = %7.5f" % (self.diffrac.WaveLength)) self.output("") @@ -321,7 +325,7 @@ def run(self, H, K, L, Trajectory): self.output("%10s %11s %12s %11s %10s %11s" % (str_pos[self.labelmotor["Delta"]], str_pos[self.labelmotor["Theta"]], str_pos[self.labelmotor["Chi"]], str_pos[self.labelmotor["Phi"]], str_pos[self.labelmotor["Mu"]], str_pos[self.labelmotor["Gamma"]])) - + class ca(Macro, _diffrac): """Calculate motor positions for given H K L according to the current operation mode (trajectory 0).""" @@ -402,7 +406,7 @@ def prepare(self): _diffrac.prepare(self) def run(self): - + str_type = "Eulerian 6C" if self.type == 'E4CV': str_type = "Eulerian 4C Vertical" @@ -605,7 +609,6 @@ class setmode(iMacro, _diffrac): ['new_mode', Type.Integer, -1, "Mode to be set"] ] - def prepare(self, new_mode): _diffrac.prepare(self) @@ -675,7 +678,6 @@ class setlat(iMacro, _diffrac): ['gamma', Type.Float, -999, "Lattice 'gamma' parameter"] ] - def prepare(self, a, b, c, alpha, beta, gamma): _diffrac.prepare(self) @@ -1016,7 +1018,7 @@ def run(self): if reflections != None: if len(reflections) > 1: self.output("Computing UB with reflections 0 and 1") - values = [0,1] + values = [0, 1] self.diffrac.write_attribute("ComputeUB", values) self.execMacro('savecrystal') else: @@ -1082,7 +1084,6 @@ class newcrystal(iMacro, _diffrac): ['crystal_name', Type.String, "", 'Name of the crystal to add and select'] ] - def prepare(self, crystal_name): _diffrac.prepare(self) @@ -1165,7 +1166,8 @@ class hscan(aNscan, Macro, _diffrac): def prepare(self, start_pos, final_pos, nr_interv, integ_time): _diffrac.prepare(self) - aNscan._prepare(self, [self.h_device], [start_pos], [final_pos], nr_interv, integ_time) + aNscan._prepare(self, [self.h_device], [start_pos], [ + final_pos], nr_interv, integ_time) class kscan(aNscan, Macro, _diffrac): @@ -1180,7 +1182,8 @@ class kscan(aNscan, Macro, _diffrac): def prepare(self, start_pos, final_pos, nr_interv, integ_time): _diffrac.prepare(self) - aNscan._prepare(self, [self.k_device], [start_pos], [final_pos], nr_interv, integ_time) + aNscan._prepare(self, [self.k_device], [start_pos], [ + final_pos], nr_interv, integ_time) class lscan(aNscan, Macro, _diffrac): @@ -1195,7 +1198,8 @@ class lscan(aNscan, Macro, _diffrac): def prepare(self, start_pos, final_pos, nr_interv, integ_time): _diffrac.prepare(self) - aNscan._prepare(self, [self.l_device], [start_pos], [final_pos], nr_interv, integ_time) + aNscan._prepare(self, [self.l_device], [start_pos], [ + final_pos], nr_interv, integ_time) class hklscan(aNscan, Macro, _diffrac): @@ -1214,8 +1218,8 @@ class hklscan(aNscan, Macro, _diffrac): def prepare(self, h_start_pos, h_final_pos, k_start_pos, k_final_pos, l_start_pos, l_final_pos, nr_interv, integ_time): _diffrac.prepare(self) - aNscan._prepare(self, [self.h_device, self.k_device, self.l_device], [h_start_pos, k_start_pos, l_start_pos], [h_final_pos, k_final_pos, l_final_pos], nr_interv, integ_time) - + aNscan._prepare(self, [self.h_device, self.k_device, self.l_device], [ + h_start_pos, k_start_pos, l_start_pos], [h_final_pos, k_final_pos, l_final_pos], nr_interv, integ_time) class th2th(Macro): @@ -1386,7 +1390,7 @@ def run(self): if len(res) == 0: self.output("No crystals available in set directory. Nothing done") return - + i = 1 for filename in res: filename = filename.split('.')[0] @@ -1484,7 +1488,7 @@ def prepare(self, flagprint): _diffrac.prepare(self) def run(self, flagprint): - + moving = 1 tmp_dev = {} for angle in self.angle_names: @@ -1511,17 +1515,18 @@ class _diff_scan(Macro): This macro is internal and reserved to the hkl infrastucture. """ param_def = [ - ['motor', Type.Motor, None, 'Motor to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'], - ['channel', Type.ExpChannel, None, 'Channel to analize'] + ['motor', Type.Motor, None, 'Motor to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'], + ['channel', Type.ExpChannel, None, 'Channel to analize'] ] def run(self, motor, start_pos, final_pos, nr_interv, integ_time, channel): - ascan, pars= self.createMacro("ascan",motor, start_pos, final_pos, nr_interv, integ_time) + ascan, pars = self.createMacro( + "ascan", motor, start_pos, final_pos, nr_interv, integ_time) self.runMacro(ascan) channel_fullname = channel.getFullName() diff --git a/src/sardana/macroserver/macros/ioregister.py b/src/sardana/macroserver/macros/ioregister.py index 2d0fa1c2dc..5d93492b1e 100644 --- a/src/sardana/macroserver/macros/ioregister.py +++ b/src/sardana/macroserver/macros/ioregister.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -34,12 +34,12 @@ class write_ioreg(Macro): """Writes a value to an input register""" - + param_def = [ - ['input/output register', Type.IORegister, None, 'input/output register'], - ['data', Type.Integer, None, 'value to be send'] + ['input/output register', Type.IORegister, None, 'input/output register'], + ['data', Type.Integer, None, 'value to be send'] ] - + def run(self, ioreg, data): name = ioreg.getName() o = "Writing " + str(data) + " to " + name + " register " @@ -47,22 +47,21 @@ def run(self, ioreg, data): data = ioreg.writeIORegister(data) - class read_ioreg(Macro): """Reads an output register""" - + param_def = [ - ['input/output register', Type.IORegister, None, 'input/output register'] + ['input/output register', Type.IORegister, None, 'input/output register'] ] - + result_def = [ - ['input/output register value', Type.Integer, None, 'value read from ' + - 'the input/output register'] + ['input/output register value', Type.Integer, None, 'value read from ' + + 'the input/output register'] ] def run(self, ioreg): name = ioreg.getName() data = ioreg.readIORegister(force=True) - o = "Reading " + name + " register " + o = "Reading " + name + " register " self.debug(o) return data diff --git a/src/sardana/macroserver/macros/lists.py b/src/sardana/macroserver/macros/lists.py index 35d1cecb88..2a206ca489 100644 --- a/src/sardana/macroserver/macros/lists.py +++ b/src/sardana/macroserver/macros/lists.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -43,10 +43,12 @@ # List of elements related macros #~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + class _ls(Macro): param_def = [ ['filter', - ParamRepeat(['filter', Type.String, '.*', 'a regular expression filter'], min=1), + ParamRepeat(['filter', Type.String, '.*', + 'a regular expression filter'], min=1), '.*', 'a regular expression filter'], ] @@ -57,7 +59,7 @@ def get_column_names(self): col = col[0] cols.append(col) return cols - + def get_column_members(self): cols = [] for col in self.cols: @@ -65,18 +67,19 @@ def get_column_members(self): col = col[1] cols.append(col.lower()) return cols - + def run(self, *filter): - self.warning('This macro is not intended to be executed directly by ' \ + self.warning('This macro is not intended to be executed directly by ' 'the user') return + class lsdef(_ls): """List all macro definitions""" - cols = 'Name', 'Module', 'Brief Description' - width = -1, -1, -1 - align = Right, Right, Left + cols = 'Name', 'Module', 'Brief Description' + width = -1, -1, -1 + align = Right, Right, Left def run(self, filter): # TODO: passing a list causes TypeError: unhashable type: 'list' @@ -86,23 +89,23 @@ def run(self, filter): cols = self.get_column_names() out = List(cols, text_alignment=self.align, max_col_width=self.width) - + for m in self.getMacros(filter): if m.name.startswith("_"): continue out.appendRow([m.name, m.module_name, m.get_brief_description()]) - + for line in out.genOutput(): self.output(line) class _lsobj(_ls): - + subtype = Macro.All - cols = 'Name', 'Type', 'Controller', 'Axis'#, 'State' - width = -1, -1, -1, -1#, -1 - align = Right, Right, Right, Right#, Right + cols = 'Name', 'Type', 'Controller', 'Axis' # , 'State' + width = -1, -1, -1, -1 # , -1 + align = Right, Right, Right, Right # , Right def objs(self, filter): return self.findObjs(filter, type_class=self.type, subtype=self.subtype, @@ -120,7 +123,7 @@ def obj2Row(self, o, cols=None): value = '-----' ret.append(value) return ret - + def run(self, filter): objs = self.objs(filter) nb = len(objs) @@ -134,60 +137,70 @@ def run(self, filter): t = self.subtype.lower() self.output('No %ss defined' % t) return - + cols = self.get_column_names() out = List(cols, text_alignment=self.align, max_col_width=self.width) objs.sort() for obj in objs: try: - out.appendRow( self.obj2Row(obj) ) + out.appendRow(self.obj2Row(obj)) except: pass for line in out.genOutput(): self.output(line) - + class lsm(_lsobj): """Lists all motors""" type = Type.Moveable + class lspm(lsm): """Lists all existing motors""" subtype = 'PseudoMotor' + class lscom(_lsobj): """Lists all communication channels""" type = Type.ComChannel - + + class lsior(_lsobj): """Lists all IORegisters""" type = Type.IORegister + class lsexp(_lsobj): """Lists all experiment channels""" type = Type.ExpChannel - + + class lsct(lsexp): """Lists all Counter/Timers""" subtype = 'CTExpChannel' - + + class ls0d(lsexp): """Lists all 0D experiment channels""" subtype = 'ZeroDExpChannel' - + + class ls1d(lsexp): """Lists all 1D experiment channels""" subtype = 'OneDExpChannel' + class ls2d(lsexp): """Lists all 2D experiment channels""" subtype = 'TwoDExpChannel' + class lspc(lsexp): """Lists all pseudo counters""" subtype = 'PseudoCounter' - + + class lstg(_lsobj): """Lists all trigger/gate elements""" type = Type.TriggerGate @@ -196,32 +209,37 @@ class lstg(_lsobj): class lsctrllib(_lsobj): """Lists all existing controller classes""" type = Type.ControllerClass - cols = 'Name', ('Type', 'main_type'), ('Library', 'module'), ('Family','gender') + cols = 'Name', ('Type', 'main_type'), ('Library', + 'module'), ('Family', 'gender') + class lsctrl(_lsobj): """Lists all existing controllers""" type = Type.Controller cols = 'Name', ('Type', 'main_type'), ('Class', 'klass'), 'Module' + class lsi(_lsobj): """Lists all existing instruments""" type = Type.Instrument cols = 'Name', 'Type', ('Parent', 'parent_instrument') + class lsa(_lsobj): """Lists all existing objects""" type = Type.Moveable, Type.ComChannel, Type.ExpChannel, Type.IORegister,\ - Type.TriggerGate - + Type.TriggerGate + + class lsmeas(_lsobj): """List existing measurement groups""" type = Type.MeasurementGroup - cols = 'Active', 'Name', 'Timer', 'Experim. channels' - width = -1, -1, -1, 60 - align = HCenter, Right, Right, Left - + cols = 'Active', 'Name', 'Timer', 'Experim. channels' + width = -1, -1, -1, 60 + align = HCenter, Right, Right, Left + def prepare(self, filter, **opts): try: self.mnt_grp = self.getEnv('ActiveMntGrp').lower() or None @@ -235,14 +253,16 @@ def obj2Row(self, o): active = ' ' return active, o.name, o.getTimerName(), ", ".join(o.getChannelLabels()) + class lsmac(_lsobj): """Lists existing macros""" - + type = Type.MacroCode cols = 'Name', ('Location', 'file_path') + class lsmaclib(_lsobj): """Lists existing macro libraries.""" - + type = Type.MacroLibrary cols = 'Name', ('Location', 'file_path') diff --git a/src/sardana/macroserver/macros/mca.py b/src/sardana/macroserver/macros/mca.py index 9fa506af1b..2583057fd3 100644 --- a/src/sardana/macroserver/macros/mca.py +++ b/src/sardana/macroserver/macros/mca.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,28 +31,30 @@ import array + class mca_start(Macro): """Starts an mca""" - + param_def = [ - ['mca', Type.ExpChannel, None, 'mca'] + ['mca', Type.ExpChannel, None, 'mca'] ] - + def run(self, mca): name = mca.getName() mca.Start() - o = "Starting " + name + o = "Starting " + name self.output(o) + class mca_stop(Macro): """Stops an mca""" - + param_def = [ - ['mca', Type.ExpChannel, None, 'mca'] + ['mca', Type.ExpChannel, None, 'mca'] ] - + def run(self, mca): name = mca.getName() mca.Abort() - o = "Stopping " + name + o = "Stopping " + name self.output(o) diff --git a/src/sardana/macroserver/macros/scan.py b/src/sardana/macroserver/macros/scan.py index 788fe6a5e6..e395c5b8cc 100644 --- a/src/sardana/macroserver/macros/scan.py +++ b/src/sardana/macroserver/macros/scan.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -35,11 +35,11 @@ __all__ = ["a2scan", "a3scan", "a4scan", "amultiscan", "aNscan", "ascan", "d2scan", "d3scan", "d4scan", "dmultiscan", "dNscan", "dscan", - "fscan", "mesh", + "fscan", "mesh", "a2scanc", "a3scanc", "a4scanc", "ascanc", - "d2scanc", "d3scanc", "d4scanc", "dNScanc", "dscanc", - "meshc", - "a2scanct", "a3scanct", "a4scanct", "ascanct", + "d2scanc", "d3scanc", "d4scanc", "dNScanc", "dscanc", + "meshc", + "a2scanct", "a3scanct", "a4scanct", "ascanct", "scanhist", "getCallable", "UNCONSTRAINED"] __docformat__ = 'restructuredtext' @@ -61,80 +61,92 @@ from sardana.util.motion import Motor, MotionPath from sardana.util.tree import BranchNode, LeafNode, Tree -UNCONSTRAINED="unconstrained" +UNCONSTRAINED = "unconstrained" StepMode = 's' -ContinuousMode = 'c' #TODO: change it to be more verbose e.g. ContinuousSwMode +ContinuousMode = 'c' # TODO: change it to be more verbose e.g. ContinuousSwMode ContinuousHwTimeMode = 'ct' HybridMode = 'h' + def getCallable(repr): '''returns a function . Ideas: repr could be an URL for a file where the function is contained, or be evaluable code, or a pickled function object,... - + In any case, the return from it should be a callable of the form: f(x1,x2) where x1, x2 are points in the moveable space and the return value of f is True if the movement from x1 to x2 is allowed. False otherwise''' - if repr==UNCONSTRAINED: - return lambda x1,x2:True + if repr == UNCONSTRAINED: + return lambda x1, x2: True else: return lambda: None + class aNscan(Hookable): - - hints = { 'scan' : 'aNscan', 'allowsHooks': ('pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan') } + + hints = {'scan': 'aNscan', 'allowsHooks': ( + 'pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan')} #env = ('ActiveMntGrp',) - + """N-dimensional scan. This is **not** meant to be called by the user, but as a generic base to construct ascan, a2scan, a3scan,...""" + def _prepare(self, motorlist, startlist, endlist, scan_length, integ_time, mode=StepMode, latency_time=0, **opts): self.motors = motorlist - self.starts = numpy.array(startlist,dtype='d') - self.finals = numpy.array(endlist,dtype='d') + self.starts = numpy.array(startlist, dtype='d') + self.finals = numpy.array(endlist, dtype='d') self.mode = mode self.integ_time = integ_time self.opts = opts if len(self.motors) == self.starts.size == self.finals.size: self.N = self.finals.size else: - raise ValueError('Moveablelist, startlist and endlist must all be same length') + raise ValueError( + 'Moveablelist, startlist and endlist must all be same length') moveables = [] for m, start, final in zip(self.motors, self.starts, self.finals): - moveables.append(MoveableDesc(moveable=m, min_value=min(start,final), max_value=max(start,final))) + moveables.append(MoveableDesc(moveable=m, min_value=min( + start, final), max_value=max(start, final))) moveables[0].is_reference = True - env = opts.get('env',{}) - constrains = [getCallable(cns) for cns in opts.get('constrains',[UNCONSTRAINED])] - extrainfodesc = opts.get('extrainfodesc',[]) + env = opts.get('env', {}) + constrains = [getCallable(cns) for cns in opts.get( + 'constrains', [UNCONSTRAINED])] + extrainfodesc = opts.get('extrainfodesc', []) - #Hooks are not always set at this point. We will call getHooks later on in the scan_loop + # Hooks are not always set at this point. We will call getHooks later on in the scan_loop #self.pre_scan_hooks = self.getHooks('pre-scan') - #self.post_scan_hooks = self.getHooks('post-scan' - + # self.post_scan_hooks = self.getHooks('post-scan' + if mode == StepMode: self.nr_interv = scan_length - self.nr_points = self.nr_interv+1 - self.interv_sizes = ( self.finals - self.starts) / self.nr_interv - self.name = opts.get('name','a%iscan'%self.N) - self._gScan = SScan(self, self._stepGenerator, moveables, env, constrains, extrainfodesc) + self.nr_points = self.nr_interv + 1 + self.interv_sizes = (self.finals - self.starts) / self.nr_interv + self.name = opts.get('name', 'a%iscan' % self.N) + self._gScan = SScan(self, self._stepGenerator, + moveables, env, constrains, extrainfodesc) elif mode in [ContinuousMode, ContinuousHwTimeMode]: - #TODO: probably not 100% correct, + # TODO: probably not 100% correct, # the idea is to allow passing a list of waypoints - if isinstance(endlist[0],list): + if isinstance(endlist[0], list): self.waypoints = self.finals else: self.waypoints = [self.finals] self.nr_waypoints = len(self.waypoints) - if mode == ContinuousMode: + if mode == ContinuousMode: self.slow_down = scan_length - self.nr_waypoints = 2 #aNscans will only have two waypoints (the start and the final positions) - self.way_lengths = ( self.finals - self.starts) / (self.nr_waypoints -1) - self.name = opts.get('name','a%iscanc'%self.N) - self._gScan = CSScan(self, self._waypoint_generator, self._period_generator, moveables, env, constrains, extrainfodesc) + # aNscans will only have two waypoints (the start and the final + # positions) + self.nr_waypoints = 2 + self.way_lengths = ( + self.finals - self.starts) / (self.nr_waypoints - 1) + self.name = opts.get('name', 'a%iscanc' % self.N) + self._gScan = CSScan(self, self._waypoint_generator, + self._period_generator, moveables, env, constrains, extrainfodesc) elif mode == ContinuousHwTimeMode: self.nr_interv = scan_length self.nr_of_points = self.nr_interv + 1 @@ -146,36 +158,38 @@ def _prepare(self, motorlist, startlist, endlist, scan_length, integ_time, mg_latency_time) latency_time = mg_latency_time self.latency_time = latency_time - self.name = opts.get('name','a%iscanct'%self.N) - self._gScan = CTScan(self, self._waypoint_generator_hwtime, - moveables, - env, - constrains, - extrainfodesc) + self.name = opts.get('name', 'a%iscanct' % self.N) + self._gScan = CTScan(self, self._waypoint_generator_hwtime, + moveables, + env, + constrains, + extrainfodesc) elif mode == HybridMode: self.nr_interv = scan_length - self.nr_points = self.nr_interv+1 - self.interv_sizes = ( self.finals - self.starts) / self.nr_interv - self.name = opts.get('name','a%iscanh'%self.N) - self._gScan = HScan(self, self._stepGenerator, moveables, env, constrains, extrainfodesc) + self.nr_points = self.nr_interv + 1 + self.interv_sizes = (self.finals - self.starts) / self.nr_interv + self.name = opts.get('name', 'a%iscanh' % self.N) + self._gScan = HScan(self, self._stepGenerator, + moveables, env, constrains, extrainfodesc) else: raise ValueError('invalid value for mode %s' % mode) - + def _stepGenerator(self): step = {} - step["integ_time"] = self.integ_time + step["integ_time"] = self.integ_time step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["pre-acq-hooks"] = self.getHooks('pre-acq') - step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') + step[ + "post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') - + step["check_func"] = [] for point_no in xrange(self.nr_points): step["positions"] = self.starts + point_no * self.interv_sizes step["point_id"] = point_no yield step - + def _waypoint_generator(self): step = {} step["pre-move-hooks"] = self.getHooks('pre-move') @@ -186,9 +200,9 @@ def _waypoint_generator(self): step["positions"] = self.starts + point_no * self.way_lengths step["waypoint_id"] = point_no yield step - + def _waypoint_generator_hwtime(self): - #TODO: remove starts + # TODO: remove starts def calculate_positions(moveable_node, start, end): '''Function to calculate starting and ending positions on the physical motors level. @@ -197,7 +211,7 @@ def calculate_positions(moveable_node, start, end): or a LeafNode representing a PhysicalMotor). :param start: (float) starting position of the moveable :param end: (float) ending position of the moveable - + :return: (list<(float,float)>) a list of tuples comprising starting and ending positions. List order is important and preserved.''' start_positions = [] @@ -209,24 +223,26 @@ def calculate_positions(moveable_node, start, end): starts = moveable.calcPhysical(start) ends = moveable.calcPhysical(end) for moveable_node, start, end in zip(moveable_nodes, starts, - ends): + ends): _start_positions, _end_positions = calculate_positions( - moveable_node, - start, end) + moveable_node, + start, end) start_positions += _start_positions end_positions += _end_positions else: start_positions = [start] end_positions = [end] - + return start_positions, end_positions - - #CScan in its constructor populates a list of data structures - trees. - #Each tree represent one Moveables with its hierarchy of inferior moveables. - moveables_trees = self._gScan.get_moveables_trees() + + # CScan in its constructor populates a list of data structures - trees. + # Each tree represent one Moveables with its hierarchy of inferior + # moveables. + moveables_trees = self._gScan.get_moveables_trees() step = {} step["pre-move-hooks"] = self.getHooks('pre-move') - post_move_hooks = self.getHooks('post-move') + [self._fill_missing_records] + post_move_hooks = self.getHooks( + 'post-move') + [self._fill_missing_records] step["post-move-hooks"] = post_move_hooks step["check_func"] = [] step["active_time"] = self.nr_of_points * (self.integ_time + @@ -235,21 +251,23 @@ def calculate_positions(moveable_node, start, end): step["start_positions"] = [] starts = self.starts for point_no, waypoint in enumerate(self.waypoints): - for start, end, moveable_tree in zip(starts, waypoint, + for start, end, moveable_tree in zip(starts, waypoint, moveables_trees): moveable_root = moveable_tree.root() - start_positions, end_positions = calculate_positions(moveable_root, start, end) + start_positions, end_positions = calculate_positions( + moveable_root, start, end) step["start_positions"] += start_positions step["positions"] += end_positions step["waypoint_id"] = point_no starts = waypoint yield step - + def _period_generator(self): step = {} - step["integ_time"] = self.integ_time + step["integ_time"] = self.integ_time step["pre-acq-hooks"] = self.getHooks('pre-acq') - step["post-acq-hooks"] = self.getHooks('post-acq')+self.getHooks('_NOHINTS_') + step[ + "post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] step['extrainfo'] = {} @@ -258,15 +276,15 @@ def _period_generator(self): point_no += 1 step["point_id"] = point_no yield step - - def run(self,*args): + + def run(self, *args): for step in self._gScan.step_scan(): yield step - + @property def data(self): return self._gScan.data - + def getTimeEstimation(self): gScan = self._gScan mode = self.mode @@ -282,7 +300,7 @@ def getTimeEstimation(self): for v_motor, start, stop, length in zip(v_motors, curr_pos, step0['positions'], self.interv_sizes): path0 = MotionPath(v_motor, start, stop) path = MotionPath(v_motor, 0, length) - max_step0_time = max(max_step0_time, path0.duration) + max_step0_time = max(max_step0_time, path0.duration) max_step_time = max(max_step_time, path.duration) motion_time = max_step0_time + self.nr_interv * max_step_time # calculate acquisition time @@ -291,9 +309,9 @@ def getTimeEstimation(self): elif mode == ContinuousMode: total_time = gScan.waypoint_estimation() - #TODO: add time estimation for ContinuousHwTimeMode + # TODO: add time estimation for ContinuousHwTimeMode return total_time - + def getIntervalEstimation(self): mode = self.mode if mode == StepMode: @@ -309,6 +327,7 @@ def _fill_missing_records(self): missing_records = nb_of_points - nb_of_records scan.data.initRecords(missing_records) + class dNscan(aNscan): '''same as aNscan but it interprets the positions as being relative to the current positions and upon completion, it returns the motors to their @@ -318,18 +337,20 @@ class dNscan(aNscan): hints['scan'] = 'dNscan' def _prepare(self, motorlist, startlist, endlist, scan_length, integ_time, mode=StepMode, **opts): - self._motion=self.getMotion( [ m.getName() for m in motorlist] ) - self.originalPositions = numpy.array(self._motion.readPosition(force=True)) + self._motion = self.getMotion([m.getName() for m in motorlist]) + self.originalPositions = numpy.array( + self._motion.readPosition(force=True)) starts = numpy.array(startlist, dtype='d') + self.originalPositions finals = numpy.array(endlist, dtype='d') + self.originalPositions - aNscan._prepare(self, motorlist, starts, finals, scan_length, integ_time, mode=mode, **opts) - + aNscan._prepare(self, motorlist, starts, finals, + scan_length, integ_time, mode=mode, **opts) + def do_restore(self): self.info("Returning to start positions...") self._motion.move(self.originalPositions) -class ascan(aNscan, Macro): +class ascan(aNscan, Macro): """Do an absolute scan of the specified motor. ascan scans one motor, as specified by motor. The motor starts at the position given by start_pos and ends at the position given by final_pos. @@ -338,19 +359,20 @@ class ascan(aNscan, Macro): specifies seconds and if negative, specifies monitor counts. """ param_def = [ - ['motor', Type.Moveable, None, 'Moveable to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor', Type.Moveable, None, 'Moveable to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): - self._prepare([motor], [start_pos], [final_pos], nr_interv, integ_time, **opts) - + self._prepare([motor], [start_pos], [final_pos], + nr_interv, integ_time, **opts) -class a2scan(aNscan, Macro): + +class a2scan(aNscan, Macro): """two-motor scan. a2scan scans two motors, as specified by motor1 and motor2. Each motor moves the same number of intervals with starting and ending @@ -360,22 +382,23 @@ class a2scan(aNscan, Macro): Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor1, start_pos1, final_pos1, motor2, start_pos2, final_pos2, nr_interv, integ_time, **opts): - self._prepare([motor1,motor2], [start_pos1,start_pos2], [final_pos1,final_pos2], nr_interv, integ_time, **opts) + self._prepare([motor1, motor2], [start_pos1, start_pos2], [ + final_pos1, final_pos2], nr_interv, integ_time, **opts) -class a3scan(aNscan, Macro): +class a3scan(aNscan, Macro): """three-motor scan . a3scan scans three motors, as specified by motor1, motor2 and motor3. Each motor moves the same number of intervals with starting and ending @@ -386,25 +409,26 @@ class a3scan(aNscan, Macro): Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, nr_interv, integ_time, **opts): - self._prepare([m1,m2,m3], [s1,s2,s3], [f1,f2,f3], nr_interv, integ_time, **opts) + self._prepare([m1, m2, m3], [s1, s2, s3], [f1, f2, f3], + nr_interv, integ_time, **opts) -class a4scan(aNscan, Macro): +class a4scan(aNscan, Macro): """four-motor scan . a4scan scans four motors, as specified by motor1, motor2, motor3 and motor4. Each motor moves the same number of intervals with starting and ending @@ -414,28 +438,29 @@ class a4scan(aNscan, Macro): Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['motor4', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos4', Type.Float, None, 'Scan start position 3'], - ['final_pos4', Type.Float, None, 'Scan final position 3'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['motor4', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos4', Type.Float, None, 'Scan start position 3'], + ['final_pos4', Type.Float, None, 'Scan final position 3'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, nr_interv, integ_time, **opts): - self._prepare([m1,m2,m3,m4], [s1,s2,s3,s4], [f1,f2,f3,f4], nr_interv, integ_time, **opts) + self._prepare([m1, m2, m3, m4], [s1, s2, s3, s4], [ + f1, f2, f3, f4], nr_interv, integ_time, **opts) -class amultiscan(aNscan, Macro): +class amultiscan(aNscan, Macro): '''Multiple motor scan. amultiscan scans N motors, as specified by motor1, motor2,...,motorN. Each motor moves the same number of intervals with starting and ending @@ -447,25 +472,26 @@ class amultiscan(aNscan, Macro): ''' param_def = [ - ['motor_start_end_list', - ParamRepeat(['motor', Type.Moveable, None, 'Moveable to move'], - ['start', Type.Float, None, 'Starting position'], - ['end', Type.Float, None, 'Final position']), - None, 'List of motor, start and end positions'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor_start_end_list', + ParamRepeat(['motor', Type.Moveable, None, 'Moveable to move'], + ['start', Type.Float, None, 'Starting position'], + ['end', Type.Float, None, 'Final position']), + None, 'List of motor, start and end positions'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] - + def prepare(self, *args, **opts): motors = args[0:-2:3] starts = args[1:-2:3] - ends = args[2:-2:3] + ends = args[2:-2:3] nr_interv = args[-2] integ_time = args[-1] - + self._prepare(motors, starts, ends, nr_interv, integ_time, **opts) -class dmultiscan(dNscan, Macro): + +class dmultiscan(dNscan, Macro): '''Multiple motor scan relative to the starting positions. dmultiscan scans N motors, as specified by motor1, motor2,...,motorN. Each motor moves the same number of intervals If each motor is at a @@ -477,26 +503,26 @@ class dmultiscan(dNscan, Macro): if negative, specifies monitor counts.""" ''' param_def = [ - ['motor_start_end_list', - ParamRepeat(['motor', Type.Moveable, None, 'Moveable to move'], - ['start', Type.Float, None, 'Starting position'], - ['end', Type.Float, None, 'Final position']), - None, 'List of motor, start and end positions'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor_start_end_list', + ParamRepeat(['motor', Type.Moveable, None, 'Moveable to move'], + ['start', Type.Float, None, 'Starting position'], + ['end', Type.Float, None, 'Final position']), + None, 'List of motor, start and end positions'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] - + def prepare(self, *args, **opts): motors = args[0:-2:3] starts = args[1:-2:3] - ends = args[2:-2:3] + ends = args[2:-2:3] nr_interv = args[-2] integ_time = args[-1] - + self._prepare(motors, starts, ends, nr_interv, integ_time, **opts) -class dscan(dNscan, Macro): +class dscan(dNscan, Macro): """motor scan relative to the starting position. dscan scans one motor, as specified by motor. If motor motor is at a position X before the scan begins, it will be scanned from X+start_pos @@ -506,19 +532,20 @@ class dscan(dNscan, Macro): specifies monitor counts. """ param_def = [ - ['motor', Type.Moveable, None, 'Moveable to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor', Type.Moveable, None, 'Moveable to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, **opts): - self._prepare([motor], [start_pos], [final_pos], nr_interv, integ_time, **opts) + self._prepare([motor], [start_pos], [final_pos], + nr_interv, integ_time, **opts) -class d2scan(dNscan,Macro): +class d2scan(dNscan, Macro): """two-motor scan relative to the starting position. d2scan scans two motors, as specified by motor1 and motor2. Each motor moves the same number of intervals. If each motor is at a @@ -529,22 +556,23 @@ class d2scan(dNscan,Macro): Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor1, start_pos1, final_pos1, motor2, start_pos2, final_pos2, nr_interv, integ_time, **opts): - self._prepare([motor1,motor2], [start_pos1,start_pos2], [final_pos1,final_pos2], nr_interv, integ_time, **opts) + self._prepare([motor1, motor2], [start_pos1, start_pos2], [ + final_pos1, final_pos2], nr_interv, integ_time, **opts) -class d3scan(dNscan, Macro): +class d3scan(dNscan, Macro): """three-motor scan . d3scan scans three motors, as specified by motor1, motor2 and motor3. Each motor moves the same number of intervals. If each motor is at a @@ -555,25 +583,26 @@ class d3scan(dNscan, Macro): Count time is given by time which if positive, specifies seconds and if negative, specifies monitor counts.""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, nr_interv, integ_time, **opts): - self._prepare([m1,m2,m3], [s1,s2,s3], [f1,f2,f3], nr_interv, integ_time, **opts) - + self._prepare([m1, m2, m3], [s1, s2, s3], [f1, f2, f3], + nr_interv, integ_time, **opts) + -class d4scan(dNscan, Macro): +class d4scan(dNscan, Macro): """four-motor scan relative to the starting positions a4scan scans four motors, as specified by motor1, motor2, motor3 and motor4. Each motor moves the same number of intervals. If each motor is at a @@ -586,28 +615,29 @@ class d4scan(dNscan, Macro): Upon termination, the motors are returned to their starting positions. """ param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['motor4', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos4', Type.Float, None, 'Scan start position 3'], - ['final_pos4', Type.Float, None, 'Scan final position 3'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['motor4', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos4', Type.Float, None, 'Scan start position 3'], + ['final_pos4', Type.Float, None, 'Scan final position 3'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, nr_interv, integ_time, **opts): - self._prepare([m1,m2,m3,m4], [s1,s2,s3,s4], [f1,f2,f3,f4], nr_interv, integ_time, **opts) - + self._prepare([m1, m2, m3, m4], [s1, s2, s3, s4], [ + f1, f2, f3, f4], nr_interv, integ_time, **opts) + -class mesh(Macro,Hookable): +class mesh(Macro, Hookable): """2d grid scan . The mesh scan traces out a grid using motor1 and motor2. The first motor scans from m1_start_pos to m1_final_pos using the specified @@ -617,73 +647,77 @@ class mesh(Macro,Hookable): The scan of motor1 is done at each point scanned by motor2. That is, the first motor scan is nested within the second motor scan. """ - - hints = { 'scan' : 'mesh', 'allowsHooks': ('pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan') } + + hints = {'scan': 'mesh', 'allowsHooks': ( + 'pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan')} env = ('ActiveMntGrp',) - + param_def = [ - ['motor1', Type.Moveable, None, 'First motor to move'], - ['m1_start_pos',Type.Float, None, 'Scan start position for first motor'], - ['m1_final_pos',Type.Float, None, 'Scan final position for first motor'], - ['m1_nr_interv',Type.Integer, None, 'Number of scan intervals'], - ['motor2', Type.Moveable, None, 'Second motor to move'], - ['m2_start_pos',Type.Float, None, 'Scan start position for second motor'], - ['m2_final_pos',Type.Float, None, 'Scan final position for second motor'], - ['m2_nr_interv',Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'], - ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] + ['motor1', Type.Moveable, None, 'First motor to move'], + ['m1_start_pos', Type.Float, None, 'Scan start position for first motor'], + ['m1_final_pos', Type.Float, None, 'Scan final position for first motor'], + ['m1_nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['motor2', Type.Moveable, None, 'Second motor to move'], + ['m2_start_pos', Type.Float, None, 'Scan start position for second motor'], + ['m2_final_pos', Type.Float, None, 'Scan final position for second motor'], + ['m2_nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'], + ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] ] def prepare(self, m1, m1_start_pos, m1_final_pos, m1_nr_interv, m2, m2_start_pos, m2_final_pos, m2_nr_interv, integ_time, bidirectional, **opts): - self.motors=[m1,m2] - self.starts = numpy.array([m1_start_pos,m2_start_pos],dtype='d') - self.finals = numpy.array([m1_final_pos,m2_final_pos],dtype='d') - self.nr_intervs= numpy.array([m1_nr_interv, m2_nr_interv],dtype='i') + self.motors = [m1, m2] + self.starts = numpy.array([m1_start_pos, m2_start_pos], dtype='d') + self.finals = numpy.array([m1_final_pos, m2_final_pos], dtype='d') + self.nr_intervs = numpy.array([m1_nr_interv, m2_nr_interv], dtype='i') self.integ_time = integ_time self.bidirectional_mode = bidirectional - - self.name=opts.get('name','mesh') - - generator=self._generator - moveables=self.motors - env=opts.get('env',{}) - constrains=[getCallable(cns) for cns in opts.get('constrains',[UNCONSTRAINED])] - - #Hooks are not always set at this point. We will call getHooks later on in the scan_loop + + self.name = opts.get('name', 'mesh') + + generator = self._generator + moveables = self.motors + env = opts.get('env', {}) + constrains = [getCallable(cns) for cns in opts.get( + 'constrains', [UNCONSTRAINED])] + + # Hooks are not always set at this point. We will call getHooks later on in the scan_loop #self.pre_scan_hooks = self.getHooks('pre-scan') #self.post_scan_hooks = self.getHooks('post-scan') - self._gScan=SScan(self, generator, moveables, env, constrains) + self._gScan = SScan(self, generator, moveables, env, constrains) def _generator(self): step = {} - step["integ_time"] = self.integ_time + step["integ_time"] = self.integ_time step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["pre-acq-hooks"] = self.getHooks('pre-acq') - step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') + step[ + "post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] - m1start,m2start=self.starts - m1end,m2end=self.finals - points1,points2=self.nr_intervs+1 - point_no=1 - m1_space = numpy.linspace(m1start,m1end,points1) - m1_space_inv = numpy.linspace(m1end,m1start,points1) - - for i, m2pos in enumerate(numpy.linspace(m2start,m2end,points2)): + m1start, m2start = self.starts + m1end, m2end = self.finals + points1, points2 = self.nr_intervs + 1 + point_no = 1 + m1_space = numpy.linspace(m1start, m1end, points1) + m1_space_inv = numpy.linspace(m1end, m1start, points1) + + for i, m2pos in enumerate(numpy.linspace(m2start, m2end, points2)): space = m1_space if i % 2 != 0 and self.bidirectional_mode: space = m1_space_inv for m1pos in space: - step["positions"] = numpy.array([m1pos,m2pos]) - step["point_id"]= point_no #TODO: maybe another ID would be better? (e.g. "(A,B)") - point_no+=1 + step["positions"] = numpy.array([m1pos, m2pos]) + # TODO: maybe another ID would be better? (e.g. "(A,B)") + step["point_id"] = point_no + point_no += 1 yield step - - def run(self,*args): + + def run(self, *args): for step in self._gScan.step_scan(): yield step @@ -691,7 +725,8 @@ def run(self,*args): def data(self): return self._gScan.data -class dmesh(mesh): + +class dmesh(mesh): '''2d relative grid scan. The relative mesh scan traces out a grid using motor1 and motor2. If first motor is at the position X before the scan begins, it will @@ -711,37 +746,39 @@ class dmesh(mesh): hints['scan'] = 'dmesh' env = copy.deepcopy(mesh.env) - + param_def = [ - ['motor1', Type.Moveable, None, 'First motor to move'], - ['m1_start_pos',Type.Float, None, 'Scan start position for first motor'], - ['m1_final_pos',Type.Float, None, 'Scan final position for first motor'], - ['m1_nr_interv',Type.Integer, None, 'Number of scan intervals'], - ['motor2', Type.Moveable, None, 'Second motor to move'], - ['m2_start_pos',Type.Float, None, 'Scan start position for second motor'], - ['m2_final_pos',Type.Float, None, 'Scan final position for second motor'], - ['m2_nr_interv',Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'], - ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] + ['motor1', Type.Moveable, None, 'First motor to move'], + ['m1_start_pos', Type.Float, None, 'Scan start position for first motor'], + ['m1_final_pos', Type.Float, None, 'Scan final position for first motor'], + ['m1_nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['motor2', Type.Moveable, None, 'Second motor to move'], + ['m2_start_pos', Type.Float, None, 'Scan start position for second motor'], + ['m2_final_pos', Type.Float, None, 'Scan final position for second motor'], + ['m2_nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'], + ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] ] def prepare(self, m1, m1_start_pos, m1_final_pos, m1_nr_interv, m2, m2_start_pos, m2_final_pos, m2_nr_interv, integ_time, bidirectional, **opts): - self._motion=self.getMotion( [m1,m2] ) - self.originalPositions = numpy.array(self._motion.readPosition(force=True)) - start1 = self.originalPositions[0] + m1_start_pos - start2 = self.originalPositions[1] + m2_start_pos - final1 = self.originalPositions[0] + m1_final_pos - final2 = self.originalPositions[1] + m2_final_pos + self._motion = self.getMotion([m1, m2]) + self.originalPositions = numpy.array( + self._motion.readPosition(force=True)) + start1 = self.originalPositions[0] + m1_start_pos + start2 = self.originalPositions[1] + m2_start_pos + final1 = self.originalPositions[0] + m1_final_pos + final2 = self.originalPositions[1] + m2_final_pos mesh.prepare(self, m1, start1, final1, m1_nr_interv, - m2, start2, final2, m2_nr_interv, integ_time, - bidirectional, **opts) + m2, start2, final2, m2_nr_interv, integ_time, + bidirectional, **opts) def do_restore(self): self.info("Returning to start positions...") self._motion.move(self.originalPositions) + class fscan(Macro, Hookable): '''N-dimensional scan along user defined paths. The motion path for each motor is defined through the evaluation of a @@ -790,8 +827,10 @@ def prepare(self, *args, **opts): self.motors = [item[0] for item in args[2]] self.funcstrings = [item[1] for item in args[2]] - globals_lst = [dict(zip(indepvars, values)) for values in zip(*indepvars.values())] - self.paths = [[SafeEvaluator(globals).eval(func) for globals in globals_lst] for func in self.funcstrings] + globals_lst = [dict(zip(indepvars, values)) + for values in zip(*indepvars.values())] + self.paths = [[SafeEvaluator(globals).eval( + func) for globals in globals_lst] for func in self.funcstrings] self.integ_time = numpy.array(eval(args[1]), dtype='d') @@ -799,12 +838,14 @@ def prepare(self, *args, **opts): if len(self.motors) == len(self.paths) > 0: self.N = len(self.motors) else: - raise ValueError('Moveable and func lists must be non-empty and same length') + raise ValueError( + 'Moveable and func lists must be non-empty and same length') npoints = len(self.paths[0]) try: # if everything is OK, the following lines should return a 2D array # n which each motor path is a row. - # Typical failure is due to shape mismatch due to inconsistent input + # Typical failure is due to shape mismatch due to inconsistent + # input self.paths = numpy.array(self.paths, dtype='d') self.paths.reshape((self.N, npoints)) except: # shape mismatch? @@ -818,16 +859,19 @@ def prepare(self, *args, **opts): self.nr_points = npoints if self.integ_time.size == 1: - self.integ_time = self.integ_time * numpy.ones(self.nr_points) # extend integ_time + self.integ_time = self.integ_time * \ + numpy.ones(self.nr_points) # extend integ_time elif self.integ_time.size != self.nr_points: - raise ValueError('time_integ must either be a scalar or length=npoints (%i)' % self.nr_points) + raise ValueError( + 'time_integ must either be a scalar or length=npoints (%i)' % self.nr_points) self.name = opts.get('name', 'fscan') generator = self._generator moveables = self.motors env = opts.get('env', {}) - constrains = [getCallable(cns) for cns in opts.get('constrains', [UNCONSTRAINED])] + constrains = [getCallable(cns) for cns in opts.get( + 'constrains', [UNCONSTRAINED])] # Hooks are not always set at this point. We will call getHooks later on in the scan_loop # self.pre_scan_hooks = self.getHooks('pre-scan') @@ -840,7 +884,8 @@ def _generator(self): step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["pre-acq-hooks"] = self.getHooks('pre-acq') - step["post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') + step[ + "post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] @@ -858,7 +903,8 @@ def run(self, *args): def data(self): return self._gScan.data -class ascanh(aNscan, Macro): + +class ascanh(aNscan, Macro): """Do an absolute scan of the specified motor. ascan scans one motor, as specified by motor. The motor starts at the position given by start_pos and ends at the position given by final_pos. @@ -867,11 +913,11 @@ class ascanh(aNscan, Macro): specifies seconds and if negative, specifies monitor counts. """ param_def = [ - ['motor', Type.Moveable, None, 'Moveable to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'] + ['motor', Type.Moveable, None, 'Moveable to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'] ] def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, @@ -883,12 +929,12 @@ def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, class scanhist(Macro): """Shows scan history information. Give optional parameter scan number to display details about a specific scan""" - + param_def = [ - ['scan number', Type.Integer, -1, - 'scan number. [default=-1 meaning show all scans]'], + ['scan number', Type.Integer, -1, + 'scan number. [default=-1 meaning show all scans]'], ] - + def run(self, scan_number): try: hist = self.getEnv("ScanHistory") @@ -899,7 +945,7 @@ def run(self, scan_number): self.show_all(hist) else: self.show_one(hist, scan_number) - + def show_one(self, hist, scan_number): item = None for h in hist: @@ -909,7 +955,7 @@ def show_one(self, hist, scan_number): if item is None: self.warning("Could not find scan number %s", scan_number) return - + serialno, title = h['serialno'], h['title'] start = datetime.datetime.fromtimestamp(h['startts']) end = datetime.datetime.fromtimestamp(h['endts']) @@ -917,7 +963,7 @@ def show_one(self, hist, scan_number): start, end, total_time = start.ctime(), end.ctime(), str(total_time) scan_dir, scan_file = h['ScanDir'], h['ScanFile'] deadtime = '%.1f%%' % h['deadtime'] - + user = h['user'] store = "Not stored!" if scan_dir is not None and scan_file is not None: @@ -925,23 +971,23 @@ def show_one(self, hist, scan_number): store = os.path.join(scan_dir, scan_file) else: store = scan_dir + os.path.sep + str(scan_file) - + channels = ", ".join(h['channels']) cols = ["#", "Title", "Start time", "End time", "Took", "Dead time", - "User", "Stored", "Channels" ] + "User", "Stored", "Channels"] data = [serialno, title, start, end, total_time, deadtime, user, store, channels] - + table = Table([data], row_head_str=cols, row_head_fmt='%*s', elem_fmt=['%-*s'], col_sep=' : ') for line in table.genOutput(): self.output(line) - + def show_all(self, hist): - - cols = "#", "Title", "Start time", "End time", "Stored" - width = -1, -1, -1, -1, -1 + + cols = "#", "Title", "Start time", "End time", "Stored" + width = -1, -1, -1, -1, -1 out = List(cols, max_col_width=width) today = datetime.datetime.today().date() for h in hist: @@ -963,18 +1009,18 @@ def show_all(self, hist): out.appendRow(row) for line in out.genOutput(): self.output(line) - -class ascanc(aNscan, Macro): + +class ascanc(aNscan, Macro): """Do an absolute continuous scan of the specified motor. ascanc scans one motor, as specified by motor.""" param_def = [ - ['motor', Type.Moveable, None, 'Moveable to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['integ_time', Type.Float, None, 'Integration time'], - ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], + ['motor', Type.Moveable, None, 'Moveable to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['integ_time', Type.Float, None, 'Integration time'], + ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, motor, start_pos, final_pos, integ_time, slow_down, @@ -983,17 +1029,17 @@ def prepare(self, motor, start_pos, final_pos, integ_time, slow_down, integ_time, mode=ContinuousMode, **opts) -class a2scanc(aNscan, Macro): +class a2scanc(aNscan, Macro): """two-motor continuous scan""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['integ_time', Type.Float, None, 'Integration time'], - ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['integ_time', Type.Float, None, 'Integration time'], + ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, motor1, start_pos1, final_pos1, motor2, start_pos2, @@ -1003,54 +1049,55 @@ def prepare(self, motor1, start_pos1, final_pos1, motor2, start_pos2, mode=ContinuousMode, **opts) -class a3scanc(aNscan, Macro): +class a3scanc(aNscan, Macro): """three-motor continuous scan""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['integ_time', Type.Float, None, 'Integration time'], - ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['integ_time', Type.Float, None, 'Integration time'], + ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, integ_time, slow_down, **opts): - self._prepare([m1,m2,m3], [s1,s2,s3], [f1,f2,f3], slow_down, + self._prepare([m1, m2, m3], [s1, s2, s3], [f1, f2, f3], slow_down, integ_time, mode=ContinuousMode, **opts) -class a4scanc(aNscan, Macro): + +class a4scanc(aNscan, Macro): """four-motor continuous scan""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['motor4', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos4', Type.Float, None, 'Scan start position 3'], - ['final_pos4', Type.Float, None, 'Scan final position 3'], - ['integ_time', Type.Float, None, 'Integration time'], - ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['motor4', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos4', Type.Float, None, 'Scan start position 3'], + ['final_pos4', Type.Float, None, 'Scan final position 3'], + ['integ_time', Type.Float, None, 'Integration time'], + ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, integ_time, slow_down, **opts): - self._prepare([m1,m2,m3,m4], [s1,s2,s3,s4], [f1,f2,f3,f4], slow_down, + self._prepare([m1, m2, m3, m4], [s1, s2, s3, s4], [f1, f2, f3, f4], slow_down, integ_time, mode=ContinuousMode, **opts) class dNscanc(dNscan): - + def do_restore(self): # set velocities to maximum and then move to initial positions for moveable in self.motors: @@ -1058,164 +1105,174 @@ def do_restore(self): dNscan.do_restore(self) -class dscanc(dNscanc, Macro): +class dscanc(dNscanc, Macro): """continuous motor scan relative to the starting position.""" param_def = [ - ['motor', Type.Moveable, None, 'Moveable to move'], - ['start_pos', Type.Float, None, 'Scan start position'], - ['final_pos', Type.Float, None, 'Scan final position'], - ['integ_time', Type.Float, None, 'Integration time'], - ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], + ['motor', Type.Moveable, None, 'Moveable to move'], + ['start_pos', Type.Float, None, 'Scan start position'], + ['final_pos', Type.Float, None, 'Scan final position'], + ['integ_time', Type.Float, None, 'Integration time'], + ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, motor, start_pos, final_pos, integ_time, slow_down, **opts): self._prepare([motor], [start_pos], [final_pos], slow_down, integ_time, - mode=ContinuousMode, **opts) + mode=ContinuousMode, **opts) -class d2scanc(dNscanc,Macro): +class d2scanc(dNscanc, Macro): """continuous two-motor scan relative to the starting positions""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['integ_time', Type.Float, None, 'Integration time'], - ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['integ_time', Type.Float, None, 'Integration time'], + ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, motor1, start_pos1, final_pos1, motor2, start_pos2, final_pos2, integ_time, slow_down, **opts): - self._prepare([motor1,motor2], [start_pos1,start_pos2], - [final_pos1,final_pos2], slow_down, integ_time, - mode=ContinuousMode, **opts) + self._prepare([motor1, motor2], [start_pos1, start_pos2], + [final_pos1, final_pos2], slow_down, integ_time, + mode=ContinuousMode, **opts) -class d3scanc(dNscanc, Macro): +class d3scanc(dNscanc, Macro): """continuous three-motor scan""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['integ_time', Type.Float, None, 'Integration time'], - ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['integ_time', Type.Float, None, 'Integration time'], + ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, integ_time, slow_down, **opts): - self._prepare([m1,m2,m3], [s1,s2,s3], [f1,f2,f3], slow_down, integ_time, - mode=ContinuousMode, **opts) - + self._prepare([m1, m2, m3], [s1, s2, s3], [f1, f2, f3], slow_down, integ_time, + mode=ContinuousMode, **opts) + -class d4scanc(dNscanc, Macro): +class d4scanc(dNscanc, Macro): """continuous four-motor scan relative to the starting positions""" param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['motor4', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos4', Type.Float, None, 'Scan start position 3'], - ['final_pos4', Type.Float, None, 'Scan final position 3'], - ['integ_time', Type.Float, None, 'Integration time'], - ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['motor4', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos4', Type.Float, None, 'Scan start position 3'], + ['final_pos4', Type.Float, None, 'Scan final position 3'], + ['integ_time', Type.Float, None, 'Integration time'], + ['slow_down', Type.Float, 1, 'global scan slow down factor (0, 1]'], ] def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, integ_time, slow_down, **opts): - self._prepare([m1,m2,m3,m4], [s1,s2,s3,s4], [f1,f2,f3,f4], slow_down, + self._prepare([m1, m2, m3, m4], [s1, s2, s3, s4], [f1, f2, f3, f4], slow_down, integ_time, mode=ContinuousMode, **opts) -class meshc(Macro,Hookable): +class meshc(Macro, Hookable): """2d grid scan. scans continuous""" - - hints = { 'scan' : 'mesh', 'allowsHooks': ('pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan') } + + hints = {'scan': 'mesh', 'allowsHooks': ( + 'pre-scan', 'pre-move', 'post-move', 'pre-acq', 'post-acq', 'post-step', 'post-scan')} env = ('ActiveMntGrp',) - + param_def = [ - ['motor1', Type.Moveable, None, 'First motor to move'], - ['m1_start_pos', Type.Float, None, 'Scan start position for first motor'], - ['m1_final_pos', Type.Float, None, 'Scan final position for first motor'], - ['slow_down', Type.Float, None, 'global scan slow down factor (0, 1]'], - ['motor2', Type.Moveable, None, 'Second motor to move'], - ['m2_start_pos', Type.Float, None, 'Scan start position for second motor'], - ['m2_final_pos', Type.Float, None, 'Scan final position for second motor'], - ['m2_nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'], - ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] + ['motor1', Type.Moveable, None, 'First motor to move'], + ['m1_start_pos', Type.Float, None, + 'Scan start position for first motor'], + ['m1_final_pos', Type.Float, None, + 'Scan final position for first motor'], + ['slow_down', Type.Float, None, + 'global scan slow down factor (0, 1]'], + ['motor2', Type.Moveable, None, 'Second motor to move'], + ['m2_start_pos', Type.Float, None, + 'Scan start position for second motor'], + ['m2_final_pos', Type.Float, None, + 'Scan final position for second motor'], + ['m2_nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'], + ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] ] def prepare(self, m1, m1_start_pos, m1_final_pos, slow_down, m2, m2_start_pos, m2_final_pos, m2_nr_interv, integ_time, bidirectional, **opts): - self.motors=[m1,m2] + self.motors = [m1, m2] self.slow_down = slow_down - self.starts = numpy.array([m1_start_pos,m2_start_pos],dtype='d') - self.finals = numpy.array([m1_final_pos,m2_final_pos],dtype='d') + self.starts = numpy.array([m1_start_pos, m2_start_pos], dtype='d') + self.finals = numpy.array([m1_final_pos, m2_final_pos], dtype='d') self.m2_nr_interv = m2_nr_interv self.integ_time = integ_time self.bidirectional_mode = bidirectional self.nr_waypoints = m2_nr_interv + 1 - - self.name=opts.get('name','meshc') + + self.name = opts.get('name', 'meshc') moveables = [] for m, start, final in zip(self.motors, self.starts, self.finals): - moveables.append(MoveableDesc(moveable=m, min_value=min(start,final), max_value=max(start,final))) + moveables.append(MoveableDesc(moveable=m, min_value=min( + start, final), max_value=max(start, final))) moveables[0].is_reference = True - env=opts.get('env',{}) - constrains=[getCallable(cns) for cns in opts.get('constrains',[UNCONSTRAINED])] - extrainfodesc = opts.get('extrainfodesc',[]) - - #Hooks are not always set at this point. We will call getHooks later on in the scan_loop + env = opts.get('env', {}) + constrains = [getCallable(cns) for cns in opts.get( + 'constrains', [UNCONSTRAINED])] + extrainfodesc = opts.get('extrainfodesc', []) + + # Hooks are not always set at this point. We will call getHooks later on in the scan_loop #self.pre_scan_hooks = self.getHooks('pre-scan') - #self.post_scan_hooks = self.getHooks('post-scan' + # self.post_scan_hooks = self.getHooks('post-scan' - self._gScan = CSScan(self, self._waypoint_generator, self._period_generator, moveables, env, constrains, extrainfodesc) + self._gScan = CSScan(self, self._waypoint_generator, + self._period_generator, moveables, env, constrains, extrainfodesc) self._gScan.frozen_motors = [m2] - + def _waypoint_generator(self): step = {} step["pre-move-hooks"] = self.getHooks('pre-move') step["post-move-hooks"] = self.getHooks('post-move') step["check_func"] = [] step["slow_down"] = self.slow_down - points2=self.m2_nr_interv+1 - m1start,m2start=self.starts - m1end,m2end=self.finals - point_no=1 - for i, m2pos in enumerate(numpy.linspace(m2start,m2end,points2)): + points2 = self.m2_nr_interv + 1 + m1start, m2start = self.starts + m1end, m2end = self.finals + point_no = 1 + for i, m2pos in enumerate(numpy.linspace(m2start, m2end, points2)): start, end = m1start, m1end if i % 2 != 0 and self.bidirectional_mode: start, end = m1end, m1start step["start_positions"] = numpy.array([start, m2pos]) step["positions"] = numpy.array([end, m2pos]) - step["point_id"]= point_no - point_no+=1 + step["point_id"] = point_no + point_no += 1 yield step - + def _period_generator(self): step = {} - step["integ_time"] = self.integ_time + step["integ_time"] = self.integ_time step["pre-acq-hooks"] = self.getHooks('pre-acq') - step["post-acq-hooks"] = self.getHooks('post-acq')+self.getHooks('_NOHINTS_') + step[ + "post-acq-hooks"] = self.getHooks('post-acq') + self.getHooks('_NOHINTS_') step["post-step-hooks"] = self.getHooks('post-step') step["check_func"] = [] step['extrainfo'] = {} @@ -1225,7 +1282,7 @@ def _period_generator(self): step["point_id"] = point_no yield step - def run(self,*args): + def run(self, *args): for step in self._gScan.step_scan(): yield step @@ -1240,7 +1297,7 @@ def data(self): return self._gScan.data -class dmeshc(meshc): +class dmeshc(meshc): '''2d relative continuous grid scan. The relative mesh scan traces out a grid using motor1 and motor2. If first motor is at the position X before the scan begins, it will @@ -1261,30 +1318,36 @@ class dmeshc(meshc): env = copy.deepcopy(meshc.env) param_def = [ - ['motor1', Type.Moveable, None, 'First motor to move'], - ['m1_start_pos', Type.Float, None, 'Scan start position for first motor'], - ['m1_final_pos', Type.Float, None, 'Scan final position for first motor'], - ['slow_down', Type.Float, None, 'global scan slow down factor (0, 1]'], - ['motor2', Type.Moveable, None, 'Second motor to move'], - ['m2_start_pos', Type.Float, None, 'Scan start position for second motor'], - ['m2_final_pos', Type.Float, None, 'Scan final position for second motor'], - ['m2_nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'], - ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] + ['motor1', Type.Moveable, None, 'First motor to move'], + ['m1_start_pos', Type.Float, None, + 'Scan start position for first motor'], + ['m1_final_pos', Type.Float, None, + 'Scan final position for first motor'], + ['slow_down', Type.Float, None, + 'global scan slow down factor (0, 1]'], + ['motor2', Type.Moveable, None, 'Second motor to move'], + ['m2_start_pos', Type.Float, None, + 'Scan start position for second motor'], + ['m2_final_pos', Type.Float, None, + 'Scan final position for second motor'], + ['m2_nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'], + ['bidirectional', Type.Boolean, False, 'Save time by scanning s-shaped'] ] def prepare(self, m1, m1_start_pos, m1_final_pos, slow_down, m2, m2_start_pos, m2_final_pos, m2_nr_interv, integ_time, bidirectional, **opts): - self._motion=self.getMotion( [m1,m2] ) - self.originalPositions = numpy.array(self._motion.readPosition(force=True)) - start1 = self.originalPositions[0] + m1_start_pos - start2 = self.originalPositions[1] + m2_start_pos - final1 = self.originalPositions[0] + m1_final_pos - final2 = self.originalPositions[1] + m2_final_pos + self._motion = self.getMotion([m1, m2]) + self.originalPositions = numpy.array( + self._motion.readPosition(force=True)) + start1 = self.originalPositions[0] + m1_start_pos + start2 = self.originalPositions[1] + m2_start_pos + final1 = self.originalPositions[0] + m1_final_pos + final2 = self.originalPositions[1] + m2_final_pos meshc.prepare(self, m1, start1, final1, slow_down, - m2, start2, final2, m2_nr_interv, integ_time, - bidirectional, **opts) + m2, start2, final2, m2_nr_interv, integ_time, + bidirectional, **opts) def do_restore(self): self.info("Returning to start positions...") @@ -1298,11 +1361,11 @@ class ascanct(aNscan, Macro): start_pos and finishes at the position after the final_pos in order to maintain the constant velocity until the final_pos.""" - hints = {'scan' : 'ascanct', 'allowsHooks': ('pre-configuration', - 'post-configuration', - 'pre-start', - 'pre-cleanup', - 'post-cleanup') } + hints = {'scan': 'ascanct', 'allowsHooks': ('pre-configuration', + 'post-configuration', + 'pre-start', + 'pre-cleanup', + 'post-cleanup')} param_def = [['motor', Type.Moveable, None, 'Moveable name'], ['start_pos', Type.Float, None, 'Scan start position'], @@ -1311,8 +1374,7 @@ class ascanct(aNscan, Macro): ['integ_time', Type.Float, None, 'Integration time'], ['latency_time', Type.Float, 0, 'Latency time']] - - def prepare(self, motor, start_pos, final_pos, nr_interv, + def prepare(self, motor, start_pos, final_pos, nr_interv, integ_time, latency_time, **opts): self._prepare([motor], [start_pos], [final_pos], nr_interv, integ_time, mode=ContinuousHwTimeMode, @@ -1327,24 +1389,24 @@ class a2scanct(aNscan, Macro): its final_pos in order to maintain the constant velocity until its final_pos.""" - hints = {'scan' : 'a2scanct', 'allowsHooks': ('pre-configuration', - 'post-configuration', - 'pre-start', - 'pre-cleanup', - 'post-cleanup') } + hints = {'scan': 'a2scanct', 'allowsHooks': ('pre-configuration', + 'post-configuration', + 'pre-start', + 'pre-cleanup', + 'post-cleanup')} param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'], - ['latency_time', Type.Float, 0, 'Latency time']] - - def prepare(self, m1, s1, f1, m2, s2, f2, nr_interv, + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'], + ['latency_time', Type.Float, 0, 'Latency time']] + + def prepare(self, m1, s1, f1, m2, s2, f2, nr_interv, integ_time, latency_time, **opts): self._prepare([m1, m2], [s1, s2], [f1, f2], nr_interv, integ_time, mode=ContinuousHwTimeMode, @@ -1359,27 +1421,27 @@ class a3scanct(aNscan, Macro): after its final_pos in order to maintain the constant velocity until its final_pos.""" - hints = {'scan' : 'a2scanct', 'allowsHooks': ('pre-configuration', - 'post-configuration', - 'pre-start', - 'pre-cleanup', - 'post-cleanup') } + hints = {'scan': 'a2scanct', 'allowsHooks': ('pre-configuration', + 'post-configuration', + 'pre-start', + 'pre-cleanup', + 'post-cleanup')} param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'], - ['latency_time', Type.Float, 0, 'Latency time']] - - def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, nr_interv, + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'], + ['latency_time', Type.Float, 0, 'Latency time']] + + def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, nr_interv, integ_time, latency_time, **opts): self._prepare([m1, m2, m3], [s1, s2, s3], [f1, f2, f3], nr_interv, integ_time, mode=ContinuousHwTimeMode, @@ -1394,33 +1456,32 @@ class a4scanct(aNscan, Macro): position after its final_pos in order to maintain the constant velocity until its final_pos.""" - hints = {'scan' : 'a2scanct', 'allowsHooks': ('pre-configuration', - 'post-configuration', - 'pre-start', - 'pre-cleanup', - 'post-cleanup') } + hints = {'scan': 'a2scanct', 'allowsHooks': ('pre-configuration', + 'post-configuration', + 'pre-start', + 'pre-cleanup', + 'post-cleanup')} param_def = [ - ['motor1', Type.Moveable, None, 'Moveable 1 to move'], - ['start_pos1', Type.Float, None, 'Scan start position 1'], - ['final_pos1', Type.Float, None, 'Scan final position 1'], - ['motor2', Type.Moveable, None, 'Moveable 2 to move'], - ['start_pos2', Type.Float, None, 'Scan start position 2'], - ['final_pos2', Type.Float, None, 'Scan final position 2'], - ['motor3', Type.Moveable, None, 'Moveable 3 to move'], - ['start_pos3', Type.Float, None, 'Scan start position 3'], - ['final_pos3', Type.Float, None, 'Scan final position 3'], - ['motor4', Type.Moveable, None, 'Moveable 4 to move'], - ['start_pos4', Type.Float, None, 'Scan start position 4'], - ['final_pos4', Type.Float, None, 'Scan final position 4'], - ['nr_interv', Type.Integer, None, 'Number of scan intervals'], - ['integ_time', Type.Float, None, 'Integration time'], - ['latency_time', Type.Float, 0, 'Latency time']] - - def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, + ['motor1', Type.Moveable, None, 'Moveable 1 to move'], + ['start_pos1', Type.Float, None, 'Scan start position 1'], + ['final_pos1', Type.Float, None, 'Scan final position 1'], + ['motor2', Type.Moveable, None, 'Moveable 2 to move'], + ['start_pos2', Type.Float, None, 'Scan start position 2'], + ['final_pos2', Type.Float, None, 'Scan final position 2'], + ['motor3', Type.Moveable, None, 'Moveable 3 to move'], + ['start_pos3', Type.Float, None, 'Scan start position 3'], + ['final_pos3', Type.Float, None, 'Scan final position 3'], + ['motor4', Type.Moveable, None, 'Moveable 4 to move'], + ['start_pos4', Type.Float, None, 'Scan start position 4'], + ['final_pos4', Type.Float, None, 'Scan final position 4'], + ['nr_interv', Type.Integer, None, 'Number of scan intervals'], + ['integ_time', Type.Float, None, 'Integration time'], + ['latency_time', Type.Float, 0, 'Latency time']] + + def prepare(self, m1, s1, f1, m2, s2, f2, m3, s3, f3, m4, s4, f4, nr_interv, integ_time, latency_time, **opts): self._prepare([m1, m2, m3, m4], [s1, s2, s3, s4], [f1, f2, f3, f4], nr_interv, integ_time, mode=ContinuousHwTimeMode, latency_time=latency_time - **opts) - + ** opts) diff --git a/src/sardana/macroserver/macros/sequence.py b/src/sardana/macroserver/macros/sequence.py index d44e26600e..a3e6dbe036 100644 --- a/src/sardana/macroserver/macros/sequence.py +++ b/src/sardana/macroserver/macros/sequence.py @@ -3,40 +3,41 @@ from sardana.macroserver.macro import * -TAG_MACRO = 'macro' -TAG_PARAM = 'param' +TAG_MACRO = 'macro' +TAG_PARAM = 'param' TAG_PARAMREPEAT = 'paramrepeat' -TAG_REPEAT = 'repeat' -TAG_PARAMS = 'params' -TAG_SEQUENCE = 'sequence' +TAG_REPEAT = 'repeat' +TAG_PARAMS = 'params' +TAG_SEQUENCE = 'sequence' + +ATTRIBUTE_NAME = 'name' +ATTRIBUTE_VALUE = 'value' +ATTRIBUTE_INDEX = 'nr' +ATTRIBUTE_DESCRIPTION = 'description' +ATTRIBUTE_DEFVALUE = 'defvalue' +ATTRIBUTE_TYPE = 'type' +ATTRIBUTE_ALLOWEDHOOKS = 'allowedHooks' +ATTRIBUTE_HASPARAMS = 'hasParams' +ATTRIBUTE_MIN = 'min' -ATTRIBUTE_NAME = 'name' -ATTRIBUTE_VALUE = 'value' -ATTRIBUTE_INDEX = 'nr' -ATTRIBUTE_DESCRIPTION = 'description' -ATTRIBUTE_DEFVALUE = 'defvalue' -ATTRIBUTE_TYPE = 'type' -ATTRIBUTE_ALLOWEDHOOKS = 'allowedHooks' -ATTRIBUTE_HASPARAMS = 'hasParams' -ATTRIBUTE_MIN = 'min' class sequence(Macro): """This macro executes a sequence of macros. As a parameter it receives a string which is a xml structure. These macros which allow hooks can nest another sequence (xml structure). In such a case, this macro is executed recursively.""" - + param_def = [ - ['xml', Type.String, None, 'Xml string representing a sequence'] + ['xml', Type.String, None, 'Xml string representing a sequence'] ] - - def run(self, *pars): + + def run(self, *pars): xmlDoc = xml.dom.minidom.parseString(pars[0]) macros = self.parseXml(xmlDoc) for macro in macros: self.runMacro(macro) # self.pausePoint() - + def parseXml(self, xmlDoc): macros = [] sequenceElement = xmlDoc.getElementsByTagName(TAG_SEQUENCE)[0] @@ -47,12 +48,12 @@ def parseXml(self, xmlDoc): macro = self.createMacro(params) if hookElement is not None: hook = self.createExecMacroHook([self.__class__.__name__, - hookElement.toxml()]) + hookElement.toxml()]) macro.hooks = [hook] macros.append(macro) childElement = childElement.nextSibling return macros - + def parseMacro(self, xmlElement): name = str(xmlElement.getAttribute(ATTRIBUTE_NAME)) params = (name,) @@ -66,11 +67,11 @@ def parseMacro(self, xmlElement): elif childElement.localName == TAG_SEQUENCE: hookElement = childElement childElement = childElement.nextSibling - return (params,hookElement) - + return (params, hookElement) + def parseParam(self, xmlElement): return (str(xmlElement.getAttribute(ATTRIBUTE_VALUE)),) - + def parseParamRepeat(self, xmlElement): params = () childElement = xmlElement.firstChild @@ -79,7 +80,7 @@ def parseParamRepeat(self, xmlElement): params += self.parseRepeat(childElement) childElement = childElement.nextSibling return params - + def parseRepeat(self, xmlElement): params = () childElement = xmlElement.firstChild diff --git a/src/sardana/macroserver/macros/standard.py b/src/sardana/macroserver/macros/standard.py index 9cc021366e..6e7f01d4db 100644 --- a/src/sardana/macroserver/macros/standard.py +++ b/src/sardana/macroserver/macros/standard.py @@ -1,30 +1,30 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """This is the standard macro module""" __all__ = ["ct", "mstate", "mv", "mvr", "pwa", "pwm", "set_lim", "set_lm", - "set_pos", "settimer", "uct", "umv", "umvr", "wa", "wm", "tw"] + "set_pos", "settimer", "uct", "umv", "umvr", "wa", "wm", "tw"] __docformat__ = 'restructuredtext' @@ -38,11 +38,12 @@ import numpy as np -################################################################################ +########################################################################## # # Motion related macros # -################################################################################ +########################################################################## + class _wm(Macro): """Show motor positions""" @@ -58,9 +59,9 @@ def run(self, motor_list): show_ctrlaxis = self.getViewOption(ViewOption.ShowCtrlAxis) pos_format = self.getViewOption(ViewOption.PosFormat) motor_width = 9 - motors = {} # dict(motor name: motor obj) - requests = {} # dict(motor name: request id) - data = {} # dict(motor name: list of motor data) + motors = {} # dict(motor name: motor obj) + requests = {} # dict(motor name: request id) + data = {} # dict(motor name: list of motor data) # sending asynchronous requests: neither Taurus nor Sardana extensions # allow asynchronous requests - use PyTango asynchronous request model for motor in motor_list: @@ -125,7 +126,7 @@ def run(self, motor_list): col_headers = [] values = [] for mot_name, mot_values in sorted(data.items()): - col_headers.append([mot_name]) # convert name to list + col_headers.append([mot_name]) # convert name to list values.append(mot_values) # create and print table table = Table(values, elem_fmt=t_format, @@ -134,6 +135,7 @@ def run(self, motor_list): for line in table.genOutput(): self.output(line) + class _wum(Macro): """Show user motor positions""" @@ -145,12 +147,12 @@ class _wum(Macro): def prepare(self, motor_list, **opts): self.table_opts = {} - + def run(self, motor_list): show_dial = self.getViewOption(ViewOption.ShowDial) motor_width = 9 motor_names = [] - motor_pos = [] + motor_pos = [] motor_list = list(motor_list) motor_list.sort() for motor in motor_list: @@ -160,58 +162,64 @@ def run(self, motor_list): if pos is None: pos = float('NAN') motor_pos.append((pos,)) - motor_width = max(motor_width,len(name)) + motor_width = max(motor_width, len(name)) - fmt = '%c*.%df' % ('%',motor_width - 5) + fmt = '%c*.%df' % ('%', motor_width - 5) table = Table(motor_pos, elem_fmt=[fmt], col_head_str=motor_names, col_head_width=motor_width, **self.table_opts) for line in table.genOutput(): self.output(line) - + + class wu(Macro): """Show all user motor positions""" def prepare(self, **opts): self.all_motors = self.findObjs('.*', type_class=Type.Moveable) self.table_opts = {} - + def run(self): nr_motors = len(self.all_motors) if nr_motors == 0: self.output('No motor defined') return - - self.output('Current positions (user) on %s'%datetime.datetime.now().isoformat(' ')) + + self.output('Current positions (user) on %s' % + datetime.datetime.now().isoformat(' ')) self.output('') - - self.execMacro('_wum',self.all_motors, **self.table_opts) + + self.execMacro('_wum', self.all_motors, **self.table_opts) + class wa(Macro): """Show all motor positions""" param_def = [ ['filter', - ParamRepeat(['filter', Type.String, '.*', 'a regular expression filter'], min=1), + ParamRepeat(['filter', Type.String, '.*', + 'a regular expression filter'], min=1), '.*', 'a regular expression filter'], ] def prepare(self, filter, **opts): self.all_motors = self.findObjs(filter, type_class=Type.Moveable) self.table_opts = {} - + def run(self, filter): nr_motors = len(self.all_motors) if nr_motors == 0: self.output('No motor defined') return - + show_dial = self.getViewOption(ViewOption.ShowDial) if show_dial: - self.output('Current positions (user, dial) on %s'%datetime.datetime.now().isoformat(' ')) + self.output('Current positions (user, dial) on %s' % + datetime.datetime.now().isoformat(' ')) else: - self.output('Current positions (user) on %s'%datetime.datetime.now().isoformat(' ')) + self.output('Current positions (user) on %s' % + datetime.datetime.now().isoformat(' ')) self.output('') self.execMacro('_wm', self.all_motors, **self.table_opts) @@ -221,13 +229,15 @@ class pwa(Macro): param_def = [ ['filter', - ParamRepeat(['filter', Type.String, '.*', 'a regular expression filter'], min=1), + ParamRepeat(['filter', Type.String, '.*', + 'a regular expression filter'], min=1), '.*', 'a regular expression filter'], ] def run(self, filter): self.execMacro('wa', filter, **Table.PrettyOpts) + class set_lim(Macro): """Sets the software limits on the specified motor hello""" param_def = [ @@ -235,12 +245,14 @@ class set_lim(Macro): ['low', Type.Float, None, 'lower limit'], ['high', Type.Float, None, 'upper limit'] ] - + def run(self, motor, low, high): name = motor.getName() self.debug("Setting user limits for %s" % name) - motor.getPositionObj().setLimits(low,high) - self.output("%s limits set to %.4f %.4f (user units)" % (name, low, high)) + motor.getPositionObj().setLimits(low, high) + self.output("%s limits set to %.4f %.4f (user units)" % + (name, low, high)) + class set_lm(Macro): """Sets the dial limits on the specified motor""" @@ -249,35 +261,38 @@ class set_lm(Macro): ['low', Type.Float, None, 'lower limit'], ['high', Type.Float, None, 'upper limit'] ] - + def run(self, motor, low, high): name = motor.getName() self.debug("Setting dial limits for %s" % name) - motor.getDialPositionObj().setLimits(low,high) - self.output("%s limits set to %.4f %.4f (dial units)" % (name, low, high)) - + motor.getDialPositionObj().setLimits(low, high) + self.output("%s limits set to %.4f %.4f (dial units)" % + (name, low, high)) + + class set_pos(Macro): """Sets the position of the motor to the specified value""" - + param_def = [ ['motor', Type.Motor, None, 'Motor name'], ['pos', Type.Float, None, 'Position to move to'] ] - + def run(self, motor, pos): name = motor.getName() old_pos = motor.getPosition(force=True) motor.definePosition(pos) self.output("%s reset from %.4f to %.4f" % (name, old_pos, pos)) + class set_user_pos(Macro): """Sets the USER position of the motor to the specified value (by changing OFFSET and keeping DIAL)""" - + param_def = [ ['motor', Type.Motor, None, 'Motor name'], ['pos', Type.Float, None, 'Position to move to'] ] - + def run(self, motor, pos): name = motor.getName() old_pos = motor.getPosition(force=True) @@ -285,31 +300,34 @@ def run(self, motor, pos): old_offset = offset_attr.read().value new_offset = pos - (old_pos - old_offset) offset_attr.write(new_offset) - self.output("%s reset from %.4f (offset %.4f) to %.4f (offset %.4f)" % (name, old_pos, old_offset, pos, new_offset)) + self.output("%s reset from %.4f (offset %.4f) to %.4f (offset %.4f)" % ( + name, old_pos, old_offset, pos, new_offset)) + class wm(Macro): """Show the position of the specified motors.""" param_def = [ ['motor_list', - ParamRepeat(['motor', Type.Moveable, None, 'Motor to see where it is']), + ParamRepeat(['motor', Type.Moveable, None, + 'Motor to see where it is']), None, 'List of motor to show'], ] def prepare(self, motor_list, **opts): self.table_opts = {} - + def run(self, motor_list): motor_width = 10 motor_names = [] - motor_pos = [] + motor_pos = [] show_dial = self.getViewOption(ViewOption.ShowDial) show_ctrlaxis = self.getViewOption(ViewOption.ShowCtrlAxis) pos_format = self.getViewOption(ViewOption.PosFormat) - + for motor in motor_list: - + max_len = 0 if show_ctrlaxis: axis_nb = getattr(motor, "axis") @@ -320,7 +338,7 @@ def run(self, motor_list): max_len = max_len + 5 if max_len < 14: - max_len = 14 # Length of 'Not specified' + max_len = 14 # Length of 'Not specified' str_fmt = "%c%ds" % ('%', int(max_len)) @@ -336,10 +354,9 @@ def run(self, motor_list): val1 = str_fmt % val1 except: val1 = str_fmt % motor.getPosition(force=True) - - val2 = str_fmt % posObj.getMaxValue() - val3 = str_fmt % posObj.getMinValue() + val2 = str_fmt % posObj.getMaxValue() + val3 = str_fmt % posObj.getMinValue() if show_ctrlaxis: valctrl = str_fmt % (ctrl_name) @@ -347,21 +364,21 @@ def run(self, motor_list): upos = map(str, [valctrl, valaxis, ' ', val2, val1, val3]) else: upos = map(str, ['', val2, val1, val3]) - pos_data = upos + pos_data = upos if show_dial: try: val1 = fmt % motor.getDialPosition(force=True) val1 = str_fmt % val1 except: val1 = str_fmt % motor.getDialPosition(force=True) - - dPosObj = motor.getDialPositionObj() - val2 = str_fmt % dPosObj.getMaxValue() - val3 = str_fmt % dPosObj.getMinValue() + + dPosObj = motor.getDialPositionObj() + val2 = str_fmt % dPosObj.getMaxValue() + val3 = str_fmt % dPosObj.getMinValue() dpos = map(str, [val2, val1, val3]) pos_data += [''] + dpos - + motor_pos.append(pos_data) elem_fmt = (['%*s'] + ['%*s'] * 5) * 2 @@ -377,40 +394,44 @@ def run(self, motor_list): for line in table.genOutput(): self.output(line) + class wum(Macro): """Show the user position of the specified motors.""" param_def = [ ['motor_list', - ParamRepeat(['motor', Type.Moveable, None, 'Motor to see where it is']), + ParamRepeat(['motor', Type.Moveable, None, + 'Motor to see where it is']), None, 'List of motor to show'], ] def prepare(self, motor_list, **opts): self.table_opts = {} - + def run(self, motor_list): motor_width = 10 motor_names = [] - motor_pos = [] - + motor_pos = [] + for motor in motor_list: name = motor.getName() motor_names.append([name]) posObj = motor.getPositionObj() - upos = map(str, [posObj.getMaxValue(), motor.getPosition(force=True), posObj.getMinValue()]) + upos = map(str, [posObj.getMaxValue(), motor.getPosition( + force=True), posObj.getMinValue()]) pos_data = [''] + upos - + motor_pos.append(pos_data) elem_fmt = (['%*s'] + ['%*s'] * 3) * 2 - row_head_str = ['User', ' High', ' Current', ' Low',] + row_head_str = ['User', ' High', ' Current', ' Low', ] table = Table(motor_pos, elem_fmt=elem_fmt, row_head_str=row_head_str, col_head_str=motor_names, col_head_width=motor_width, **self.table_opts) for line in table.genOutput(): self.output(line) - + + class pwm(Macro): """Show the position of the specified motors in a pretty table""" @@ -423,14 +444,15 @@ class pwm(Macro): def run(self, motor_list): self.execMacro('wm', motor_list, **Table.PrettyOpts) + class mv(Macro): """Move motor(s) to the specified position(s)""" param_def = [ - ['motor_pos_list', - ParamRepeat(['motor', Type.Moveable, None, 'Motor to move'], - ['pos', Type.Float, None, 'Position to move to']), - None, 'List of motor/position pairs'], + ['motor_pos_list', + ParamRepeat(['motor', Type.Moveable, None, 'Motor to move'], + ['pos', Type.Float, None, 'Position to move to']), + None, 'List of motor/position pairs'], ] def run(self, motor_pos_list): @@ -448,14 +470,16 @@ def run(self, motor_pos_list): msg.append(motor.information()) self.info("\n".join(msg)) + class mstate(Macro): """Prints the state of a motor""" - + param_def = [['motor', Type.Moveable, None, 'Motor to check state']] def run(self, motor): self.info("Motor %s" % str(motor.getState())) + class umv(Macro): """Move motor(s) to the specified position(s) and update""" @@ -475,14 +499,14 @@ def run(self, motor_pos_list): self.print_pos = True self.execMacro('mv', motor_pos_list) self.finish() - + def finish(self): self._clean() self.printAllPos() - + def on_abort(self): self.finish() - + def _clean(self): for motor, pos in self.getParameters()[0]: posObj = motor.getPositionObj() @@ -491,13 +515,13 @@ def _clean(self): except Exception, e: print str(e) raise e - + def positionChanged(self, motor, position): idx = self.all_names.index([motor.getName()]) self.all_pos[idx] = [position] if self.print_pos: self.printAllPos() - + def printAllPos(self): motor_width = 10 table = Table(self.all_pos, elem_fmt=['%*.4f'], @@ -505,20 +529,21 @@ def printAllPos(self): self.outputBlock(table.genOutput()) self.flushOutput() + class mvr(Macro): """Move motor(s) relative to the current position(s)""" param_def = [ - ['motor_disp_list', - ParamRepeat(['motor', Type.Moveable, None, 'Motor to move'], - ['disp', Type.Float, None, 'Relative displacement']), - None, 'List of motor/displacement pairs'], + ['motor_disp_list', + ParamRepeat(['motor', Type.Moveable, None, 'Motor to move'], + ['disp', Type.Float, None, 'Relative displacement']), + None, 'List of motor/displacement pairs'], ] - + def run(self, motor_disp_list): motor_pos_list = [] for motor, disp in motor_disp_list: - pos = motor.getPosition(force=True) + pos = motor.getPosition(force=True) if pos is None: self.error("Cannot get %s position" % motor.getName()) return @@ -527,6 +552,7 @@ def run(self, motor_disp_list): motor_pos_list.append([motor, pos]) self.execMacro('mv', motor_pos_list) + class umvr(Macro): """Move motor(s) relative to the current position(s) and update""" @@ -535,7 +561,7 @@ class umvr(Macro): def run(self, motor_disp_list): motor_pos_list = [] for motor, disp in motor_disp_list: - pos = motor.getPosition(force=True) + pos = motor.getPosition(force=True) if pos is None: self.error("Cannot get %s position" % motor.getName()) return @@ -546,8 +572,11 @@ def run(self, motor_disp_list): # TODO: implement tw macro with param repeats in order to be able to pass # multiple motors and multiple deltas. Also allow to pass the integration time -# in order to execute the measurement group acquisition after each move and -# print the results. Basically follow the SPEC's API: https://certif.com/spec_help/tw.html +# in order to execute the measurement group acquisition after each move and +# print the results. Basically follow the SPEC's API: +# https://certif.com/spec_help/tw.html + + class tw(iMacro): """Tweak motor by variable delta""" @@ -586,7 +615,7 @@ def run(self, motor, delta): elif a == "n": a = "-" # the sign is already correct, just continue - elif a in ("+", "-"): + elif a in ("+", "-"): pass else: msg = "Typing '%s' caused 'tw' macro to stop." % a @@ -600,11 +629,11 @@ def run(self, motor, delta): self.mv(motor, pos) -################################################################################ +########################################################################## # # Data acquisition related macros # -################################################################################ +########################################################################## class ct(Macro): @@ -613,12 +642,13 @@ class ct(Macro): env = ('ActiveMntGrp',) param_def = [ - ['integ_time', Type.Float, 1.0, 'Integration time'] + ['integ_time', Type.Float, 1.0, 'Integration time'] ] def prepare(self, integ_time, **opts): mnt_grp_name = self.getEnv('ActiveMntGrp') - self.mnt_grp = self.getObj(mnt_grp_name, type_class=Type.MeasurementGroup) + self.mnt_grp = self.getObj( + mnt_grp_name, type_class=Type.MeasurementGroup) def run(self, integ_time): if self.mnt_grp is None: @@ -655,23 +685,24 @@ class uct(Macro): env = ('ActiveMntGrp',) param_def = [ - ['integ_time', Type.Float, 1.0, 'Integration time'] + ['integ_time', Type.Float, 1.0, 'Integration time'] ] def prepare(self, integ_time, **opts): - + self.print_value = False - + mnt_grp_name = self.getEnv('ActiveMntGrp') - self.mnt_grp = self.getObj(mnt_grp_name, type_class=Type.MeasurementGroup) + self.mnt_grp = self.getObj( + mnt_grp_name, type_class=Type.MeasurementGroup) if self.mnt_grp is None: return names, nan = self.mnt_grp.getChannelLabels(), float('nan') - self.names = [ [n] for n in names ] - - self.values = len(names)*[ [nan] ] + self.names = [[n] for n in names] + + self.values = len(names) * [[nan]] self.channels = self.mnt_grp.getChannelAttrExs() for ch_attr_ex in self.channels: @@ -679,24 +710,24 @@ def prepare(self, integ_time, **opts): def printAllValues(self): ch_width = 10 - table = Table(self.values, elem_fmt=['%*.4f'], col_head_str=self.names, + table = Table(self.values, elem_fmt=['%*.4f'], col_head_str=self.names, col_head_width=ch_width) self.outputBlock(table.genOutput()) self.flushOutput() - + def counterChanged(self, ch_attr, value): idx = self.channels.index(ch_attr) self.values[idx] = [value] if self.print_value: self.printAllValues() - + def run(self, integ_time): if self.mnt_grp is None: self.error('ActiveMntGrp is not defined or has invalid value') return - + self.print_value = True - + state, data = self.mnt_grp.count(integ_time) for ch_attr_ex in self.mnt_grp.getChannelAttrExs(): @@ -706,31 +737,32 @@ def run(self, integ_time): class settimer(Macro): """Defines the timer channel for the active measurement group""" - + env = ('ActiveMntGrp',) - + param_def = [ - ['timer', Type.ExpChannel, None, 'Timer'], + ['timer', Type.ExpChannel, None, 'Timer'], ] - - def run(self,timer): + + def run(self, timer): mnt_grp_name = self.getEnv('ActiveMntGrp') mnt_grp = self.getObj(mnt_grp_name, type_class=Type.MeasurementGroup) if mnt_grp is None: - self.error('ActiveMntGrp is not defined or has invalid value.\n' \ - 'please define a valid active measurement group ' \ + self.error('ActiveMntGrp is not defined or has invalid value.\n' + 'please define a valid active measurement group ' 'before setting a timer') return - + try: mnt_grp.setTimer(timer.getName()) - except Exception,e: + except Exception, e: self.output(str(e)) - self.output("%s is not a valid channel in the active measurement group" % timer) + self.output( + "%s is not a valid channel in the active measurement group" % timer) + @macro([['message', ParamRepeat(['message_item', Type.String, None, 'message item to be reported']), None, 'message to be reported']]) def report(self, message): """Logs a new record into the message report system (if active)""" self.report(' '.join(message)) - diff --git a/src/sardana/macroserver/macros/test/__init__.py b/src/sardana/macroserver/macros/test/__init__.py index fc0cbde84c..eab3a577a0 100644 --- a/src/sardana/macroserver/macros/test/__init__.py +++ b/src/sardana/macroserver/macros/test/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/macros/test/base.py b/src/sardana/macroserver/macros/test/base.py index 57c735938c..0231642e46 100644 --- a/src/sardana/macroserver/macros/test/base.py +++ b/src/sardana/macroserver/macros/test/base.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -33,8 +33,10 @@ from sardana.macroserver.macros.test import MacroExecutorFactory from taurus.test import insertTest -#Define a "_NOT_PASSED" object to mark a keyword arg which is not passed +# Define a "_NOT_PASSED" object to mark a keyword arg which is not passed # Note that we do not want to use None because one may want to pass None + + class __NotPassedType(int): pass _NOT_PASSED = __NotPassedType() @@ -107,25 +109,25 @@ class FooTest(RunMacroTestCase, unittest.TestCase): @testRun(macro_params=['-1']) class FooTest(RunMacroTestCase, unittest.TestCase): macro_name = 'twice' - + .. seealso:: :function::`taurus.test.insertTest` """ - #recipe to allow decorating with and without arguments + # recipe to allow decorating with and without arguments if klass is None: return functools.partial(macroTest, helper_name=helper_name, test_method_name=test_method_name, test_method_doc=test_method_doc, **helper_kwargs) - - return insertTest(klass=klass, helper_name=helper_name, + + return insertTest(klass=klass, helper_name=helper_name, test_method_name=test_method_name, - test_method_doc=test_method_doc, - tested_name = helper_kwargs.get("macro_name") or \ + test_method_doc=test_method_doc, + tested_name=helper_kwargs.get("macro_name") or klass.macro_name, **helper_kwargs) -#Definition of specializations of the macroTest decorator: +# Definition of specializations of the macroTest decorator: testRun = functools.partial(macroTest, helper_name='macro_runs') testStop = functools.partial(macroTest, helper_name='macro_stops') testFail = functools.partial(macroTest, helper_name='macro_fails') @@ -178,7 +180,7 @@ def assertFinished(self, msg): """ finishStates = [u'finish'] state = self.macro_executor.getState() - #TODO buffer is just for debugging, attach only the last state + # TODO buffer is just for debugging, attach only the last state state_buffer = self.macro_executor.getStateBuffer() msg = msg + '; State history=%s' % state_buffer self.assertIn(state, finishStates, msg) @@ -213,14 +215,14 @@ class member) sync=True, timeout=wait_timeout) self.assertFinished('Macro %s did not finish' % macro_name) - #check if the data of the macro is the expected one + # check if the data of the macro is the expected one if data is not _NOT_PASSED: actual_data = self.macro_executor.getData() msg = 'Macro data does not match expected data:\n' + \ 'obtained=%s\nexpected=%s' % (actual_data, data) self.assertEqual(actual_data, data, msg) - #TODO: implement generic asserts for macro result and macro output, etc + # TODO: implement generic asserts for macro result and macro output, etc # in a similar way to what is done for macro data def macro_fails(self, macro_name=None, macro_params=None, @@ -265,7 +267,7 @@ def assertStopped(self, msg): """ stoppedStates = [u'stop'] state = self.macro_executor.getState() - #TODO buffer is just for debugging, attach only the last state + # TODO buffer is just for debugging, attach only the last state state_buffer = self.macro_executor.getStateBuffer() msg = msg + '; State buffer was %s' % state_buffer self.assertIn(state, stoppedStates, msg) diff --git a/src/sardana/macroserver/macros/test/macroexecutor.py b/src/sardana/macroserver/macros/test/macroexecutor.py index 111a932260..794d45fad6 100644 --- a/src/sardana/macroserver/macros/test/macroexecutor.py +++ b/src/sardana/macroserver/macros/test/macroexecutor.py @@ -2,30 +2,31 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## from taurus.core.util.singleton import Singleton import time + class BaseMacroExecutor(object): """Abstract MacroExecutor class. Inherit from it if you want to create your @@ -37,7 +38,7 @@ class BaseMacroExecutor(object): def __init__(self): # macro result self._result = None - #macro exception status + # macro exception status self._exception = None # buffer for state history self._state_buffer = [] @@ -110,7 +111,7 @@ def wait(self, timeout=float("inf")): timeout = float("inf") self._wait(timeout) - #TODO: workaround: this sleep is necessary to perform multiple tests. + # TODO: workaround: this sleep is necessary to perform multiple tests. time.sleep(2) def _wait(self, timeout): @@ -294,7 +295,7 @@ def getMacroExecutor(self, door_name=None): from sardana import sardanacustomsettings door_name = getattr(sardanacustomsettings, 'UNITTEST_DOOR_NAME') - #======================================================================= + #====================================================================== # TODO: Once SEP3 is done, it will define a better way to get the scheme # from a model name (including customized default schemes) # For the moment I implement it by calling an internal member of diff --git a/src/sardana/macroserver/macros/test/sardemoenv.py b/src/sardana/macroserver/macros/test/sardemoenv.py index 3bb492c606..77eb3ae4e7 100644 --- a/src/sardana/macroserver/macros/test/sardemoenv.py +++ b/src/sardana/macroserver/macros/test/sardemoenv.py @@ -2,24 +2,24 @@ ############################################################################# ## -## This file is part of Sardana, a Tango User Interface Library +# This file is part of Sardana, a Tango User Interface Library ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################# @@ -88,7 +88,8 @@ def getElements(self, elem_type='all'): :return: (list) """ if not self.ready: - raise RuntimeError('SarDemoEnv instantiation had previously failed') + raise RuntimeError( + 'SarDemoEnv instantiation had previously failed') if elem_type.lower() == 'all': return self.env if elem_type.lower() == 'moveable': @@ -195,30 +196,39 @@ def getElements(elem_type="all", fallback_name="element_not_defined", elements = [fallback_name] * fallback_elements_len return elements + def getControllers(): return getElements(elem_type="controller") + def getCTs(): return getElements(elem_type="ctexpchannel") + def getMotors(): return getElements(elem_type="motor") + def getPseudoMotors(): return getElements(elem_type="pseudomotor") + def getMoveables(): return getElements(elem_type="moveable") + def getZerods(): return getElements(elem_type="zerodexpchannel") + def getOneds(): return getElements(elem_type="onedexpchannel") + def getTwods(): return getElements(elem_type="twodexpchannel") + def getIORs(): return getElements(elem_type="ioregister") diff --git a/src/sardana/macroserver/macros/test/test_ascanct.py b/src/sardana/macroserver/macros/test/test_ascanct.py index 252f192e86..9d249b9cce 100644 --- a/src/sardana/macroserver/macros/test/test_ascanct.py +++ b/src/sardana/macroserver/macros/test/test_ascanct.py @@ -4,14 +4,16 @@ import PyTango from taurus.external import unittest from sardana.macroserver.macros.test import (RunStopMacroTestCase, testRun, - testStop) + testStop) from sardana.pool import AcqSynchType -#TODO: MeasSarTestTestCase is a util, could be moved to base_sartest or another +# TODO: MeasSarTestTestCase is a util, could be moved to base_sartest or another # utils module. from sardana.tango.pool.test.test_measurementgroup import MeasSarTestTestCase from sardana.tango.macroserver.test import BaseMacroServerTestCase + class UtilsForTests(): + def parsingOutputPoints(self, log_output): """A helper method to know if points are ordered based on log_output. """ @@ -28,8 +30,8 @@ def parsingOutputPoints(self, log_output): nb_points = len(list_points) ordered_points = 0 - for i in range(len(list_points)-1): - if list_points[i+1] >= list_points[i]: + for i in range(len(list_points) - 1): + if list_points[i + 1] >= list_points[i]: ordered_points = 1 else: ordered_points = 0 @@ -37,14 +39,13 @@ def parsingOutputPoints(self, log_output): return (nb_points, ordered_points) - - def orderPointsData(self, data): + def orderPointsData(self, data): """A helper method to know if points are ordered based on getData. """ obtained_nb_points_data = len(data.keys()) ordered_points_data = 0 - for i in range(obtained_nb_points_data-1): - if int(data.keys()[i+1]) >= int(data.keys()[i]): + for i in range(obtained_nb_points_data - 1): + if int(data.keys()[i + 1]) >= int(data.keys()[i]): ordered_points_data = 1 else: ordered_points_data = 0 @@ -54,25 +55,26 @@ def orderPointsData(self, data): mg_config1 = [[('_test_ct_1_1', '_test_tg_1_1', AcqSynchType.Trigger)]] mg_config2 = [[('_test_ct_1_1', '_test_tg_1_1', AcqSynchType.Trigger), ('_test_ct_1_2', '_test_tg_1_1', AcqSynchType.Trigger)] - ] + ] mg_config3 = [[('_test_ct_1_1', 'software', AcqSynchType.Trigger)], [('_test_ct_2_1', '_test_tg_1_1', AcqSynchType.Trigger)] - ] + ] mg_config4 = [[('_test_ct_1_1', 'software', AcqSynchType.Trigger)], [('_test_ct_2_1', 'software', AcqSynchType.Trigger)] - ] + ] macro_params_1 = ['_test_mt_1_1', '0', '10', '100', '0.1'] -@testRun(meas_config=mg_config1, macro_params=macro_params_1, + +@testRun(meas_config=mg_config1, macro_params=macro_params_1, wait_timeout=30) -@testRun(meas_config=mg_config2, macro_params=macro_params_1, +@testRun(meas_config=mg_config2, macro_params=macro_params_1, wait_timeout=30) -@testRun(meas_config=mg_config3, macro_params=macro_params_1, +@testRun(meas_config=mg_config3, macro_params=macro_params_1, wait_timeout=30) -@testRun(meas_config=mg_config4, macro_params=macro_params_1, +@testRun(meas_config=mg_config4, macro_params=macro_params_1, wait_timeout=30) @testStop(meas_config=mg_config1, macro_params=macro_params_1, - stop_delay=5, wait_timeout=20) + stop_delay=5, wait_timeout=20) class AscanctTest(MeasSarTestTestCase, BaseMacroServerTestCase, RunStopMacroTestCase, unittest.TestCase): """Checks that ascanct works and generates the exact number of records @@ -91,7 +93,7 @@ def setUp(self): RunStopMacroTestCase.setUp(self) def macro_runs(self, meas_config, macro_params, wait_timeout=float("inf")): - #TODO: workaround for bug with velocity0, - "The ascanct execution did not return any scan point.\n" - + "Checked using macro_executor.getData()") + self.assertTrue(len(data.keys()) > 0, + "The ascanct execution did not return any scan point.\n" + + "Checked using macro_executor.getData()") obtained_nb_points_data = len(data.keys()) self.assertEqual(int(obtained_nb_points_data), int(expected_nb_points), - "The ascanct execution did not return the expected number of " + - " points.\n Expected " + str(expected_nb_points) + " points." + - "\n Obtained " + str(obtained_nb_points_data) + " points." + - "\nChecked using macro_executor.getData()") + "The ascanct execution did not return the expected number of " + + " points.\n Expected " + str(expected_nb_points) + " points." + + "\n Obtained " + str(obtained_nb_points_data) + " points." + + "\nChecked using macro_executor.getData()") self.assertTrue(order_points_data, "Scan points are NOT in good order." - + "\nChecked using macro_executor.getData().") + + "\nChecked using macro_executor.getData().") def macro_stops(self, meas_config, macro_params, wait_timeout=float("inf"), stop_delay=0.1): - #TODO: workaround for bug with velocity. +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/macros/test/test_env.py b/src/sardana/macroserver/macros/test/test_env.py index 798caa8013..499b9a03f2 100644 --- a/src/sardana/macroserver/macros/test/test_env.py +++ b/src/sardana/macroserver/macros/test/test_env.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -28,6 +28,7 @@ from taurus.external import unittest from sardana.macroserver.macros.test import RunMacroTestCase, testRun + @testRun class DumpenvTest(RunMacroTestCase, unittest.TestCase): """Test case for dumpenv macro @@ -58,14 +59,14 @@ class UsetvoTest(RunMacroTestCase, unittest.TestCase): @testRun @testRun(macro_params=["ascan"]) -@testRun(macro_params=["ascan", "dscan"]) +@testRun(macro_params=["ascan", "dscan"]) class LsenvTest(RunMacroTestCase, unittest.TestCase): """Test case for lsvo macro """ macro_name = "lsenv" -@testRun(macro_params=["MyEnvVar", "test.dat"]) +@testRun(macro_params=["MyEnvVar", "test.dat"]) class SenvTest(RunMacroTestCase, unittest.TestCase): """Test case for senv macro """ diff --git a/src/sardana/macroserver/macros/test/test_expert.py b/src/sardana/macroserver/macros/test/test_expert.py index f1de5f00c4..5bd73c3b1c 100644 --- a/src/sardana/macroserver/macros/test/test_expert.py +++ b/src/sardana/macroserver/macros/test/test_expert.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -32,9 +32,11 @@ CTRL_NAME1 = getControllers()[0] CT_NAME1, CT_NAME2 = getCTs()[:2] + class ExpertTest(RunMacroTestCase, unittest.TestCase): """Test case for some of the expert macros. """ + def test_expert(self): CTRL_NAME = "unittestmotctrl01" MOT_NAME1 = "unittestmot01" @@ -56,7 +58,7 @@ def test_expert(self): macro_params=[MOT_NAME1, MOT_NAME2], wait_timeout=1) self.macro_runs(macro_name="udefctrl", - macro_params = [CTRL_NAME], + macro_params=[CTRL_NAME], wait_timeout=1) except Exception, e: import taurus @@ -68,6 +70,7 @@ def test_expert(self): class MeasTest(RunMacroTestCase, unittest.TestCase): """Test case for measurement group related expert macros. """ + def test_meas(self): MNTGRP_NAME = "unittestmntgrp01" try: @@ -81,7 +84,7 @@ def test_meas(self): " exception during the test.") raise e -#TODO: improve this test: not all sardana controller implement SendToCtrl +# TODO: improve this test: not all sardana controller implement SendToCtrl # @testRun(macro_params=[CTRL_NAME1, "blabla"], wait_timeout=1) # class Send2ctrlTest(RunMacroTestCase, unittest.TestCase): # """Test case for send2ctrl macro. diff --git a/src/sardana/macroserver/macros/test/test_ioregister.py b/src/sardana/macroserver/macros/test/test_ioregister.py index 6a738f9df6..1fbc7315f7 100644 --- a/src/sardana/macroserver/macros/test/test_ioregister.py +++ b/src/sardana/macroserver/macros/test/test_ioregister.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -30,10 +30,11 @@ IOR_NAME = getIORs()[0] + @testRun(macro_name="write_ioreg", macro_params=[IOR_NAME, "1"], wait_timeout=1) @testRun(macro_name="read_ioreg", macro_params=[IOR_NAME], wait_timeout=1) class IORegisterTest(RunMacroTestCase, unittest.TestCase): """Test case for ioregister macros """ - pass \ No newline at end of file + pass diff --git a/src/sardana/macroserver/macros/test/test_list.py b/src/sardana/macroserver/macros/test/test_list.py index 181b55a2be..ff24c16d12 100644 --- a/src/sardana/macroserver/macros/test/test_list.py +++ b/src/sardana/macroserver/macros/test/test_list.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -73,7 +73,7 @@ def macro_runs(self, **kwargs): else: raise Exception("element_type cannot be None") - #parsing log output to get all elements + # parsing log output to get all elements header_rows = 2 names_column_index = 0 macro_output = [] diff --git a/src/sardana/macroserver/macros/test/test_scan.py b/src/sardana/macroserver/macros/test/test_scan.py index b848a21214..8bba57aa7d 100644 --- a/src/sardana/macroserver/macros/test/test_scan.py +++ b/src/sardana/macroserver/macros/test/test_scan.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,9 +29,10 @@ from sardana.macroserver.macros.test import (RunStopMacroTestCase, testRun, testStop, getMotors) -#get handy motor names from sardemo +# get handy motor names from sardemo _m1, _m2 = getMotors()[:2] + def parsing_log_output(log_output): """A helper method to parse log output of an executed scan macro. :params log_output: (seq) Result of macro_executor.getLog('output') @@ -98,7 +99,7 @@ def macro_runs(self, macro_params=None, wait_timeout=30.0): - Intervals in terms of motor position between one point and the next one are equidistant. """ - #call the parent class implementation + # call the parent class implementation ANscanTest.macro_runs(self, macro_params=macro_params, wait_timeout=wait_timeout) @@ -154,11 +155,11 @@ class DscanTest(DNscanTest, unittest.TestCase): macro_name = 'dscan' -@testRun(macro_params=[_m1, '-1', '1', '3', _m2, '-1', '0', '2', '.1'], +@testRun(macro_params=[_m1, '-1', '1', '3', _m2, '-1', '0', '2', '.1'], wait_timeout=30) -@testRun(macro_params=[_m1, '-2', '2', '3', _m2, '-2', '-1', '2', '.1'], +@testRun(macro_params=[_m1, '-2', '2', '3', _m2, '-2', '-1', '2', '.1'], wait_timeout=40) -@testStop(macro_params=[_m1, '-3', '0', '3', _m2, '-3', '0', '2', '.1'], +@testStop(macro_params=[_m1, '-3', '0', '3', _m2, '-3', '0', '2', '.1'], wait_timeout=30) class MeshTest(RunStopMacroTestCase, unittest.TestCase): diff --git a/src/sardana/macroserver/macros/test/test_standard.py b/src/sardana/macroserver/macros/test/test_standard.py index f9143d1ef8..9f5278978b 100644 --- a/src/sardana/macroserver/macros/test/test_standard.py +++ b/src/sardana/macroserver/macros/test/test_standard.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,7 +31,7 @@ MOT_NAME1, MOT_NAME2 = getMotors()[:2] -#TODO: these tests randomly causes segfaults. fix it! +# TODO: these tests randomly causes segfaults. fix it! # @testRun(macro_name="wu", wait_timeout=1) # @testRun(macro_name="wa", wait_timeout=1) # @testRun(macro_name="wa", macro_params=["mot.*"], wait_timeout=1) @@ -47,6 +47,7 @@ # """ # pass + @testRun(macro_name="set_lim", macro_params=[MOT_NAME1, "-100", "100"], wait_timeout=1) @testRun(macro_name="set_lm", macro_params=[MOT_NAME1, "-1000", "1000"], @@ -70,6 +71,7 @@ class PosTest(RunMacroTestCase, unittest.TestCase): class MoveTest(RunMacroTestCase, unittest.TestCase): """Test case for position macros """ + def test_move(self): self.macro_runs("set_user_pos", macro_params=[MOT_NAME1, "0"], wait_timeout=1) diff --git a/src/sardana/macroserver/macros/test/test_wm.py b/src/sardana/macroserver/macros/test/test_wm.py index 5f2a898251..2388fd36bf 100644 --- a/src/sardana/macroserver/macros/test/test_wm.py +++ b/src/sardana/macroserver/macros/test/test_wm.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,9 +29,10 @@ from sardana.macroserver.macros.test import (RunMacroTestCase, testRun, getMotors) -#get handy motor names from sardemo +# get handy motor names from sardemo _m1, _m2 = getMotors()[:2] + class WBase(RunMacroTestCase): """Base class for testing macros used to read position. diff --git a/src/sardana/macroserver/macroserver.py b/src/sardana/macroserver/macroserver.py index afc839a94e..01bd3151db 100644 --- a/src/sardana/macroserver/macroserver.py +++ b/src/sardana/macroserver/macroserver.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -58,20 +58,21 @@ CHANGE_EVT_TYPES = TaurusEventType.Change, TaurusEventType.Periodic ET = ElementType -#: dictionary dict<:data:`~sardana.ElementType`, :class:`tuple`> +#: dictionary dict<:data:`~sardana.ElementType`, :class:`tuple`> #: where tuple is a sequence: -#: +#: #: #. type string representation #: #. family #: #. internal macro server class #: #. automatic full name TYPE_MAP = { - ET.Door : ("Door", "Door", MSDoor, "door/{macro_server.name}/{name}"), + ET.Door: ("Door", "Door", MSDoor, "door/{macro_server.name}/{name}"), } + class TypeData(object): """Information for a specific Element type""" - + def __init__(self, **kwargs): self.__dict__.update(kwargs) @@ -79,7 +80,7 @@ def __init__(self, **kwargs): #: dict<:data:`~sardana.ElementType`, :class:`~sardana.macroserver.macroserver.TypeData`> TYPE_MAP_OBJ = {} for t, d in TYPE_MAP.items(): - o = TypeData(type=t, name=d[0], family=d[1], klass=d[2] , + o = TypeData(type=t, name=d[0], family=d[1], klass=d[2], auto_full_name=d[3]) TYPE_MAP_OBJ[t] = o @@ -129,14 +130,14 @@ def doRollover(self): class MacroServer(MSContainer, MSObject, SardanaElementManager, SardanaIDManager): - + All = "All" - + MaxParalellMacros = 5 - + logReportParams = dict(when='midnight', interval=1, backupCount=365) logReportKlass = NonOverlappingTimedRotatingFileHandler - + def __init__(self, full_name, name=None, macro_path=None, environment_db=None, recorder_path=None): # dict @@ -145,16 +146,16 @@ def __init__(self, full_name, name=None, macro_path=None, self._pools = CaselessDict() self._max_parallel_macros = self.MaxParalellMacros self._path_id = None - + MSContainer.__init__(self) MSObject.__init__(self, full_name=full_name, name=name, id=InvalidId, macro_server=self, elem_type=ElementType.MacroServer) - + registerExtensions() - + self._type_manager = TypeManager(self) self._environment_manager = EnvironmentManager(self, - environment_db=environment_db) + environment_db=environment_db) self._macro_manager = MacroManager(self, macro_path=macro_path) self._recorder_manager = RecorderManager(self, recorder_path=recorder_path) @@ -165,7 +166,7 @@ def serialize(self, *args, **kwargs): kwargs['id'] = InvalidId kwargs['parent'] = None return kwargs - + def add_job(self, job, callback=None, *args, **kw): th_pool = get_thread_pool() th_pool.add(job, callback, *args, **kw) @@ -176,7 +177,7 @@ def add_job(self, job, callback=None, *args, **kw): def set_environment_db(self, environment_db): """Sets the environment database. - + :param env_db: environment database name :type env_db: @@ -200,7 +201,7 @@ def set_python_path(self, path): def set_macro_path(self, macro_path): """Sets the macro path. - + :param macro_path: macro path :type macro_path: @@ -228,7 +229,7 @@ def set_recorder_path(self, recorder_path): def set_log_report(self, filename=None, format=None): log = self.get_report_logger() - + # first check that the handler has not been initialized yet. If it has # we remove previous handlers. We only allow one timed rotating file # handler at a time @@ -236,30 +237,30 @@ def set_log_report(self, filename=None, format=None): for handler in log.handlers: if isinstance(handler, logging.handlers.TimedRotatingFileHandler): to_remove.append(handler) - + for handler in to_remove: handler.close() log.removeHandler(handler) - + if filename is None: return - + if format is None: format = Logger.DftLogMessageFormat formatter = logging.Formatter(format) - + self.info("Reports are being stored in %s", filename) klass = self.logReportKlass handler = klass(filename, **self.logReportParams) handler.setFormatter(formatter) log.addHandler(handler) - + def clear_log_report(self): self.set_log_report() - + def get_report_logger(self): return logging.getLogger("Sardana.Report") - + report_logger = property(get_report_logger) def report(self, msg, *args, **kwargs): @@ -269,34 +270,34 @@ def report(self, msg, *args, **kwargs): the arguments which are merged into msg using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.) - + *kwargs* are the same as :meth:`logging.Logger.debug` plus an optional level kwargs which has default value **INFO** - + Example:: - + self.report("this is an official report!") - + :param msg: the message to be recorded :type msg: :obj:`str` :param args: list of arguments :param kwargs: list of keyword arguments""" level = kwargs.pop('level', logging.INFO) return self.report_logger.log(level, msg, *args, **kwargs) - + # -------------------------------------------------------------------------- # Pool related methods # -------------------------------------------------------------------------- - + def set_pool_names(self, pool_names): """Registers a new list of device pools in this manager - + :param pool_names: sequence of pool names :type pool_names: seq""" for pool in self._pools.values(): elements_attr = pool.getAttribute("Elements") elements_attr.removeListener(self.on_pool_elements_changed) - + for name in pool_names: self.debug("Creating pool %s", name) pool = Device(name) @@ -306,57 +307,57 @@ def set_pool_names(self, pool_names): self._pools[name] = pool elements_attr = pool.getAttribute("Elements") elements_attr.addListener(self.on_pool_elements_changed) - + def get_pool_names(self): """Returns the list of names of the pools this macro server is connected to. - + :return: the list of names of the pools this macro server is connected to :rtype: seq""" return self._pools.keys() - + def get_pool(self, pool_name): """Returns the device pool object corresponding to the given device name or None if no match is found. - + :param pool_name: device pool name :type pool_name: str :return: Pool object or None if no match is found""" return self._pools.get(pool_name) - + def get_pools(self): """Returns the list of pools this macro server is connected to. - + :return: the list of pools this macro server is connected to :rtype: seq""" return self._pools.values() - + def on_pool_elements_changed(self, evt_src, evt_type, evt_value): if evt_type not in CHANGE_EVT_TYPES: return self.fire_event(EventType("PoolElementsChanged"), evt_value) - + # -------------------------------------------------------------------------- # Door related methods # -------------------------------------------------------------------------- - + def create_element(self, **kwargs): type = kwargs['type'] elem_type = ElementType[type] name = kwargs['name'] - + kwargs['macro_server'] = self - + td = TYPE_MAP_OBJ[elem_type] klass = td.klass auto_full_name = td.auto_full_name - + full_name = kwargs.get("full_name", auto_full_name.format(**kwargs)) - + self.check_element(name, full_name) - + id = kwargs.get('id') if id is None: kwargs['id'] = id = self.get_new_id() @@ -366,53 +367,53 @@ def create_element(self, **kwargs): ret = self.add_element(elem) self.fire_event(EventType("ElementCreated"), elem) return ret - + def create_door(self, **kwargs): return self.create_element(type="Door", **kwargs) - + # -------------------------------------------------------------------------- # General access to elements # -------------------------------------------------------------------------- - + def get_elements_info(self): return self.get_remote_elements_info() + self.get_local_elements_info() - + def get_remote_elements_info(self): - return [ elem.serialize() - for pool in self.get_pools() - for elem in pool.getElements() ] - + return [elem.serialize() + for pool in self.get_pools() + for elem in pool.getElements()] + def get_local_elements_info(self): # fill macro library info - ret = [ macrolib.serialize() - for macrolib in self.get_macro_libs().values() ] + ret = [macrolib.serialize() + for macrolib in self.get_macro_libs().values()] # fill macro info - ret += [ macro.serialize() - for macro in self.get_macros().values() ] + ret += [macro.serialize() + for macro in self.get_macros().values()] # fill parameter type info - ret += [ paramtype.serialize() - for paramtype in self.get_data_types().values() ] - + ret += [paramtype.serialize() + for paramtype in self.get_data_types().values()] + return ret - + # -------------------------------------------------------------------------- # macro execution # -------------------------------------------------------------------------- - + def set_max_parallel_macros(self, nb): assert nb > 0, "max parallel macros number must be > 0" th_pool = get_thread_pool() if th_pool.size + 5 < nb: th_pool.size = nb self._max_parallel_macros = nb - + def get_max_parallel_macros(self): return self._max_parallel_macros - + max_parallel_macros = property(get_max_parallel_macros, - set_max_parallel_macros, doc="maximum number of macros which can " - "execute at the same time") - + set_max_parallel_macros, doc="maximum number of macros which can " + "execute at the same time") + @property def macro_manager(self): return self._macro_manager @@ -424,28 +425,28 @@ def recorder_manager(self): @property def environment_manager(self): return self._environment_manager - + @property def type_manager(self): return self._type_manager - + # -------------------------------------------------------------------------- # (Re)load code # -------------------------------------------------------------------------- - + def reload_lib(self, lib_name): - return self.macro_manager.reloadLib(lib_name) - + return self.macro_manager.reloadLib(lib_name) + def reload_macro_lib(self, lib_name): manager = self.macro_manager - + try: old_lib = manager.getMacroLib(lib_name) except UnknownMacroLibrary: old_lib = None - + new_elements, changed_elements, deleted_elements = [], [], [] - + new_lib = manager.reloadMacroLib(lib_name) if new_lib.has_errors(): return new_lib @@ -455,8 +456,8 @@ def reload_macro_lib(self, lib_name): new_elements.append(new_lib) else: changed_elements.append(new_lib) - new_names = set([ macro.name for macro in new_lib.get_macros() ]) - old_names = set([ macro.name for macro in old_lib.get_macros() ]) + new_names = set([macro.name for macro in new_lib.get_macros()]) + old_names = set([macro.name for macro in old_lib.get_macros()]) changed_names = set.intersection(new_names, old_names) deleted_names = old_names.difference(new_names) new_names = new_names.difference(old_names) @@ -467,42 +468,42 @@ def reload_macro_lib(self, lib_name): changed_elements.append(new_lib.get_macro(changed_name)) for deleted_name in deleted_names: deleted_elements.append(old_lib.get_macro(deleted_name)) - - evt = { "new" : new_elements, "change" : changed_elements, - "del" : deleted_elements } + + evt = {"new": new_elements, "change": changed_elements, + "del": deleted_elements} self.fire_event(EventType("ElementsChanged"), evt) return new_lib - + reload_macro_lib.__doc__ = MacroManager.reloadMacroLib.__doc__ - + def reload_macro_libs(self, lib_names): for lib_name in lib_names: self.reload_macro_lib(lib_name) - + def reload_macro(self, macro_name): macro_info = self.macro_manager.getMacro(macro_name) lib_name = macro_info.module_name return self.reload_macro_lib(lib_name) - + def reload_macros(self, macro_names): lib_names = set() for macro_name in macro_names: macro_info = self.macro_manager.getMacro(macro_name) lib_names.add(macro_info.module_name) self.reload_macro_libs(lib_names) - + def get_macro_lib(self, lib_name): return self.macro_manager.getMacroLib(lib_name) get_macro_lib.__doc__ = MacroManager.getMacroLib.__doc__ - + def get_macro_libs(self, filter=None): return self.macro_manager.getMacroLibs(filter=filter) get_macro_libs.__doc__ = MacroManager.getMacroLibs.__doc__ - + def get_macro_lib_names(self): return self.macro_manager.getMacroLibNames() get_macro_lib_names.__doc__ = MacroManager.getMacroLibNames.__doc__ - + def get_macro(self, name): return self.macro_manager.getMacro(name) get_macro.__doc__ = MacroManager.getMacro.__doc__ @@ -510,19 +511,19 @@ def get_macro(self, name): def get_macros(self, filter=None): return self.macro_manager.getMacros(filter=filter) get_macros.__doc__ = MacroManager.getMacros.__doc__ - + def get_macro_names(self): return self.macro_manager.getMacroNames() get_macro_names.__doc__ = MacroManager.getMacroNames.__doc__ - + def get_macro_classes(self): return self.macro_manager.getMacroClasses() get_macro_classes.__doc__ = MacroManager.getMacroClasses.__doc__ - + def get_macro_functions(self): return self.macro_manager.getMacroFunctions() get_macro_functions.__doc__ = MacroManager.getMacroFunctions.__doc__ - + def get_macro_libs_summary_info(self): libs = self.get_macro_libs() ret = [] @@ -530,7 +531,7 @@ def get_macro_libs_summary_info(self): elem = "%s (%s)" % (macro_lib_info.name, macro_lib_info.file_path) ret.append(elem) return ret - + def get_macro_classes_summary_info(self): macros = self.get_macros() ret = [] @@ -538,12 +539,12 @@ def get_macro_classes_summary_info(self): elem = "%s (%s)" % (macro_info.name, macro_info.file_path) ret.append(elem) return ret - + def get_or_create_macro_lib(self, lib_name, macro_name=None): """Gets the exiting macro lib or creates a new macro lib file. If name is not None, a macro template code for the given macro name is appended to the end of the file. - + :param lib_name: module name, python file name, or full file name (with path) :type lib_name: str @@ -552,7 +553,7 @@ def get_or_create_macro_lib(self, lib_name, macro_name=None): to the end of the file (default is None meaning no macro code is added) :type macro_name: str - + :return: a sequence with three items: full_filename, code, line number is 0 if no macro is created or n representing the first line of code for @@ -561,59 +562,59 @@ def get_or_create_macro_lib(self, lib_name, macro_name=None): return self.macro_manager.getOrCreateMacroLib(lib_name, macro_name=macro_name) get_or_create_macro_lib.__doc__ = MacroManager.getOrCreateMacroLib.__doc__ - + def set_macro_lib(self, lib_name, code, auto_reload=True): module_name = self.macro_manager.setMacroLib(lib_name, code, auto_reload=False) if auto_reload: self.reload_macro_lib(module_name) - + set_macro_lib.__doc__ = MacroManager.setMacroLib.__doc__ - + # -------------------------------------------------------------------------- # Data types # -------------------------------------------------------------------------- - + def get_data_types(self): return self.type_manager.getTypes() get_data_types.__doc__ = TypeManager.getTypes.__doc__ - + def get_data_type(self, type_name): return self.type_manager.getTypeObj(type_name) get_data_type.__doc__ = TypeManager.getTypeObj.__doc__ - + def get_data_type_names(self): return self.type_manager.getTypeNames() get_data_type_names.__doc__ = TypeManager.getTypeNames.__doc__ - + def get_data_type_names_with_asterisc(self): return self.type_manager.getTypeListStr() get_data_type_names_with_asterisc.__doc__ = TypeManager.getTypeListStr.__doc__ - + # -------------------------------------------------------------------------- # Doors # -------------------------------------------------------------------------- - + def get_doors(self): return self.get_elements_by_type(ElementType.Door) - + def get_door_names(self): - return [ door.full_name for door in self.get_doors() ] - + return [door.full_name for door in self.get_doors()] + #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Environment access methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- - + def get_env(self, key=None, door_name=None, macro_name=None): """Gets the environment matching the given parameters: - + - door_name and macro_name define the context where to look for the environment. If both are None, the global environment is used. If door name is None but macro name not, the given macro environment is used and so on... - If key is None it returns the complete environment, otherwise key must be a string containing the environment variable name. - + :param key: environment variable name [default: None, meaning all environment] :type key: str @@ -625,100 +626,102 @@ def get_env(self, key=None, door_name=None, macro_name=None): local context for a given macro [default: None, meaning no macro context is used] :type macro_name: str - + :return: a :obj:`dict` containing the environment :rtype: :obj:`dict` - + :raises: UnknownEnv""" return self.environment_manager.getEnv(key=key, macro_name=macro_name, door_name=door_name) - + def set_env(self, key, value): """Sets the environment key to the new value and stores it persistently. - + :param key: the key for the environment :param value: the value for the environment - + :return: a tuple with the key and value objects stored""" env_man = self.environment_manager if env_man.hasEnv(key): evt_type = "change" else: evt_type = "new" - - k,v = self.environment_manager.setEnv(key, value) - - evt = { evt_type : { k : v } } + + k, v = self.environment_manager.setEnv(key, value) + + evt = {evt_type: {k: v}} self.fire_event(EventType("EnvironmentChanged"), evt) - return k,v - + return k, v + def set_env_obj(self, data): """Sets the environment key to the new value and stores it persistently. - + :param key: the key for the environment :param value: the value for the environment - + :return: a tuple with the key and value objects stored""" env_man = self.environment_manager - + new, change = {}, {} for key, value in data.items(): d = new if env_man.hasEnv(key): d = change d[key] = value - + ret = env_man.setEnvObj(data) - + evt = dict(new=new, change=change) self.fire_event(EventType("EnvironmentChanged"), evt) return ret - + def change_env(self, data): env_man = self.environment_manager new_change_env = data.get('new', {}) new_change_env.update(data.get('change', {})) del_env = data.get('del', []) - + new, change = {}, {} for key, value in new_change_env.items(): d = new if env_man.hasEnv(key): d = change d[key] = value - + del_keys = env_man.unsetEnv(del_env) env_man.setEnvObj(new_change_env) - + evt = dict(new=new, change=change) evt['del'] = del_keys self.fire_event(EventType("EnvironmentChanged"), evt) - + def unset_env(self, key): """Unsets the environment for the given key. - + :param key: the key for the environment to be unset""" ret = self.environment_manager.unsetEnv(key) # list is unhashable - convert to a tuple - if isinstance(key, list): key = tuple(key) - evt = { 'del' : { key : None } } + if isinstance(key, list): + key = tuple(key) + evt = {'del': {key: None}} self.fire_event(EventType("EnvironmentChanged"), evt) return ret - + def has_env(self, key, macro_name=None, door_name=None): return self.environment_manager.hasEnv(key, - macro_name=macro_name, door_name=door_name) - + macro_name=macro_name, door_name=door_name) + #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # General object access methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- - + def get_object(self, name, type_class=All, subtype=All, pool=All): objs = self.find_objects(name, type_class, subtype, pool) if len(objs) == 0: return None if len(objs) > 1: - raise AttributeError('More than one object named "%s" found' % name) + raise AttributeError( + 'More than one object named "%s" found' % name) return objs[0] def get_objects(self, names, type_class=All, subtype=All, pool=All): @@ -728,7 +731,7 @@ def get_objects(self, names, type_class=All, subtype=All, pool=All): def find_objects(self, param, type_class=All, subtype=All, pool=All): if is_pure_str(param): param = param, - + if type_class == MacroServer.All: type_name_list = self.get_data_type_names() else: @@ -737,7 +740,7 @@ def find_objects(self, param, type_class=All, subtype=All, pool=All): else: type_name_list = type_class obj_set = set() - param = [ '^%s$' % x for x in param ] + param = ['^%s$' % x for x in param] re_objs = map(re.compile, param, len(param) * (re.IGNORECASE,)) re_subtype = re.compile(subtype, re.IGNORECASE) for type_name in type_name_list: @@ -759,34 +762,34 @@ def find_objects(self, param, type_class=All, subtype=All, pool=All): for re_obj in re_objs: if re_obj.match(name) is not None: obj_type = obj.getType() - if (subtype is MacroServer.All or \ + if (subtype is MacroServer.All or re_subtype.match(obj.getType())) and \ obj_type != "MotorGroup": obj_set.add(obj) return list(obj_set) - + def get_motion(self, elems, motion_source=None, read_only=False, cache=True, decoupled=False): if motion_source is None: motion_source = self.get_pools() - + motion_klass = Motion - if decoupled: # and len(elems)>1: + if decoupled: # and len(elems)>1: motion_klass = MotionGroup return motion_klass(elems, motion_source) - + _LOCAL_INTERFACES = { - Interface.MacroLibrary : get_macro_libs, - Interface.MacroCode : get_macros, + Interface.MacroLibrary: get_macro_libs, + Interface.MacroCode: get_macros, Interface.MacroClass: get_macro_classes, - Interface.MacroFunction: get_macro_functions, + Interface.MacroFunction: get_macro_functions, } - + def is_macroserver_interface(self, interface): if is_pure_str(interface): interface = Interface[interface] return interface in self._LOCAL_INTERFACES - + def get_elements_with_interface(self, interface): ret = CaselessDict() if is_pure_str(interface): @@ -801,87 +804,87 @@ def get_elements_with_interface(self, interface): for pool in self.get_pools(): ret.update(pool.getElementsWithInterface(interface_str)) return ret - + def get_element_with_interface(self, name, interface): for pool in self.get_pools(): element = pool.getElementWithInterface(name, interface) if element is not None: return element - + def get_controllers(self): return self.get_elements_with_interface("Controller") - + def get_moveables(self): return self.get_elements_with_interface("Moveable") - + def get_motors(self): return self.get_elements_with_interface("Motor") - + def get_pseudo_motors(self): return self.get_elements_with_interface("PseudoMotor") - + def get_io_registers(self): return self.get_elements_with_interface("IORegister") - + def get_measurement_groups(self): return self.get_elements_with_interface("MeasurementGroup") - + def get_exp_channels(self): return self.get_elements_with_interface("ExpChannel") - + def get_counter_timers(self): return self.get_elements_with_interface("CTExpChannel") - + def get_0d_exp_channels(self): return self.get_elements_with_interface("ZeroDExpChannel") - + def get_1d_exp_channels(self): return self.get_elements_with_interface("OneDExpChannel") - + def get_2d_exp_channels(self): return self.get_elements_with_interface("TwoDExpChannel") - + def get_pseudo_counters(self): return self.get_elements_with_interface("PseudoCounter") - + def get_instruments(self): return self.get_elements_with_interface("Instrument") - + def get_controller(self, name): return self.get_element_with_interface(name, "Controller") - + def get_moveable(self, name): return self.get_element_with_interface(name, "Moveable") - + def get_motor(self, name): return self.get_element_with_interface(name, "Motor") - + def get_pseudo_motor(self, name): return self.get_element_with_interface(name, "PseudoMotor") - + def get_io_register(self, name): return self.get_element_with_interface(name, "IORegister") - + def get_measurement_group(self, name): return self.get_element_with_interface(name, "MeasurementGroup") - + def get_exp_channel(self, name): return self.get_element_with_interface(name, "ExpChannel") - + def get_counter_timer(self, name): return self.get_element_with_interface(name, "CTExpChannel") - + def get_0d_exp_channel(self, name): return self.get_element_with_interface(name, "ZeroDExpChannel") - + def get_1d_exp_channel(self, name): return self.get_element_with_interface(name, "OneDExpChannel") - + def get_2d_exp_channel(self, name): return self.get_element_with_interface(name, "TwoDExpChannel") - + def get_pseudo_counter(self, name): return self.get_element_with_interface(name, "PseudoCounter") - + def get_instrument(self, name): return self.get_element_with_interface(name, "Instrument") diff --git a/src/sardana/macroserver/msbase.py b/src/sardana/macroserver/msbase.py index 726259bac8..959c1781c7 100644 --- a/src/sardana/macroserver/msbase.py +++ b/src/sardana/macroserver/msbase.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -54,7 +54,7 @@ def serialize(self, *args, **kwargs): return kwargs macro_server = property(get_macro_server, - doc="reference to the :class:`sardana.macroserver.macroserver.MacroServer`") + doc="reference to the :class:`sardana.macroserver.macroserver.MacroServer`") class MSObject(SardanaObjectID, MSBaseObject): diff --git a/src/sardana/macroserver/mscontainer.py b/src/sardana/macroserver/mscontainer.py index 58ca2090ab..f32d8a1d2e 100644 --- a/src/sardana/macroserver/mscontainer.py +++ b/src/sardana/macroserver/mscontainer.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/msdoor.py b/src/sardana/macroserver/msdoor.py index fa734aa757..73e3b60361 100644 --- a/src/sardana/macroserver/msdoor.py +++ b/src/sardana/macroserver/msdoor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -132,8 +132,8 @@ def get_running_macro(self): def get_macro_data(self): macro = self.running_macro if macro is None: - raise MacroServerException("No macro has run so far " + \ - "or the macro data was not preserved.") + raise MacroServerException("No macro has run so far " + + "or the macro data was not preserved.") data = macro.data return data @@ -210,7 +210,7 @@ def input(self, msg, *args, **kwargs): input_data.update(kwargs) data_type = kwargs['data_type'] is_seq = not isinstance(data_type, (str, unicode)) and \ - isinstance(data_type, collections.Sequence) + isinstance(data_type, collections.Sequence) if is_seq: handle = self._handle_seq_input else: @@ -373,11 +373,11 @@ def output(loggable, msg, *args, **kw): formatter = logging.Formatter(fmt="%(message)s") Logger.setLogFormat("%(message)s") handler = logging.StreamHandler(stream=sys.stdout) - #handler.addFilter(filter) + # handler.addFilter(filter) Logger.addRootLogHandler(handler) - #handler.setFormatter(formatter) - #logger.addHandler(handler) - #logger.addFilter(filter) + # handler.setFormatter(formatter) + # logger.addHandler(handler) + # logger.addFilter(filter) self.__logging_info = handler, filter, formatter # result of a macro diff --git a/src/sardana/macroserver/msenvmanager.py b/src/sardana/macroserver/msenvmanager.py index 9ebbe41fd4..35977f461f 100644 --- a/src/sardana/macroserver/msenvmanager.py +++ b/src/sardana/macroserver/msenvmanager.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/msexception.py b/src/sardana/macroserver/msexception.py index 66c6e5c531..ca2ac2e22b 100644 --- a/src/sardana/macroserver/msexception.py +++ b/src/sardana/macroserver/msexception.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/msmacromanager.py b/src/sardana/macroserver/msmacromanager.py index c655db70e8..4dc88995d1 100644 --- a/src/sardana/macroserver/msmacromanager.py +++ b/src/sardana/macroserver/msmacromanager.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -44,7 +44,7 @@ from taurus.external.ordereddict import OrderedDict from taurus.core.util.log import Logger -from taurus.core.util.codecs import CodecFactory +from taurus.core.util.codecs import CodecFactory from sardana.sardanadefs import ElementType from sardana.sardanamodulemanager import ModuleManager @@ -62,7 +62,8 @@ MacroServerException, UnknownEnv # These classes are imported from the "client" part of sardana, if finally -# both the client and the server side needs them, place them in some common location +# both the client and the server side needs them, place them in some +# common location from sardana.taurus.core.tango.sardana.macro import createMacroNode _BASE_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -71,7 +72,8 @@ def islambda(f): """inspect doesn't come with islambda so I create one :-P""" return inspect.isfunction(f) and \ - f.__name__ == (lambda: True).__name__ + f.__name__ == (lambda: True).__name__ + def is_macro(macro, abs_file=None, logger=None): """Helper function to determine if a certain python object is a valid @@ -126,6 +128,7 @@ def is_macro(macro, abs_file=None, logger=None): return False return True + def recur_map(fun, data, keep_none=False): """Recursive map. Similar to map, but maintains the list objects structure @@ -141,6 +144,7 @@ def recur_map(fun, data, keep_none=False): else: return fun(data) + def is_flat_list(obj): """Check if a given object is a flat list.""" if not isinstance(obj, list): @@ -150,6 +154,7 @@ def is_flat_list(obj): return False return True + class MacroManager(MacroServerManager): DEFAULT_MACRO_DIRECTORIES = os.path.join(_BASE_DIR, 'macros'), @@ -188,7 +193,7 @@ def cleanUp(self): if self.is_cleaned(): return - #if self._modules: + # if self._modules: # ModuleManager().unloadModules(self._modules.keys()) self._macro_path = None @@ -208,7 +213,7 @@ class A != class A).""" p.extend(item.split(":")) # filter empty and commented paths - p = [ i for i in p if i and not i.startswith("#") ] + p = [i for i in p if i and not i.startswith("#")] # add basic macro directories for macro_dir in self.DEFAULT_MACRO_DIRECTORIES: @@ -307,13 +312,14 @@ def getOrCreateMacroLib(self, lib_name, macro_name=None): code = f.read() f.close() else: - # if given macro name + # if given macro name if macro_lib is None: f_name, code, line_nb = self.createMacro(lib_name, macro_name) else: macro = macro_lib.get_macro(macro_name) if macro is None: - f_name, code, line_nb = self.createMacro(lib_name, macro_name) + f_name, code, line_nb = self.createMacro( + lib_name, macro_name) else: _, line_nb = macro.code f_name = macro.file_path @@ -321,7 +327,7 @@ def getOrCreateMacroLib(self, lib_name, macro_name=None): code = f.read() f.close() - return [ f_name, code, line_nb ] + return [f_name, code, line_nb] def setMacroLib(self, lib_name, code, auto_reload=True): f_name = self._fromNameToFileName(lib_name) @@ -340,7 +346,8 @@ def createMacroLib(self, lib_name, path=None): f_name = self._fromNameToFileName(lib_name, path) if os.path.exists(f_name): - raise Exception("Unable to create macro lib: '%s' already exists" % f_name) + raise Exception( + "Unable to create macro lib: '%s' already exists" % f_name) f = open(f_name, 'w') f.close() @@ -359,7 +366,8 @@ def createMacro(self, lib_name, macro_name): template += '\n' t = open(f_name, 'rU') line_nb = -1 - for line_nb, _ in enumerate(t): pass + for line_nb, _ in enumerate(t): + pass line_nb += 3 t.close() @@ -374,7 +382,8 @@ def createMacro(self, lib_name, macro_name): template += f_templ.read() f_templ.close() except: - self.debug("Failed to open template macro file. Using simplified template") + self.debug( + "Failed to open template macro file. Using simplified template") template += MACRO_TEMPLATE if f_templ: f_templ.close() @@ -429,7 +438,8 @@ def reloadMacroLibs(self, module_names, path=None): ret = [] for module_name in module_names: m = self.reloadMacroLib(module_name, path=path) - if m: ret.append(m) + if m: + ret.append(m) return ret def reloadLib(self, module_name, path=None): @@ -446,7 +456,7 @@ def reloadLib(self, module_name, path=None): if module_name in self._modules: raise LibraryError("Cannot use simple " + "reload to reload a Macro Library") - + mod_manager = ModuleManager() return mod_manager.reloadModule(module_name, path=None) @@ -578,7 +588,7 @@ def getMacros(self, filter=None): continue ret[name] = macro return ret - + def getMacroClasses(self, filter=None): """Returns a :obj:`dict` containing information about macro classes. @@ -612,7 +622,7 @@ def getMacroFunctions(self, filter=None): if macro.get_type() == ElementType.MacroFunction: macro_classes[name] = macro return macro_classes - + def getMacroNames(self): return sorted(self._macro_dict.keys()) @@ -666,7 +676,7 @@ def getMacroInfo(self, macro_names, format='json'): macro_meta = self.getMacro(macro_name) ret.append(json_codec.encode(('', macro_meta.serialize()))[1]) return ret - + def _createMacroNode(self, macro_name, macro_params): macro = self.getMacro(macro_name) params_def = macro.get_parameter() @@ -697,7 +707,7 @@ def decodeMacroParameters(self, door, raw_params): # execMacro("mv", mot01, 0.0) and parameters definition allows to # decode it from a flat list we give it a try if (is_flat_list(raw_params) and - FlatParamDecoder.isPossible(params_def)): + FlatParamDecoder.isPossible(params_def)): self.debug("Trying flat parameter decoder due to: %s" % out_e) try: out_par_list = FlatParamDecoder(type_manager, params_def, @@ -732,7 +742,8 @@ def prepareMacro(self, macro_class, par_list, init_opts={}, prepare_opts={}): The return value is a tuple (MacroObject, return value of prepare) """ macro = self.createMacroObj(macro_class, par_list, init_opts=init_opts) - prepare_result = self.prepareMacroObj(macro, par_list, prepare_opts=prepare_opts) + prepare_result = self.prepareMacroObj( + macro, par_list, prepare_opts=prepare_opts) return macro, prepare_result def createMacroObj(self, macro_class, par_list, init_opts={}): @@ -746,14 +757,14 @@ def createMacroObj(self, macro_class, par_list, init_opts={}): if not environment.has_env(env): r.append(env) if r: - raise MissingEnv("The macro %s requires the following missing " \ + raise MissingEnv("The macro %s requires the following missing " "environment to be defined: %s" % (macro_name, str(r))) macro_opts = { 'no_exec': True, - 'create_thread' : True, - 'external_prepare' : True + 'create_thread': True, + 'external_prepare': True } macro_opts.update(init_opts) @@ -775,7 +786,7 @@ def createMacroObjFromMeta(self, meta, par_list, init_opts={}): r.append(env) if r: macro_name = meta.name - raise MissingEnv("The macro %s requires the following missing " \ + raise MissingEnv("The macro %s requires the following missing " "environment to be defined: %s" % (macro_name, str(r))) @@ -801,6 +812,7 @@ class MacroExecutor(Logger): """ """ class RunSubXMLHook: + def __init__(self, me, xml): self._me = me self._xml = xml @@ -854,7 +866,7 @@ def macro_manager(self): def getNewMacroID(self): self._macro_counter -= 1 return self._macro_counter - + def _createMacroNode(self, macro_name, macro_params): return self.macro_manager._createMacroNode(macro_name, macro_params) @@ -909,7 +921,7 @@ def __preprocessResult(self, result): def _decodeMacroParameters(self, params): return self.macro_manager.decodeMacroParameters(self.door, params) - + def _composeMacroLine(self, macro_name, macro_params, macro_id): # recursive map to maintain the list objects structure params_str_list = recur_map(str, macro_params) @@ -917,7 +929,8 @@ def _composeMacroLine(self, macro_name, macro_params, macro_id): params_str_list = map(str, params_str_list) params_str = ', '.join(params_str_list) macro_id = macro_id - # create macro_line - string representation of macro, its parameters and id + # create macro_line - string representation of macro, its parameters + # and id macro_line = "%s(%s) -> %s" % (macro_name, params_str, macro_id) return macro_line @@ -927,9 +940,9 @@ def _prepareXMLMacro(self, xml_macro, parent_macro=None): macro_id = xml_macro.get("id") macro_line = self._composeMacroLine(macro_name, macro_params, macro_id) init_opts = { - 'id' : macro_id, - 'macro_line' : macro_line, - 'parent_macro' : parent_macro, + 'id': macro_id, + 'macro_line': macro_line, + 'parent_macro': parent_macro, } macro_obj = self._createMacroObj(macro_meta, macro_params, init_opts) @@ -937,10 +950,10 @@ def _prepareXMLMacro(self, xml_macro, parent_macro=None): hook = MacroExecutor.RunSubXMLHook(self, macro) hook_hints = macro.findall('hookPlace') if hook_hints is None: - macro_obj.hooks = [ hook ] + macro_obj.hooks = [hook] else: - hook_places = [ h.text for h in hook_hints ] - macro_obj.hooks = [ (hook, hook_places) ] + hook_places = [h.text for h in hook_hints] + macro_obj.hooks = [(hook, hook_places)] prepare_result = self._prepareMacroObj(macro_obj, macro_params) return macro_obj, prepare_result @@ -950,8 +963,8 @@ def _createMacroObj(self, macro_name_or_meta, pars, init_opts={}): macro_meta = self.macro_manager.getMacro(macro_meta) macro_opts = { - 'executor' : self, - 'environment' : self.macro_server + 'executor': self, + 'environment': self.macro_server } macro_opts.update(init_opts) if not macro_opts.has_key('id'): @@ -977,8 +990,10 @@ def prepareMacroObj(self, macro_name_or_meta, pars, init_opts={}, :param prepare_opts: keyword parameters for the macro prepare :return: a tuple of two elements: macro object, the result of preparing the macro""" - macroObj = self._createMacroObj(macro_name_or_meta, pars, init_opts=init_opts) - prepare_result = self._prepareMacroObj(macroObj, pars, prepare_opts=prepare_opts) + macroObj = self._createMacroObj( + macro_name_or_meta, pars, init_opts=init_opts) + prepare_result = self._prepareMacroObj( + macroObj, pars, prepare_opts=prepare_opts) return macroObj, prepare_result def prepareMacro(self, pars, init_opts={}, prepare_opts={}): @@ -1051,7 +1066,7 @@ def prepareMacro(self, pars, init_opts={}, prepare_opts={}): init_opts['macro_line'] = macro_line - return self.prepareMacroObj(meta_macro, macro_params, init_opts, + return self.prepareMacroObj(meta_macro, macro_params, init_opts, prepare_opts) def getRunningMacro(self): @@ -1161,11 +1176,11 @@ def run(self, params, asynch=True): if asynch: # start the job of actually running the macro self.macro_server.add_job(self.__runXML, self._jobEnded) - #return the proper xml + # return the proper xml return self._xml else: self.__runXML() - #return self._macro_pointer.getResult() + # return self._macro_pointer.getResult() def _jobEnded(self, *args, **kw): self.debug("Job ended (stopped=%s, aborted=%s)", @@ -1248,17 +1263,17 @@ def runMacro(self, macro_obj): mse.traceback = traceback.format_exc() except DevFailed as df: exc_info = sys.exc_info() - exp_pars = {'type' : df[0].reason, - 'msg' : df[0].desc, - 'args' : df.args, - 'traceback' : traceback.format_exc() } + exp_pars = {'type': df[0].reason, + 'msg': df[0].desc, + 'args': df.args, + 'traceback': traceback.format_exc()} macro_exp = MacroServerException(exp_pars) except Exception, err: exc_info = sys.exc_info() - exp_pars = {'type' : err.__class__.__name__, - 'msg' : str(err), - 'args' : err.args, - 'traceback' : traceback.format_exc() } + exp_pars = {'type': err.__class__.__name__, + 'msg': str(err), + 'args': err.args, + 'traceback': traceback.format_exc()} macro_exp = MacroServerException(exp_pars) finally: self.returnObjs(self._macro_pointer) @@ -1278,24 +1293,26 @@ def runMacro(self, macro_obj): if macro_exp is not None: if not self._stopped and not self._aborted: self.sendMacroStatusException(exc_info) - self.debug("[ENDEX] (%s) runMacro %s" % (macro_exp.__class__.__name__, name)) + self.debug("[ENDEX] (%s) runMacro %s" % + (macro_exp.__class__.__name__, name)) if isinstance(macro_exp, MacroServerException) and macro_obj.parent_macro is None: door.debug(macro_exp.traceback) - door.error("An error occurred while running %s:\n%s" % (macro_obj.description, macro_exp.msg)) + door.error("An error occurred while running %s:\n%s" % + (macro_obj.description, macro_exp.msg)) self._popMacro() raise macro_exp self.debug("[ END ] runMacro %s" % desc) self._popMacro() - + # decide whether to preserve the macro data - env_var_name = 'PreserveMacroData' + env_var_name = 'PreserveMacroData' try: preserve_macro_data = macro_obj.getEnv(env_var_name) except UnknownEnv: preserve_macro_data = True if not preserve_macro_data: - self.debug('Macro data will not be preserved. ' + \ - 'Set "%s" environment variable ' % env_var_name + \ + self.debug('Macro data will not be preserved. ' + + 'Set "%s" environment variable ' % env_var_name + 'to True in order to change it.') self._macro_pointer = None @@ -1306,7 +1323,7 @@ def _popMacro(self): length = len(self._macro_stack) if length > 0: self._macro_pointer = self._macro_stack[-1] - + def sendState(self, state): return self.door.set_state(state) @@ -1376,7 +1393,8 @@ def sendRecordData(self, data, codec=None): return self.door.set_record_data(data, codec=codec) def reserveObj(self, obj, macro_obj, priority=0): - if obj is None or macro_obj is None: return + if obj is None or macro_obj is None: + return # Fill _reserved_macro_objs objs = self._reserved_macro_objs[macro_obj] = \ @@ -1392,13 +1410,16 @@ def reserveObj(self, obj, macro_obj, priority=0): macros.add(macro_obj) # Tell the object that it is reserved by a new macro - if hasattr(obj, 'reserve'): obj.reserve(macro_obj) + if hasattr(obj, 'reserve'): + obj.reserve(macro_obj) def returnObjs(self, macro_obj): """Free the macro reserved objects""" - if macro_obj is None: return + if macro_obj is None: + return objs = self._reserved_macro_objs.get(macro_obj) - if objs is None: return + if objs is None: + return # inside returnObj we change the list so we have to iterate with a copy for obj in copy.copy(objs): @@ -1406,9 +1427,11 @@ def returnObjs(self, macro_obj): def returnObj(self, obj, macro_obj): """Free an object reserved by a macro""" - if obj is None or macro_obj is None: return + if obj is None or macro_obj is None: + return - if hasattr(obj, 'unreserve'): obj.unreserve() + if hasattr(obj, 'unreserve'): + obj.unreserve() objs = self._reserved_macro_objs.get(macro_obj) if objs is None: return diff --git a/src/sardana/macroserver/msmanager.py b/src/sardana/macroserver/msmanager.py index f31fdf8255..e36710e503 100644 --- a/src/sardana/macroserver/msmanager.py +++ b/src/sardana/macroserver/msmanager.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/msmetamacro.py b/src/sardana/macroserver/msmetamacro.py index 8a624df7cf..9f7b30d959 100644 --- a/src/sardana/macroserver/msmetamacro.py +++ b/src/sardana/macroserver/msmetamacro.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -62,10 +62,11 @@ def @macro_name@(self): """ + class MacroLibrary(SardanaLibrary): """Object representing a python module containing macro classes and/or macro functions. Public members: - + - module - reference to python module - file_path - complete (absolute) path (with file name at the end) - file_name - file name (including file extension) @@ -289,7 +290,7 @@ def to_parameter_definition(self): i -= 1 else: param_def.append( - (varargs , [[ varargs, Type.Any, None, varargs + " parameter"]], + (varargs, [[varargs, Type.Any, None, varargs + " parameter"]], None, "list of " + varargs)) return param_def @@ -305,4 +306,3 @@ def get_result_definition(self): def get_hints_definition(self): return self.function.hints or () - diff --git a/src/sardana/macroserver/msmetarecorder.py b/src/sardana/macroserver/msmetarecorder.py index 577748b3c3..9b0c5a6d2c 100644 --- a/src/sardana/macroserver/msmetarecorder.py +++ b/src/sardana/macroserver/msmetarecorder.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/msoptions.py b/src/sardana/macroserver/msoptions.py index def2573497..271404514d 100644 --- a/src/sardana/macroserver/msoptions.py +++ b/src/sardana/macroserver/msoptions.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -41,8 +41,8 @@ class ViewOption(object): __metaclass__ = ViewOptionMeta _DEFAULT_VIEW_OPTIONS = { - 'ShowDial' : True, - 'ShowCtrlAxis' : False, + 'ShowDial': True, + 'ShowCtrlAxis': False, 'PosFormat': -1, 'OutputBlock': False } @@ -62,6 +62,4 @@ def reset_option(cls, d, name): if name in cls._DEFAULT_VIEW_OPTIONS: d[name] = cls._DEFAULT_VIEW_OPTIONS[name] else: - del d[name] - - + del d[name] diff --git a/src/sardana/macroserver/msparameter.py b/src/sardana/macroserver/msparameter.py index b81d0981ce..751526c2b6 100644 --- a/src/sardana/macroserver/msparameter.py +++ b/src/sardana/macroserver/msparameter.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -165,6 +165,7 @@ def serialize(self, *args, **kwargs): class ParamRepeat(object): # opts: min, max + def __init__(self, *param_def, **opts): self.param_def = param_def self.opts = {'min': 1, 'max': None} @@ -214,7 +215,7 @@ def getObj(self, name, pool=ParamType.All, cache=False): except UnknownMacroLibrary: pass # neither pool nor macroserver contains any element with this name - raise UnknownParamObj('%s with name %s does not exist' % \ + raise UnknownParamObj('%s with name %s does not exist' % (self._name, name)) def getObjDict(self, pool=ParamType.All, cache=False): @@ -287,7 +288,7 @@ def getObj(self, name, pool=ParamType.All, cache=False): except UnknownMacroLibrary: pass # neither pool nor macroserver contains any element with this name - raise UnknownParamObj('%s with name %s does not exist' % \ + raise UnknownParamObj('%s with name %s does not exist' % (self._name, name)) def getObjDict(self, pool=ParamType.All, cache=False): @@ -438,7 +439,7 @@ def decodeRepeat(self, raw_param_repeat, param_repeat_def): msg = 'Found %d repetitions of param %s, min is %d' % \ (len_rep, name, min_rep) raise MissingRepeat, msg - if max_rep and len_rep > max_rep: + if max_rep and len_rep > max_rep: msg = 'Found %d repetitions of param %s, max is %d' % \ (len_rep, name, max_rep) raise SupernumeraryRepeat, msg @@ -460,7 +461,7 @@ def decodeRepeat(self, raw_param_repeat, param_repeat_def): # check if one tries to decode repeat parameter of just one # member encapsulated in a list, empty lists are still allowed # to indicate default value - elif isinstance(raw_repeat , list) and len(raw_repeat) > 0: + elif isinstance(raw_repeat, list) and len(raw_repeat) > 0: msg = 'Repetitions of just one member must not be lists' raise WrongParam, msg repeat = self.decodeNormal(raw_repeat, param_type[0]) @@ -479,6 +480,7 @@ class FlatParamDecoder: located at the very last place. It requires that the raw parameters are passed as a flat list of strings. """ + def __init__(self, type_manager, params_def, raw_params): self.type_manager = type_manager self.params_def = params_def diff --git a/src/sardana/macroserver/msrecordermanager.py b/src/sardana/macroserver/msrecordermanager.py index b2ecb4cffd..9acd9dc7a2 100644 --- a/src/sardana/macroserver/msrecordermanager.py +++ b/src/sardana/macroserver/msrecordermanager.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -181,7 +181,7 @@ def getRecorderMetaClasses(self, filter=None, extension=None): else: _map = self._scan_recorder_map if (extension in _map.keys() and - klass in _map[extension]): + klass in _map[extension]): ret[name] = klass else: ret[name] = klass diff --git a/src/sardana/macroserver/mstypemanager.py b/src/sardana/macroserver/mstypemanager.py index e33642737a..7aee3c1a11 100644 --- a/src/sardana/macroserver/mstypemanager.py +++ b/src/sardana/macroserver/mstypemanager.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -126,7 +126,7 @@ def addType(self, type_obj): mod_types = self._modules[module_name] - #action = (((type_name in mod_types) and "Updating") \ + # action = (((type_name in mod_types) and "Updating") \ # or "Adding") action = "Updating" self.debug("%s type %s", action, type_name) diff --git a/src/sardana/macroserver/recorders/__init__.py b/src/sardana/macroserver/recorders/__init__.py index 0ce403330a..763e6223f7 100644 --- a/src/sardana/macroserver/recorders/__init__.py +++ b/src/sardana/macroserver/recorders/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,4 +29,4 @@ from .sharedmemory import * from .storage import * -from .output import * \ No newline at end of file +from .output import * diff --git a/src/sardana/macroserver/recorders/examples/__init__.py b/src/sardana/macroserver/recorders/examples/__init__.py index e4160c89b7..6c114cea3c 100644 --- a/src/sardana/macroserver/recorders/examples/__init__.py +++ b/src/sardana/macroserver/recorders/examples/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/recorders/examples/dummy.py b/src/sardana/macroserver/recorders/examples/dummy.py index 686acfb364..584c53a11e 100644 --- a/src/sardana/macroserver/recorders/examples/dummy.py +++ b/src/sardana/macroserver/recorders/examples/dummy.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -33,6 +33,7 @@ from sardana.macroserver.scan.recorder import DataRecorder + class DumbRecorder(DataRecorder): def _startRecordList(self, recordlist): @@ -52,4 +53,4 @@ def _writeRecord(self, record): def _endRecordList(self, recordlist): print "Ending recording" env = recordlist.getEnviron() - print "Recording ended at: ", time.ctime(env['endtime']) \ No newline at end of file + print "Recording ended at: ", time.ctime(env['endtime']) diff --git a/src/sardana/macroserver/recorders/examples/xas.py b/src/sardana/macroserver/recorders/examples/xas.py index 4cf664e5ff..f95d9a5ae1 100644 --- a/src/sardana/macroserver/recorders/examples/xas.py +++ b/src/sardana/macroserver/recorders/examples/xas.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,59 +31,68 @@ from sardana.macroserver.scan.recorder import BaseNEXUS_FileRecorder + class NXxas_FileRecorder(BaseNEXUS_FileRecorder): """saves data to a nexus file that follows the NXsas application definition - + """ - + def __init__(self, filename=None, macro=None, overwrite=False, **pars): - BaseNEXUS_FileRecorder.__init__(self, filename=filename, macro=macro, overwrite=overwrite, **pars) - - + BaseNEXUS_FileRecorder.__init__( + self, filename=filename, macro=macro, overwrite=overwrite, **pars) + def _startRecordList(self, recordlist): nxs = self.nxs if self.filename is None: return - - #get the recordlist environment + + # get the recordlist environment self.currentlist = recordlist env = self.currentlist.getEnviron() - - #adapt the datadesc to the NeXus requirements + + # adapt the datadesc to the NeXus requirements self.datadesc = [] for dd in env['datadesc']: dd = dd.clone() dd.label = self.sanitizeName(dd.label) if dd.dtype == 'bool': dd.dtype = 'int8' - self.debug('%s will be stored with type=%s',dd.name,dd.dtype) + self.debug('%s will be stored with type=%s', dd.name, dd.dtype) if dd.dtype in self.supported_dtypes: self.datadesc.append(dd) else: - self.warning('%s will not be stored. Reason: type %s not supported',dd.name,dd.dtype) - - + self.warning( + '%s will not be stored. Reason: type %s not supported', dd.name, dd.dtype) + serialno = env["serialno"] nxfilemode = self.getFormat() - if not self.overwrite and os.path.exists(self.filename): nxfilemode='rw' - - self.debug("starting new recording %d on file %s", serialno, self.filename) - - #create an nxentry and write it to file - self.nxentry = nxs.NXentry(name= "entry%d" % serialno) + if not self.overwrite and os.path.exists(self.filename): + nxfilemode = 'rw' + + self.debug("starting new recording %d on file %s", + serialno, self.filename) + + # create an nxentry and write it to file + self.nxentry = nxs.NXentry(name="entry%d" % serialno) self.nxentry.save(self.filename, format=nxfilemode) - #add fields to nxentry + # add fields to nxentry import sardana.release - program_name = "%s (%s)" % (sardana.release.name, self.__class__.__name__) - self.nxentry.insert(nxs.NXfield(name='start_time', value=env['starttime'].isoformat())) + program_name = "%s (%s)" % ( + sardana.release.name, self.__class__.__name__) + self.nxentry.insert(nxs.NXfield(name='start_time', + value=env['starttime'].isoformat())) self.nxentry.insert(nxs.NXfield(name='title', value=env['title'])) self.nxentry.insert(nxs.NXfield(name='definition', value='NXxas')) - self.nxentry.insert(nxs.NXfield(name='epoch', value=time.mktime(env['starttime'].timetuple()))) - self.nxentry.insert(nxs.NXfield(name='program_name', value=program_name, attrs={'version':sardana.release.version})) - self.nxentry.insert(nxs.NXfield(name='entry_identifier', value=env['serialno'])) - - #add the "measurement" group (a NXcollection containing all counters from the mntgrp for convenience) + self.nxentry.insert(nxs.NXfield( + name='epoch', value=time.mktime(env['starttime'].timetuple()))) + self.nxentry.insert(nxs.NXfield(name='program_name', value=program_name, attrs={ + 'version': sardana.release.version})) + self.nxentry.insert(nxs.NXfield( + name='entry_identifier', value=env['serialno'])) + + # add the "measurement" group (a NXcollection containing all counters + # from the mntgrp for convenience) measurement = nxs.NXcollection(name='measurement') self.ddfieldsDict = {} for dd in self.datadesc: @@ -92,71 +101,78 @@ def _startRecordList(self, recordlist): shape=[nxs.UNLIMITED] + list(dd.shape), nxslab_dims=[1] + list(dd.shape) ) - if hasattr(dd,'data_units'): + if hasattr(dd, 'data_units'): field.attrs['units'] = dd.data_units measurement.insert(field) - #create a dict of fields in the datadesc for easier access later on + # create a dict of fields in the datadesc for easier access later + # on self.ddfieldsDict[dd.label] = field - + self.nxentry.insert(measurement) - - #user group + + # user group nxuser = nxs.NXuser() self.nxentry.insert(nxuser) nxuser['name'] = env['user'] - #sample group + # sample group nxsample = nxs.NXsample() self.nxentry.insert(nxsample) - nxsample['name'] = env['SampleInfo'].get('name','Unknown') - - #monitor group + nxsample['name'] = env['SampleInfo'].get('name', 'Unknown') + + # monitor group scan_acq_time = env.get('integ_time') - scan_monitor_mode = scan_acq_time>1 and 'timer' or 'monitor' + scan_monitor_mode = scan_acq_time > 1 and 'timer' or 'monitor' nxmonitor = nxs.NXmonitor(mode=scan_monitor_mode, - preset=scan_acq_time) + preset=scan_acq_time) self.nxentry.insert(nxmonitor) - monitor_data = self.ddfieldsDict[self.sanitizeName(env['monitor'])] #to be linked later on - - #instrument group + monitor_data = self.ddfieldsDict[self.sanitizeName( + env['monitor'])] # to be linked later on + + # instrument group nxinstrument = nxs.NXinstrument() self.nxentry.insert(nxinstrument) - - #monochromator group + + # monochromator group nxmonochromator = nxs.NXmonochromator() nxinstrument.insert(nxmonochromator) - energy_data = self.ddfieldsDict[self.sanitizeName(env['monochromator'])] #to be linked later on - - #incoming_beam group + energy_data = self.ddfieldsDict[self.sanitizeName( + env['monochromator'])] # to be linked later on + + # incoming_beam group nxincoming_beam = nxs.NXdetector(name='incoming_beam') nxinstrument.insert(nxincoming_beam) - incbeam_data = self.ddfieldsDict[self.sanitizeName(env['incbeam'])] #to be linked later on - - #absorbed_beam group + incbeam_data = self.ddfieldsDict[self.sanitizeName( + env['incbeam'])] # to be linked later on + + # absorbed_beam group nxabsorbed_beam = nxs.NXdetector(name='absorbed_beam') nxinstrument.insert(nxabsorbed_beam) - absbeam_data = self.ddfieldsDict[self.sanitizeName(env['absbeam'])] #to be linked later on + absbeam_data = self.ddfieldsDict[self.sanitizeName( + env['absbeam'])] # to be linked later on absbeam_data.attrs['signal'] = '1' absbeam_data.attrs['axes'] = 'energy' - - #source group + + # source group nxsource = nxs.NXsource() - nxinstrument.insert(nxsource) - nxinstrument['source']['name'] = env.get('SourceInfo',{}).get('name','Unknown') - nxinstrument['source']['type'] = env.get('SourceInfo',{}).get('type','Unknown') - nxinstrument['source']['probe'] = env.get('SourceInfo',{}).get('x-ray','Unknown') - - #data group + nxinstrument.insert(nxsource) + nxinstrument['source']['name'] = env.get( + 'SourceInfo', {}).get('name', 'Unknown') + nxinstrument['source']['type'] = env.get( + 'SourceInfo', {}).get('type', 'Unknown') + nxinstrument['source']['probe'] = env.get( + 'SourceInfo', {}).get('x-ray', 'Unknown') + + # data group nxdata = nxs.NXdata() self.nxentry.insert(nxdata) - - + #@todo create the PreScanSnapshot - #self._createPreScanSnapshot(env) - - #write everything to file - self.nxentry.write() - + # self._createPreScanSnapshot(env) + + # write everything to file + self.nxentry.write() + #@todo: do this with the PyTree api instead(how to do named links with the PyTree API????) self._nxln(monitor_data, nxmonitor, name='data') self._nxln(incbeam_data, nxincoming_beam, name='data') @@ -164,28 +180,27 @@ def _startRecordList(self, recordlist): self._nxln(energy_data, nxmonochromator, name='energy') self._nxln(energy_data, nxdata, name='energy') self._nxln(absbeam_data, nxdata, name='absorbed_beam') - + self.nxentry.nxfile.flush() - - + def _writeRecord(self, record): # most used variables in the loop fd, debug, warning = self.nxentry.nxfile, self.debug, self.warning nparray, npshape = numpy.array, numpy.shape rec_data, rec_nb = record.data, record.recordno - + for dd in self.datadesc: - if record.data.has_key( dd.name ): + if record.data.has_key(dd.name): data = rec_data[dd.name] field = self.ddfieldsDict[dd.label] - + if data is None: data = numpy.zeros(dd.shape, dtype=dd.dtype) if not hasattr(data, 'shape'): data = nparray([data], dtype=dd.dtype) elif dd.dtype != data.dtype.name: debug('%s casted to %s (was %s)', dd.label, dd.dtype, - data.dtype.name) + data.dtype.name) data = data.astype(dd.dtype) slab_offset = [rec_nb] + [0] * len(dd.shape) @@ -200,35 +215,36 @@ def _writeRecord(self, record): debug("missing data for label '%s'", dd.label) self.nxentry.nxfile.flush() - def _endRecordList(self, recordlist): - env=self.currentlist.getEnviron() - self.nxentry.insert(nxs.NXfield(name='end_time', value=env['endtime'].isoformat())) - #self._populateInstrumentInfo() - #self._createNXData() + env = self.currentlist.getEnviron() + self.nxentry.insert(nxs.NXfield( + name='end_time', value=env['endtime'].isoformat())) + # self._populateInstrumentInfo() + # self._createNXData() self.nxentry.write() self.nxentry.nxfile.flush() - self.debug("Finishing recording %d on file %s:", env['serialno'], self.filename) + self.debug("Finishing recording %d on file %s:", + env['serialno'], self.filename) return - -#=============================================================================== +#========================================================================= # BEGIN: THIS BLOCK SHOULD BE REMOVED IF NEXUS ACCEPTS THE PATCH TO NXfield -#=============================================================================== +#========================================================================= try: - from nxs import NXfield #needs Nexus v>=4.3 + from nxs import NXfield # needs Nexus v>=4.3 from nxs import napi, NeXusError - + class NXfield_comp(NXfield): - - #NOTE: THE CONSTRUCTOR IS OPTIONAL. IF NOT IMPLEMENTED, WE CAN STILL USE THE nxslab_dims PROPERTY + + # NOTE: THE CONSTRUCTOR IS OPTIONAL. IF NOT IMPLEMENTED, WE CAN STILL + # USE THE nxslab_dims PROPERTY def __init__(self, value=None, name='field', dtype=None, shape=(), group=None, attrs={}, nxslab_dims=None, **attr): NXfield.__init__(self, value=value, name=name, dtype=dtype, shape=shape, group=group, - attrs=attrs, **attr) + attrs=attrs, **attr) self._slab_dims = nxslab_dims - + def write(self): """ Write the NXfield, including attributes, to the NeXus file. @@ -238,17 +254,18 @@ def write(self): raise NeXusError("NeXus file is readonly") if not self.infile: shape = self.shape - if shape == (): shape = (1,) + if shape == (): + shape = (1,) with self.nxgroup as path: if self.nxslab_dims is not None: - #compress - path.compmakedata(self.nxname, self.dtype, shape, 'lzw', + # compress + path.compmakedata(self.nxname, self.dtype, shape, 'lzw', self.nxslab_dims) else: - # Don't use compression + # Don't use compression path.makedata(self.nxname, self.dtype, shape) self._infile = True - if not self.saved: + if not self.saved: with self as path: path._writeattrs(self.attrs) value = self.nxdata @@ -257,25 +274,27 @@ def write(self): self._saved = True else: raise IOError("Data is not attached to a file") - + def _getnxslabdims(self): try: return self._nxslab_dims except: slab_dims = None - #even if slab_dims have not been set, check if the dataset is large + # even if slab_dims have not been set, check if the dataset is + # large shape = self.shape or (1,) if numpy.prod(shape) > 10000: - slab_dims = numpy.ones(len(shape),'i') + slab_dims = numpy.ones(len(shape), 'i') slab_dims[-1] = min(shape[-1], 100000) return slab_dims - + def _setnxslabdims(self, slab_dims): self._nxslab_dims = slab_dims - - nxslab_dims = property(_getnxslabdims,_setnxslabdims,doc="Slab (a.k.a. chunk) dimensions for compression") + + nxslab_dims = property(_getnxslabdims, _setnxslabdims, + doc="Slab (a.k.a. chunk) dimensions for compression") except: - pass #NXxas_FileRecorder won't be usable + pass # NXxas_FileRecorder won't be usable #============================================================================== diff --git a/src/sardana/macroserver/recorders/output.py b/src/sardana/macroserver/recorders/output.py index 155256ac43..0cb0273b7d 100644 --- a/src/sardana/macroserver/recorders/output.py +++ b/src/sardana/macroserver/recorders/output.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -42,6 +42,7 @@ class JsonRecorder(DataRecorder): + def __init__(self, stream, cols=None, **pars): DataRecorder.__init__(self, **pars) self._stream = stream @@ -57,7 +58,8 @@ def _startRecordList(self, recordlist): column_desc = recordlist.getEnvironValue('datadesc') ref_moveables = recordlist.getEnvironValue('ref_moveables') estimatedtime = recordlist.getEnvironValue('estimatedtime') - total_scan_intervals = recordlist.getEnvironValue('total_scan_intervals') + total_scan_intervals = recordlist.getEnvironValue( + 'total_scan_intervals') start_time = recordlist.getEnvironValue('starttime').ctime() self.column_desc = [] discarded = [] @@ -84,8 +86,8 @@ def _startRecordList(self, recordlist): def _endRecordList(self, recordlist): macro_id = recordlist.getEnvironValue('macro_id') - data = { 'endtime' : recordlist.getEnvironValue('endtime').ctime(), - 'deadtime' : recordlist.getEnvironValue('deadtime') } + data = {'endtime': recordlist.getEnvironValue('endtime').ctime(), + 'deadtime': recordlist.getEnvironValue('deadtime')} self._sendPacket(type="record_end", data=data, macro_id=macro_id) def _writeRecord(self, record): @@ -100,7 +102,7 @@ def _sendPacket(self, **kwargs): '''creates a JSON packet using the keyword arguments passed and then sends it''' #data = self._codec.encode(('', kwargs)) - #self._stream.sendRecordData(*data) + # self._stream.sendRecordData(*data) self._stream._sendRecordData(kwargs, codec='json') def _addCustomData(self, value, name, **kwargs): @@ -109,7 +111,7 @@ def _addCustomData(self, value, name, **kwargs): and its data will be the dictionary of keyword arguments passed to this method plus 'name' and 'value' ''' - #try to convert to list to avoid serialization problems + # try to convert to list to avoid serialization problems try: value = value.tolist() except: @@ -156,7 +158,8 @@ def _startRecordList(self, recordlist): for fr in [r for r in dh.recorders if isinstance(r, BaseFileRecorder)]: if not hasattr(self._stream, "getAllEnv") or \ "ScanRecorder" in self._stream.getAllEnv().keys(): - message = "%s from %s" % (fr.getFormat(), fr.__class__.__name__) + message = "%s from %s" % ( + fr.getFormat(), fr.__class__.__name__) else: message = "%s" % (fr.getFormat()) self._stream.info('Operation will be saved in %s (%s)', @@ -213,7 +216,8 @@ def _startRecordList(self, recordlist): cell_t_number = '%%%%(%%s)%s' % number_fmt[1:] self._scan_line_t = [(col_names[0], '%%(%s)8d' % col_names[0])] - self._scan_line_t += [(name, cell_t_number % name) for name in col_names[1:]] + self._scan_line_t += [(name, cell_t_number % name) + for name in col_names[1:]] self._stream._output(header) self._stream._flushOutput() @@ -230,7 +234,7 @@ def _endRecordList(self, recordlist): dh = recordlist.getDataHandler() - for fr in [ r for r in dh.recorders if isinstance(r, BaseFileRecorder) ]: + for fr in [r for r in dh.recorders if isinstance(r, BaseFileRecorder)]: self._stream.info('Operation saved in %s (%s)', fr.getFileName(), fr.getFormat()) diff --git a/src/sardana/macroserver/recorders/sharedmemory.py b/src/sardana/macroserver/recorders/sharedmemory.py index d913d95080..8ba8ed7868 100644 --- a/src/sardana/macroserver/recorders/sharedmemory.py +++ b/src/sardana/macroserver/recorders/sharedmemory.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -50,7 +50,7 @@ def __init__(self, program=None, array=None, shape=None, **kwpars): """ BaseSharedMemoryRecorder.__init__(self, **kwpars) try: - import sps #check if sps format is supported by this system + import sps # check if sps format is supported by this system self.sps = sps except ImportError: raise Exception("SPS is not available") @@ -78,21 +78,25 @@ def setSize(self, rows, cols): self.cols = cols def isInitialized(self): - ret = not (self.program is None or self.array_ENV is None or self.array is None) + ret = not ( + self.program is None or self.array_ENV is None or self.array is None) return ret and not self.shape is None def putEnv(self, name, value): - if not self.isInitialized(): return + if not self.isInitialized(): + return self.sps.putenv(self.program, self.array_ENV, name, str(value)) def putAllEnv(self, d): - if not self.isInitialized(): return + if not self.isInitialized(): + return p, a = self.program, self.array_ENV for k, v in d.iteritems(): self.sps.putenv(p, a, k, str(v)) def _startRecordList(self, recordlist): - if not self.isInitialized(): return + if not self.isInitialized(): + return arraylist = self.sps.getarraylist(self.program) @@ -100,38 +104,40 @@ def _startRecordList(self, recordlist): shm = self.sps.attach(self.program, self.array) else: cols, rows = self.shape - self.sps.create(self.program, self.array, rows, cols, self.sps.DOUBLE) + self.sps.create(self.program, self.array, + rows, cols, self.sps.DOUBLE) self.owner = True if self.array_ENV in arraylist: shm_env = self.sps.attach(self.program, self.array_ENV) else: self.sps.create(self.program, self.array_ENV, self.maxenv, self.envlen, - self.sps.STRING) + self.sps.STRING) self.owner_ENV = True self.nopts = 0 env = recordlist.getEnviron() - self.labels = [ col.label for col in env['datadesc'] ] + self.labels = [col.label for col in env['datadesc']] - env = { 'title' : env['title'], - 'started' : env['starttime'].ctime(), - 'ended' : '', - 'axistitles' : ' '.join(self.labels), - 'ylabel' : 'Counts', - 'nopts' : self.nopts, - 'xbeg' : 0, - 'xend' : 200, - 'aborted' : 0, - 'command' : 'done', - 'fitresult' : '0' } + env = {'title': env['title'], + 'started': env['starttime'].ctime(), + 'ended': '', + 'axistitles': ' '.join(self.labels), + 'ylabel': 'Counts', + 'nopts': self.nopts, + 'xbeg': 0, + 'xend': 200, + 'aborted': 0, + 'command': 'done', + 'fitresult': '0'} self.putAllEnv(env) def _writeRecord(self, record): - if not self.isInitialized(): return + if not self.isInitialized(): + return vals = [] @@ -146,26 +152,29 @@ def _writeRecord(self, record): sufix = "1D" if self.array.endswith(sufix): valsmca = numpy.array(valsmca) - self.sps.putdatarow(self.program, self.array, record.recordno, valsmca) + self.sps.putdatarow( + self.program, self.array, record.recordno, valsmca) sufix = "0D" if self.array.endswith(sufix): vals = numpy.array(vals) - self.sps.putdatarow(self.program, self.array, record.recordno, vals) + self.sps.putdatarow(self.program, self.array, + record.recordno, vals) self.nopts += 1 - env = { 'nopts' : self.nopts, - 'peak' : 111, - 'peakpos' : 34, - 'fwhm' : 12.3, - 'fwhmpos' : 45, - 'com' : 23 } + env = {'nopts': self.nopts, + 'peak': 111, + 'peakpos': 34, + 'fwhm': 12.3, + 'fwhmpos': 45, + 'com': 23} self.putAllEnv(env) def _endRecordList(self, recordlist): - if not self.isInitialized(): return + if not self.isInitialized(): + return env = recordlist.getEnviron() self.putEnv('ended', env.get('endtime').ctime()) @@ -208,7 +217,8 @@ def setChanDimList(self, chandimlist): def _startRecordList(self, recordlist): - if not self.isInitialized(): return + if not self.isInitialized(): + return arraylist = self.sps.getarraylist(self.progname) @@ -216,27 +226,29 @@ def _startRecordList(self, recordlist): shm = self.sps.attach(self.progname, self.shm_id) else: self.sps.create(self.progname, self.shm_id, self.rows, self.cols, - self.sps.DOUBLE) + self.sps.DOUBLE) if self.shm_id_env in arraylist: shm_env = self.sps.attach(self.progname, self.shm_id_env) else: self.sps.create(self.progname, self.shm_id_env, self.maxenv, self.envlen, - self.sps.STRING) + self.sps.STRING) print "Starting new SHM recording" self.putenv('title', recordlist.getEnvironValue('title')) for env, val in recordlist.getEnviron().items(): - if env != 'title' and env != 'labels': - self.putenv(env , val) + if env != 'title' and env != 'labels': + self.putenv(env, val) self.nopts = 0 - self.putenv('started', time.ctime(recordlist.getEnvironValue('starttime'))) + self.putenv('started', time.ctime( + recordlist.getEnvironValue('starttime'))) self.putenv('ended', '') - self.putenv('axistitles', ' '.join(recordlist.getEnvironValue('labels'))) + self.putenv('axistitles', ' '.join( + recordlist.getEnvironValue('labels'))) self.putenv('ylabel', 'Counts') self.putenv('nopts', self.nopts) self.putenv('xbeg', 100) @@ -250,7 +262,8 @@ def _startRecordList(self, recordlist): def _writeRecord(self, record): # uhmm. only numeric values can be written - if not self.isInitialized(): return + if not self.isInitialized(): + return vals = [] @@ -264,31 +277,33 @@ def _writeRecord(self, record): myj = 0 for val2 in record.data: - tmp = val2 + '_value' - #esto me da el nombre del canal - for dim in self.chandimlist: - if tmp == dim: - dim_list[myj] = self.chandimlist[dim] - myj = myj + 1 + tmp = val2 + '_value' + # esto me da el nombre del canal + for dim in self.chandimlist: + if tmp == dim: + dim_list[myj] = self.chandimlist[dim] + myj = myj + 1 myj = 0 for val2 in record.data.values(): - valsmca = [] - if type(val2) in [list]: - if dim_list[myj] == 1: - for i in range(0, len(val2)): - valsmca.append(val2[i]) - tmp_name = self.mnt_grp + "_1D" - if self.shm_id == tmp_name: - valsmca = numpy.array(valsmca) - self.sps.putdatarow(self.progname, self.shm_id, record.recordno, valsmca) - myj = myj + 1 + valsmca = [] + if type(val2) in [list]: + if dim_list[myj] == 1: + for i in range(0, len(val2)): + valsmca.append(val2[i]) + tmp_name = self.mnt_grp + "_1D" + if self.shm_id == tmp_name: + valsmca = numpy.array(valsmca) + self.sps.putdatarow( + self.progname, self.shm_id, record.recordno, valsmca) + myj = myj + 1 vals = numpy.array(vals) tmp_name = self.mnt_grp + "_0D" if self.shm_id == tmp_name: - self.sps.putdatarow(self.progname, self.shm_id, record.recordno, vals) + self.sps.putdatarow(self.progname, self.shm_id, + record.recordno, vals) self.nopts += 1 self.putenv('nopts', self.nopts) @@ -298,8 +313,7 @@ def _writeRecord(self, record): self.putenv('fwhmpos', 45) self.putenv('com', 23) - def _endRecordList(self, recordlist): - if not self.isInitialized(): return + if not self.isInitialized(): + return self.putenv('ended', time.ctime(recordlist.getEnvironValue('endtime'))) - diff --git a/src/sardana/macroserver/recorders/storage.py b/src/sardana/macroserver/recorders/storage.py index e1f5fe2986..1a8ee2f4a1 100644 --- a/src/sardana/macroserver/recorders/storage.py +++ b/src/sardana/macroserver/recorders/storage.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -61,11 +61,11 @@ def __init__(self, filename=None, macro=None, **pars): self.setFileName(self.base_filename) def setFileName(self, filename): - if self.fd != None: + if self.fd != None: self.fd.close() - + dirname = os.path.dirname(filename) - + if not os.path.isdir(dirname): try: os.makedirs(dirname) @@ -77,7 +77,7 @@ def setFileName(self, filename): # construct the filename, e.g. : /dir/subdir/etcdir/prefix_00123.fio # tpl = filename.rpartition('.') - try: # For avoiding error when calling at __init__ + try: # For avoiding error when calling at __init__ serial = self.recordlist.getEnvironValue('serialno') self.filename = "%s_%05d.%s" % (tpl[0], serial, tpl[2]) # @@ -89,42 +89,43 @@ def setFileName(self, filename): def getFormat(self): return self.formats.keys()[0] - + def _startRecordList(self, recordlist): if self.base_filename is None: return self.setFileName(self.base_filename) - + envRec = recordlist.getEnviron() - self.sampleTime = envRec['estimatedtime'] / (envRec['total_scan_intervals'] + 1) - #datetime object + self.sampleTime = envRec['estimatedtime'] / \ + (envRec['total_scan_intervals'] + 1) + # datetime object start_time = envRec['starttime'] - - self.motorNames = envRec[ 'ref_moveables'] + + self.motorNames = envRec['ref_moveables'] self.mcaNames = [] self.ctNames = [] for e in envRec['datadesc']: - if len( e.shape) == 1: - self.mcaNames.append( e.name) + if len(e.shape) == 1: + self.mcaNames.append(e.name) else: - self.ctNames.append( e.name) + self.ctNames.append(e.name) # # we need the aliases for the column description # self.mcaAliases = [] for mca in self.mcaNames: lst = mca.split("/") - self.mcaAliases.append( self.db.get_alias( "/".join( lst[1:]))) + self.mcaAliases.append(self.db.get_alias("/".join(lst[1:]))) # self.names = [ e.name for e in envRec['datadesc'] ] - self.fd = open( self.filename,'w') + self.fd = open(self.filename, 'w') # # write the comment section of the header # - self.fd.write("!\n! Comments\n!\n%%c\n %s\nuser %s Acquisition started at %s\n" % + self.fd.write("!\n! Comments\n!\n%%c\n %s\nuser %s Acquisition started at %s\n" % (envRec['title'], envRec['user'], start_time.ctime())) self.fd.flush() # @@ -133,7 +134,7 @@ def _startRecordList(self, recordlist): self.fd.write("!\n! Parameter\n!\n%p\n") self.fd.flush() env = self.macro.getAllEnv() - if env.has_key( 'FlagFioWriteMotorPositions') and env['FlagFioWriteMotorPositions'] == True: + if env.has_key('FlagFioWriteMotorPositions') and env['FlagFioWriteMotorPositions'] == True: all_motors = self.macro.findObjs('.*', type_class=Type.Motor) all_motors.sort() for mot in all_motors: @@ -142,8 +143,8 @@ def _startRecordList(self, recordlist): record = "%s = nan\n" % (mot) else: record = "%s = %g\n" % (mot, pos) - - self.fd.write( record) + + self.fd.write(record) self.fd.flush() # # write the data section starting with the description of the columns @@ -151,7 +152,7 @@ def _startRecordList(self, recordlist): self.fd.write("!\n! Data\n!\n%d\n") self.fd.flush() i = 1 - for col in envRec[ 'datadesc']: + for col in envRec['datadesc']: if col.name == 'point_nb': continue if col.name == 'timestamp': @@ -159,14 +160,14 @@ def _startRecordList(self, recordlist): dType = 'FLOAT' if col.dtype == 'float64': dType = 'DOUBLE' - outLine = " Col %d %s %s\n" % ( i, col.label, dType) - self.fd.write( outLine) + outLine = " Col %d %s %s\n" % (i, col.label, dType) + self.fd.write(outLine) i += 1 # # 11.9.2012 timestamp to the end # - outLine = " Col %d %s %s\n" % ( i, 'timestamp', 'DOUBLE') - self.fd.write( outLine) + outLine = " Col %d %s %s\n" % (i, 'timestamp', 'DOUBLE') + self.fd.write(outLine) self.fd.flush() @@ -184,12 +185,12 @@ def _writeRecord(self, record): # outstr += ' ' + str(record.data.get('timestamp', nan)) outstr += '\n' - - fd.write( outstr ) + + fd.write(outstr) fd.flush() - if len( self.mcaNames) > 0: - self._writeMcaFile( record) + if len(self.mcaNames) > 0: + self._writeMcaFile(record) def _endRecordList(self, recordlist): if self.filename is None: @@ -201,18 +202,18 @@ def _endRecordList(self, recordlist): self.fd.flush() self.fd.close() - def _writeMcaFile( self, record): + def _writeMcaFile(self, record): if self.mcaDirName is None: return - if not os.path.isdir( self.mcaDirName): + if not os.path.isdir(self.mcaDirName): try: - os.makedirs( self.mcaDirName) + os.makedirs(self.mcaDirName) except: self.mcaDirName = None return - currDir = os.getenv( 'PWD') - os.chdir( self.mcaDirName) + currDir = os.getenv('PWD') + os.chdir(self.mcaDirName) serial = self.recordlist.getEnvironValue('serialno') if type(self.recordlist.getEnvironValue('ScanFile')).__name__ == 'list': @@ -220,11 +221,13 @@ def _writeMcaFile( self, record): else: scanFile = self.recordlist.getEnvironValue('ScanFile') - mcaFileName = "%s_%05d_mca_s%d.fio" % (scanFile.split('.')[0], serial, record.data['point_nb'] + 1) - fd = open( mcaFileName,'w') - fd.write("!\n! Comments\n!\n%%c\n Position %g, Index %d \n" % - ( record.data[ self.motorNames[0]], record.data[ 'point_nb'])) - fd.write("!\n! Parameter \n%%p\n Sample_time = %g \n" % ( self.sampleTime)) + mcaFileName = "%s_%05d_mca_s%d.fio" % ( + scanFile.split('.')[0], serial, record.data['point_nb'] + 1) + fd = open(mcaFileName, 'w') + fd.write("!\n! Comments\n!\n%%c\n Position %g, Index %d \n" % + (record.data[self.motorNames[0]], record.data['point_nb'])) + fd.write("!\n! Parameter \n%%p\n Sample_time = %g \n" % + (self.sampleTime)) self.fd.flush() col = 1 @@ -233,42 +236,43 @@ def _writeMcaFile( self, record): fd.write(" Col %d %s FLOAT \n" % (col, mca)) col = col + 1 - if not record.data[ self.mcaNames[0]] is None: - #print "+++storage.py, recordno", record.recordno - #print "+++storage.py, record.data", record.data - #print "+++storage.py, len %d, %s" % (len( record.data[ self.mcaNames[0]]), self.mcaNames[0]) + if not record.data[self.mcaNames[0]] is None: + # print "+++storage.py, recordno", record.recordno + # print "+++storage.py, record.data", record.data + # print "+++storage.py, len %d, %s" % (len( record.data[ self.mcaNames[0]]), self.mcaNames[0]) # # the MCA arrays me be of different size. the short ones are extended by zeros. # - lMax = len( record.data[ self.mcaNames[0]]) + lMax = len(record.data[self.mcaNames[0]]) for mca in self.mcaNames: - if len(record.data[ mca]) > lMax: - lMax = len(record.data[ mca]) - - for i in range( 0, lMax): + if len(record.data[mca]) > lMax: + lMax = len(record.data[mca]) + + for i in range(0, lMax): line = "" for mca in self.mcaNames: if i > (len(record.data[mca]) - 1): line = line + " 0" else: - line = line + " " + str( record.data[ mca][i]) + line = line + " " + str(record.data[mca][i]) line = line + "\n" fd.write(line) - + fd.close() else: - #print "+++storage.py, recordno", record.recordno, "data None" + # print "+++storage.py, recordno", record.recordno, "data None" pass - - os.chdir( currDir) + + os.chdir(currDir) + class SPEC_FileRecorder(BaseFileRecorder): """ Saves data to a file """ formats = {'Spec': '.spec'} - supported_dtypes = ('float32','float64','int8', - 'int16','int32','int64','uint8', - 'uint16','uint32','uint64') + supported_dtypes = ('float32', 'float64', 'int8', + 'int16', 'int32', 'int64', 'uint8', + 'uint16', 'uint32', 'uint64') def __init__(self, filename=None, macro=None, **pars): BaseFileRecorder.__init__(self) @@ -278,38 +282,38 @@ def __init__(self, filename=None, macro=None, **pars): def setLabels(self, labels): self._expectedlabels = labels - + def setFileName(self, filename): if self.fd != None: self.fd.close() - + dirname = os.path.dirname(filename) - + if not os.path.isdir(dirname): try: os.makedirs(dirname) except: self.filename = None return - self.filename = filename + self.filename = filename self.currentlist = None def getFormat(self): return self.formats.keys()[0] - + def _startRecordList(self, recordlist): '''Prepares and writes the scan header.''' if self.filename is None: return env = recordlist.getEnviron() - - #datetime object + + # datetime object start_time = env['starttime'] epoch = time.mktime(start_time.timetuple()) serialno = env['serialno'] - - #store names for performance reason + + # store names for performance reason labels = [] names = [] oned_labels = [] @@ -322,7 +326,10 @@ def _startRecordList(self, recordlist): dims = len(e.shape) if dims >= 2: continue - sanitizedlabel = "".join(x for x in e.label.replace(' ', '_') if x.isalnum() or x == '_') #substitute whitespaces by underscores and remove other non-alphanumeric characters + # substitute whitespaces by underscores and remove other + # non-alphanumeric characters + sanitizedlabel = "".join(x for x in e.label.replace( + ' ', '_') if x.isalnum() or x == '_') if not dims or (dims == 1 and e.shape[0] == 1): labels.append(sanitizedlabel) names.append(e.name) @@ -331,8 +338,8 @@ def _startRecordList(self, recordlist): oned_labels.append(sanitizedlabel) oned_names.append(e.name) oned_shape = e.shape[0] - if self._expectedlabels: - names = [] + if self._expectedlabels: + names = [] labels = self._expectedlabels for label in labels: try: @@ -349,15 +356,15 @@ def _startRecordList(self, recordlist): snapshot_labels, snapshot_values = self._preparePreScanSnapshot(env) # format scan header data = { - 'serialno': serialno, - 'title': env['title'], - 'user': env['user'], - 'epoch': epoch, - 'starttime': start_time.ctime(), - 'nocols': len(names), - 'labels': ' '.join(labels) - } - #Compatibility with PyMca + 'serialno': serialno, + 'title': env['title'], + 'user': env['user'], + 'epoch': epoch, + 'starttime': start_time.ctime(), + 'nocols': len(names), + 'labels': ' '.join(labels) + } + # Compatibility with PyMca if os.path.exists(self.filename): header = '\n' else: @@ -372,23 +379,23 @@ def _startRecordList(self, recordlist): header += '#N %(nocols)s\n' if len(oned_labels) > 0: header += '#@MCA %sC\n' % oned_shape - header += '#@CHANN %s 0 %s 1\n' % (oned_shape, oned_shape-1) + header += '#@CHANN %s 0 %s 1\n' % (oned_shape, oned_shape - 1) header += '#@MCA_NB %s\n' % len(oned_labels) for idx, oned_label in enumerate(oned_labels): - header += '#@DET_%s %s\n' %(idx, oned_label) + header += '#@DET_%s %s\n' % (idx, oned_label) header += '#L %(labels)s\n' - - self.fd = open(self.filename,'a') - self.fd.write(header % data ) + + self.fd = open(self.filename, 'a') + self.fd.write(header % data) self.fd.flush() - + def _prepareMultiLines(self, character, sep, items_list): '''Translate list of lists of items into multiple line string - + :param character (string): each line will start # :sep: separator (string): separator to use between items :param items_list (list):list of lists of items - + :return multi_lines (string): string with all the items''' multi_lines = '' for nr, items in enumerate(items_list): @@ -396,37 +403,38 @@ def _prepareMultiLines(self, character, sep, items_list): items_str = sep.join(map(str, items)) end = '\n' line = start + items_str + end - multi_lines += line + multi_lines += line return multi_lines - + def _preparePreScanSnapshot(self, env): '''Extract pre-scan snapshot, filters elements of shape different than scalar and split labels and values into chunks of 8 items. - + :param: env (dict) scan environment - + :return: labels, values (tuple) labels - list of chunks with 8 elements containing labels values - list of chunks with 8 elements containing values ''' # preScanSnapShot is a list o ColumnDesc objects - pre_scan_snapshot = env.get('preScanSnapShot',[]) - labels = []; values = [] + pre_scan_snapshot = env.get('preScanSnapShot', []) + labels = [] + values = [] for column_desc in pre_scan_snapshot: - shape = column_desc.shape # shape is a tuple of dimensions + shape = column_desc.shape # shape is a tuple of dimensions label = column_desc.label dtype = column_desc.dtype pre_scan_value = column_desc.pre_scan_value # skip items - #if label not in self._expectedlabels: + # if label not in self._expectedlabels: # continue # skip items with shape different than scalar if len(shape) > 0: - self.info('Pre-scan snapshot of "%s" will not be stored.' + \ + self.info('Pre-scan snapshot of "%s" will not be stored.' + ' Reason: value is non-scalar', label) continue if dtype not in self.supported_dtypes: - self.info('Pre-scan snapshot of "%s" will not be stored.' + \ + self.info('Pre-scan snapshot of "%s" will not be stored.' + ' Reason: type %s not supported', label, dtype) continue labels.append(label) @@ -435,12 +443,12 @@ def _preparePreScanSnapshot(self, env): labels_chunks = list(chunks(labels, 8)) values_chunks = list(chunks(values, 8)) return labels_chunks, values_chunks - + def _writeRecord(self, record): if self.filename is None: return nan, names, fd = float('nan'), self.names, self.fd - + d = [] for oned_name in self.oned_names: data = record.data.get(oned_name) @@ -451,18 +459,19 @@ def _writeRecord(self, record): str_data = '' for i in data: str_data += '%s ' % i - outstr = '@A %s' % str_data + outstr = '@A %s' % str_data outstr += '\n' - fd.write( outstr ) + fd.write(outstr) for c in names: data = record.data.get(c) - if data is None: data = nan + if data is None: + data = nan d.append(str(data)) - outstr = ' '.join(d) + outstr = ' '.join(d) outstr += '\n' - - fd.write( outstr ) + + fd.write(outstr) fd.flush() @@ -476,84 +485,90 @@ def _endRecordList(self, recordlist): self.fd.flush() self.fd.close() - def _addCustomData(self, value, name, **kwargs): ''' The custom data will be added as a comment line in the form:: - + #C name : value - + ..note:: non-scalar values (or name/values containing end-of-line) will not be written ''' if self.filename is None: - self.info('Custom data "%s" will not be stored in SPEC file. Reason: uninitialized file',name) + self.info( + 'Custom data "%s" will not be stored in SPEC file. Reason: uninitialized file', name) return - if numpy.rank(value) > 0: #ignore non-scalars - self.info('Custom data "%s" will not be stored in SPEC file. Reason: value is non-scalar', name) + if numpy.rank(value) > 0: # ignore non-scalars + self.info( + 'Custom data "%s" will not be stored in SPEC file. Reason: value is non-scalar', name) return v = str(value) - if '\n' in v or '\n' in name: #ignore if name or the string representation of the value contains end-of-line - self.info('Custom data "%s" will not be stored in SPEC file. Reason: unsupported format',name) + if '\n' in v or '\n' in name: # ignore if name or the string representation of the value contains end-of-line + self.info( + 'Custom data "%s" will not be stored in SPEC file. Reason: unsupported format', name) return - + fileWasClosed = self.fd is None or self.fd.closed if fileWasClosed: try: - self.fd = open(self.filename,'a') + self.fd = open(self.filename, 'a') except: - self.info('Custom data "%s" will not be stored in SPEC file. Reason: cannot open file',name) + self.info( + 'Custom data "%s" will not be stored in SPEC file. Reason: cannot open file', name) return self.fd.write('#C %s : %s\n' % (name, v)) self.fd.flush() if fileWasClosed: - self.fd.close() #leave the file descriptor as found + self.fd.close() # leave the file descriptor as found class NXscan_FileRecorder(BaseNAPI_FileRecorder): """saves data to a nexus file that follows the NXscan application definition - + """ def __init__(self, filename=None, macro=None, overwrite=False, **pars): - BaseNAPI_FileRecorder.__init__(self, filename=filename, macro=macro, overwrite=overwrite, **pars) - + BaseNAPI_FileRecorder.__init__( + self, filename=filename, macro=macro, overwrite=overwrite, **pars) + def _startRecordList(self, recordlist): nxs = self.nxs nxfilemode = self.getFormat() - + if self.filename is None: return - + self.currentlist = recordlist env = self.currentlist.getEnviron() serialno = env["serialno"] - self._dataCompressionRank = env.get("DataCompressionRank", self._dataCompressionRank) - - if not self.overwrite and os.path.exists(self.filename): nxfilemode='rw' + self._dataCompressionRank = env.get( + "DataCompressionRank", self._dataCompressionRank) + + if not self.overwrite and os.path.exists(self.filename): + nxfilemode = 'rw' self.fd = nxs.open(self.filename, nxfilemode) self.entryname = "entry%d" % serialno try: - self.fd.makegroup(self.entryname,"NXentry") + self.fd.makegroup(self.entryname, "NXentry") except self.nxs.NeXusError: entrynames = self.fd.getentries().keys() - - #=================================================================== + + #================================================================== ##Warn and abort if self.entryname in entrynames: - raise RuntimeError(('"%s" already exists in %s. To prevent data corruption the macro will be aborted.\n'%(self.entryname, self.filename)+ - 'This is likely caused by a wrong ScanID\n'+ - 'Possible workarounds:\n'+ + raise RuntimeError(('"%s" already exists in %s. To prevent data corruption the macro will be aborted.\n' % (self.entryname, self.filename) + + 'This is likely caused by a wrong ScanID\n' + + 'Possible workarounds:\n' + ' * first, try re-running this macro (the ScanID may be automatically corrected)\n' - ' * if not, try changing ScanID with senv, or...\n'+ - ' * change the file name (%s will be in both files containing different data)\n'%self.entryname+ + ' * if not, try changing ScanID with senv, or...\n' + + ' * change the file name (%s will be in both files containing different data)\n' % self.entryname + '\nPlease report this problem.')) else: - raise - #=================================================================== - - #=================================================================== - ## Warn and continue writing to another entry - #if self.entryname in entrynames: + raise + #================================================================== + + #================================================================== + # Warn and continue writing to another entry + # if self.entryname in entrynames: # i = 2 # newname = "%s_%i"%(self.entryname,i) # while(newname in entrynames): @@ -563,92 +578,109 @@ def _startRecordList(self, recordlist): # self.macro.warning('"%s" already exists. Using "%s" instead. \nThis may indicate a bug in %s. Please report it.',self.entryname, newname, self.macro.name) # self.entryname = newname # self.fd.makegroup(self.entryname,"NXentry") - #=================================================================== - - self.fd.opengroup(self.entryname,"NXentry") - - - #adapt the datadesc to the NeXus requirements + #================================================================== + + self.fd.opengroup(self.entryname, "NXentry") + + # adapt the datadesc to the NeXus requirements self.datadesc = [] for dd in env['datadesc']: dd = dd.clone() dd.label = self.sanitizeName(dd.label) if dd.dtype == 'bool': dd.dtype = 'int8' - self.debug('%s will be stored with type=%s',dd.name,dd.dtype) + self.debug('%s will be stored with type=%s', dd.name, dd.dtype) if dd.dtype in self.supported_dtypes: self.datadesc.append(dd) else: - self.warning('%s will not be stored. Reason: type %s not supported',dd.name,dd.dtype) - - #make a dictionary out of env['instrumentlist'] (use fullnames -paths- as keys) + self.warning( + '%s will not be stored. Reason: type %s not supported', dd.name, dd.dtype) + + # make a dictionary out of env['instrumentlist'] (use fullnames -paths- + # as keys) self.instrDict = {} for inst in env.get('instrumentlist', []): self.instrDict[inst.getFullName()] = inst if self.instrDict is {}: - self.warning("missing information on NEXUS structure. Nexus Tree won't be created") - - self.debug("starting new recording %d on file %s", env['serialno'], self.filename) + self.warning( + "missing information on NEXUS structure. Nexus Tree won't be created") - #populate the entry with some data - self._writeData('definition', 'NXscan', 'char') #this is the Application Definition for NeXus Generic Scans + self.debug("starting new recording %d on file %s", + env['serialno'], self.filename) + + # populate the entry with some data + # this is the Application Definition for NeXus Generic Scans + self._writeData('definition', 'NXscan', 'char') import sardana.release - program_name = "%s (%s)" % (sardana.release.name, self.__class__.__name__) - self._writeData('program_name', program_name, 'char', attrs={'version':sardana.release.version}) - self._writeData("start_time",env['starttime'].isoformat(),'char') #note: the type should be NX_DATE_TIME, but the nxs python api does not recognize it - self.fd.putattr("epoch",time.mktime(env['starttime'].timetuple())) - self._writeData("title",env['title'],'char') - self._writeData("entry_identifier",str(env['serialno']),'char') - self.fd.makegroup("user","NXuser") #user data goes in a separate group following NX convention... - self.fd.opengroup("user","NXuser") - self._writeData("name",env['user'],'char') + program_name = "%s (%s)" % ( + sardana.release.name, self.__class__.__name__) + self._writeData('program_name', program_name, 'char', + attrs={'version': sardana.release.version}) + # note: the type should be NX_DATE_TIME, but the nxs python api does + # not recognize it + self._writeData("start_time", env['starttime'].isoformat(), 'char') + self.fd.putattr("epoch", time.mktime(env['starttime'].timetuple())) + self._writeData("title", env['title'], 'char') + self._writeData("entry_identifier", str(env['serialno']), 'char') + # user data goes in a separate group following NX convention... + self.fd.makegroup("user", "NXuser") + self.fd.opengroup("user", "NXuser") + self._writeData("name", env['user'], 'char') self.fd.closegroup() - - #prepare the "measurement" group + + # prepare the "measurement" group self._createBranch("measurement:NXcollection") if self.savemode == SaveModes.Record: - #create extensible datasets + # create extensible datasets for dd in self.datadesc: - self._makedata(dd.label, dd.dtype, [nxs.UNLIMITED] + list(dd.shape), chunks=[1] + list(dd.shape)) #the first dimension is extensible + self._makedata(dd.label, dd.dtype, [nxs.UNLIMITED] + list(dd.shape), chunks=[ + 1] + list(dd.shape)) # the first dimension is extensible if hasattr(dd, 'data_units'): self.fd.opendata(dd.label) self.fd.putattr('units', dd.data_units) self.fd.closedata() - + else: - #leave the creation of the datasets to _writeRecordList (when we actually know the length of the data to write) + # leave the creation of the datasets to _writeRecordList (when we + # actually know the length of the data to write) pass - + self._createPreScanSnapshot(env) - + self.fd.flush() - + def _createPreScanSnapshot(self, env): - #write the pre-scan snapshot in the "measurement:NXcollection/pre_scan_snapshot:NXcollection" group - self.preScanSnapShot = env.get('preScanSnapShot',[]) - self._createBranch('measurement:NXcollection/pre_scan_snapshot:NXcollection') + # write the pre-scan snapshot in the + # "measurement:NXcollection/pre_scan_snapshot:NXcollection" group + self.preScanSnapShot = env.get('preScanSnapShot', []) + self._createBranch( + 'measurement:NXcollection/pre_scan_snapshot:NXcollection') links = {} - for dd in self.preScanSnapShot: #desc is a ColumnDesc object + for dd in self.preScanSnapShot: # desc is a ColumnDesc object label = self.sanitizeName(dd.label) dtype = dd.dtype pre_scan_value = dd.pre_scan_value if dd.dtype == 'bool': dtype = 'int8' pre_scan_value = numpy.int8(dd.pre_scan_value) - self.debug('Pre-scan snapshot of %s will be stored with type=%s',dd.name, dtype) + self.debug( + 'Pre-scan snapshot of %s will be stored with type=%s', dd.name, dtype) if dtype in self.supported_dtypes: - nid = self._writeData(label, pre_scan_value, dtype, shape=dd.shape or (1,)) #@todo: fallback shape is hardcoded! + # @todo: fallback shape is hardcoded! + nid = self._writeData( + label, pre_scan_value, dtype, shape=dd.shape or (1,)) links[label] = nid else: - self.warning('Pre-scan snapshot of %s will not be stored. Reason: type %s not supported',dd.name, dtype) - - self.fd.closegroup() #we are back at the measurement group - + self.warning( + 'Pre-scan snapshot of %s will not be stored. Reason: type %s not supported', dd.name, dtype) + + self.fd.closegroup() # we are back at the measurement group + measurement_entries = self.fd.getentries() - for label,nid in links.items(): + for label, nid in links.items(): if label not in measurement_entries: self.fd.makelink(nid) - + def _writeRecord(self, record): if self.filename is None: return @@ -656,19 +688,19 @@ def _writeRecord(self, record): fd, debug, warning = self.fd, self.debug, self.warning nparray, npshape = numpy.array, numpy.shape rec_data, rec_nb = record.data, record.recordno - + for dd in self.datadesc: - if record.data.has_key( dd.name ): + if record.data.has_key(dd.name): data = rec_data[dd.name] fd.opendata(dd.label) - + if data is None: data = numpy.zeros(dd.shape, dtype=dd.dtype) if not hasattr(data, 'shape'): data = nparray([data], dtype=dd.dtype) elif dd.dtype != data.dtype.name: debug('%s casted to %s (was %s)', dd.label, dd.dtype, - data.dtype.name) + data.dtype.name) data = data.astype(dd.dtype) slab_offset = [rec_nb] + [0] * len(dd.shape) @@ -678,12 +710,12 @@ def _writeRecord(self, record): except: warning("Could not write <%s> with shape %s", data, shape) raise - - ###Note: the following 3 lines of code were substituted by the one above. - ### (now we trust the datadesc info instead of asking the nxs file each time) - #shape,dtype=self.fd.getinfo() - #shape[0]=1 #the shape of the record is of just 1 slab in the extensible dimension (first dim) - #self.fd.putslab(record.data[lbl],[record.recordno]+[0]*(len(shape)-1),shape) + + # Note: the following 3 lines of code were substituted by the one above. + # (now we trust the datadesc info instead of asking the nxs file each time) + # shape,dtype=self.fd.getinfo() + # shape[0]=1 #the shape of the record is of just 1 slab in the extensible dimension (first dim) + # self.fd.putslab(record.data[lbl],[record.recordno]+[0]*(len(shape)-1),shape) fd.closedata() else: debug("missing data for label '%s'", dd.label) @@ -693,70 +725,81 @@ def _endRecordList(self, recordlist): if self.filename is None: return - + self._populateInstrumentInfo() self._createNXData() env = self.currentlist.getEnviron() self.fd.openpath("/%s:NXentry" % self.entryname) - self._writeData("end_time",env['endtime'].isoformat(),'char') + self._writeData("end_time", env['endtime'].isoformat(), 'char') self.fd.flush() - self.debug("Finishing recording %d on file %s:", env['serialno'], self.filename) - #self.fd.show('.') #prints nexus file summary on stdout (only the current entry) + self.debug("Finishing recording %d on file %s:", + env['serialno'], self.filename) + # self.fd.show('.') #prints nexus file summary on stdout (only the + # current entry) self.fd.close() self.currentlist = None def writeRecordList(self, recordlist): """Called when in BLOCK writing mode""" - self._startRecordList( recordlist ) + self._startRecordList(recordlist) for dd in self.datadesc: - self._makedata(dd.label, dd.dtype, [len(recordlist.records)]+list(dd.shape), chunks=[1]+list(dd.shape)) + self._makedata(dd.label, dd.dtype, [ + len(recordlist.records)] + list(dd.shape), chunks=[1] + list(dd.shape)) self.fd.opendata(dd.label) try: - #try creating a single block to write it at once - block=numpy.array([r.data[dd.label] for r in recordlist.records],dtype=dd.dtype) - #if dd.dtype !='char': block=numpy.array(block,dtype=dtype) #char not supported anyway + # try creating a single block to write it at once + block = numpy.array([r.data[dd.label] + for r in recordlist.records], dtype=dd.dtype) + # if dd.dtype !='char': block=numpy.array(block,dtype=dtype) + # #char not supported anyway self.fd.putdata(block) except KeyError: - #if not all the records contain this field, we cannot write it as a block.. so do it record by record (but only this field!) + # if not all the records contain this field, we cannot write it + # as a block.. so do it record by record (but only this field!) for record in recordlist.records: - if record.data.has_key( dd.label ): - self.fd.putslab(record.data[dd.label],[record.recordno]+[0]*len(dd.shape),[1]+list(dd.shape)) + if record.data.has_key(dd.label): + self.fd.putslab(record.data[dd.label], [ + record.recordno] + [0] * len(dd.shape), [1] + list(dd.shape)) else: - self.debug("missing data for label '%s' in record %i", dd.label, record.recordno) + self.debug( + "missing data for label '%s' in record %i", dd.label, record.recordno) self.fd.closedata() - self._endRecordList( recordlist ) + self._endRecordList(recordlist) def _populateInstrumentInfo(self): measurementpath = "/%s:NXentry/measurement:NXcollection" % self.entryname - #create a link for each + # create a link for each for dd in self.datadesc: - if getattr(dd, 'instrument', None): #we don't link if it is None or it is empty + if getattr(dd, 'instrument', None): # we don't link if it is None or it is empty try: datapath = "%s/%s" % (measurementpath, dd.label) self.fd.openpath(datapath) nid = self.fd.getdataID() self._createBranch(dd.instrument) self.fd.makelink(nid) - except Exception,e: - self.warning("Could not create link to '%s' in '%s'. Reason: %s",datapath, dd.instrument, repr(e)) - + except Exception, e: + self.warning( + "Could not create link to '%s' in '%s'. Reason: %s", datapath, dd.instrument, repr(e)) + for dd in self.preScanSnapShot: - if getattr(dd,'instrument', None): + if getattr(dd, 'instrument', None): try: label = self.sanitizeName(dd.label) - datapath = "%s/pre_scan_snapshot:NXcollection/%s" % (measurementpath, label) + datapath = "%s/pre_scan_snapshot:NXcollection/%s" % ( + measurementpath, label) self.fd.openpath(datapath) nid = self.fd.getdataID() self._createBranch(dd.instrument) self.fd.makelink(nid) - except Exception,e: - self.warning("Could not create link to '%s' in '%s'. Reason: %s",datapath, dd.instrument, repr(e)) - + except Exception, e: + self.warning( + "Could not create link to '%s' in '%s'. Reason: %s", datapath, dd.instrument, repr(e)) + def _createNXData(self): '''Creates groups of type NXdata by making links to the corresponding datasets - ''' - #classify by type of plot: + ''' + # classify by type of plot: plots1d = {} plots1d_names = {} i = 1 @@ -765,53 +808,58 @@ def _createNXData(self): if ptype == PlotType.No: continue elif ptype == PlotType.Spectrum: - axes = ":".join(dd.plot_axes) #converting the list into a colon-separated string + # converting the list into a colon-separated string + axes = ":".join(dd.plot_axes) if axes in plots1d: plots1d[axes].append(dd) else: plots1d[axes] = [dd] - plots1d_names[axes] = 'plot_%i' % i #Note that datatesc ordering determines group name indexing + # Note that datatesc ordering determines group name + # indexing + plots1d_names[axes] = 'plot_%i' % i i += 1 else: - continue #@todo: implement support for images and other - - #write the 1D NXdata group + continue # @todo: implement support for images and other + + # write the 1D NXdata group for axes, v in plots1d.items(): self.fd.openpath("/%s:NXentry" % (self.entryname)) groupname = plots1d_names[axes] - self.fd.makegroup(groupname,'NXdata') - #write the signals + self.fd.makegroup(groupname, 'NXdata') + # write the signals for i, dd in enumerate(v): - src = "/%s:NXentry/measurement:NXcollection/%s" % (self.entryname, dd.label) + src = "/%s:NXentry/measurement:NXcollection/%s" % ( + self.entryname, dd.label) dst = "/%s:NXentry/%s:NXdata" % (self.entryname, groupname) self._nxln(src, dst) self.fd.opendata(dd.label) self.fd.putattr('signal', min(i + 1, 2)) self.fd.putattr('axes', axes) self.fd.putattr('interpretation', 'spectrum') - #write the axes + # write the axes for axis in axes.split(':'): - src = "/%s:NXentry/measurement:NXcollection/%s" % (self.entryname, axis) + src = "/%s:NXentry/measurement:NXcollection/%s" % ( + self.entryname, axis) dst = "/%s:NXentry/%s:NXdata" % (self.entryname, groupname) try: self._nxln(src, dst) except: - self.warning("cannot create link for '%s'. Skipping",axis) - + self.warning("cannot create link for '%s'. Skipping", axis) + def _addCustomData(self, value, name, nxpath=None, dtype=None, **kwargs): ''' apart from value and name, this recorder can use the following optional parameters: - + :param nxpath: (str) a nexus path (optionally using name:nxclass notation for the group names). See the rules for automatic nxclass resolution used by :meth:`NXscan_FileRecorder._createBranch`. If None given, it defaults to nxpath='custom_data:NXcollection' - + :param dtype: name of data type (it is inferred from value if not given) - - ''' + + ''' if nxpath is None: nxpath = 'custom_data:NXcollection' if dtype is None: @@ -820,21 +868,23 @@ def _addCustomData(self, value, name, nxpath=None, dtype=None, **kwargs): if numpy.issubdtype(dtype, str): dtype = 'char' if dtype == 'bool': - value, dtype = int(value), 'int8' + value, dtype = int(value), 'int8' else: value = numpy.array(value) dtype = value.dtype.name - + if dtype not in self.supported_dtypes and dtype != 'char': - self.warning("cannot write '%s'. Reason: unsupported data type",name) + self.warning( + "cannot write '%s'. Reason: unsupported data type", name) return - #open the file if necessary + # open the file if necessary fileWasClosed = self.fd is None or not self.fd.isopen if fileWasClosed: - if not self.overwrite and os.path.exists(self.filename): nxfilemode = 'rw' + if not self.overwrite and os.path.exists(self.filename): + nxfilemode = 'rw' import nxs self.fd = nxs.open(self.filename, nxfilemode) - #write the data + # write the data self._createBranch(nxpath) try: self._writeData(name, value, dtype) @@ -842,6 +892,6 @@ def _addCustomData(self, value, name, nxpath=None, dtype=None, **kwargs): msg = "Error writing %s. Reason: %s" % (name, str(e)) self.warning(msg) self.macro.warning(msg) - #leave the file as it was + # leave the file as it was if fileWasClosed: self.fd.close() diff --git a/src/sardana/macroserver/scan/__init__.py b/src/sardana/macroserver/scan/__init__.py index 3cfc70006c..e8ff34706c 100644 --- a/src/sardana/macroserver/scan/__init__.py +++ b/src/sardana/macroserver/scan/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -28,4 +28,4 @@ __docformat__ = 'restructuredtext' from scandata import * -from gscan import * \ No newline at end of file +from gscan import * diff --git a/src/sardana/macroserver/scan/gscan.py b/src/sardana/macroserver/scan/gscan.py index c0fa938834..d479728143 100644 --- a/src/sardana/macroserver/scan/gscan.py +++ b/src/sardana/macroserver/scan/gscan.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -127,13 +127,15 @@ def attribute(self): def getType(self): t = self.attribute.getType() if t is None: - raise Exception("Could not determine type for unknown attribute '%s'" % self._model) + raise Exception( + "Could not determine type for unknown attribute '%s'" % self._model) return FROM_TANGO_TO_STR_TYPE[t] - + def getShape(self): s = self.attribute.getShape() if s is None: - raise Exception("Could not determine type for unknown attribute '%s'" % self._model) + raise Exception( + "Could not determine type for unknown attribute '%s'" % self._model) return s def read(self): @@ -234,8 +236,8 @@ def __init__(self, macro, generator=None, moveables=[], env={}, constraints=[], self._generator = generator self._extrainfodesc = extrainfodesc - #nasty hack to make sure macro has access to gScan as soon as possible - self._macro._gScan = self #TODO: CAUTION! this may be causing a circular reference! + # nasty hack to make sure macro has access to gScan as soon as possible + self._macro._gScan = self # TODO: CAUTION! this may be causing a circular reference! self._rec_manager = macro.getMacroServer().recorder_manager self._moveables, moveable_names = [], [] @@ -350,7 +352,7 @@ def _getExtraColumns(self): try: if kw.has_key('instrument'): instrument = self._macro.getObj(kw['instrument'], - type_class=Type.Instrument) + type_class=Type.Instrument) if instrument: kw['instrument'] = instrument ret.append(TangoExtraData(**kw)) @@ -438,14 +440,14 @@ def _getFileRecorders(self): file_names = (file_names,) elif not operator.isSequenceType(file_names): scan_file_t = type(file_names).__name__ - raise TypeError("ScanFile MUST be string or sequence of strings."\ + raise TypeError("ScanFile MUST be string or sequence of strings." " It is '%s'" % scan_file_t) if isinstance(scan_recorders, (str, unicode)): scan_recorders = (scan_recorders,) elif not operator.isSequenceType(scan_recorders): scan_recorders_t = type(scan_recorders).__name__ - raise TypeError("ScanRecorder MUST be string or sequence of strings."\ + raise TypeError("ScanRecorder MUST be string or sequence of strings." " It is '%s'" % scan_recorders_t) file_recorders = [] @@ -492,7 +494,7 @@ def _getSharedMemoryRecorder(self, eid): kwargs = {} # For now we only support SPS shared memory format if shm.lower() == 'sps': - cols = 1 # Point nb column + cols = 1 # Point nb column cols += len(self.moveables) # motor columns ch_nb = len(mg.getChannels()) oned_nb = 0 @@ -514,27 +516,28 @@ def _getSharedMemoryRecorder(self, eid): twod_nb = 0 if eid == 0: - cols += (ch_nb - oned_nb - twod_nb) # counter/timer & 0D channel columns + # counter/timer & 0D channel columns + cols += (ch_nb - oned_nb - twod_nb) elif eid == 1: cols = 1024 if eid == 0: - kwargs.update({ 'program' : macro.getDoorName(), - 'array' : "%s_0D" % array_prefix, - 'shape' : (cols, 4096) } ) + kwargs.update({'program': macro.getDoorName(), + 'array': "%s_0D" % array_prefix, + 'shape': (cols, 4096)}) elif eid == 1: if oned_nb == 0: return else: - kwargs.update({ 'program' : macro.getDoorName(), - 'array' : "%s_1D" % array_prefix, - 'shape' : (cols, 99) } ) + kwargs.update({'program': macro.getDoorName(), + 'array': "%s_1D" % array_prefix, + 'shape': (cols, 99)}) try: shmRecorder = SharedMemoryRecorder(shm, macro, **kwargs) except Exception: macro.warning("Error creating %s SharedMemory recorder." % shm) macro.debug("Details:", exc_info=1) - + return shmRecorder def _secsToTimedelta(self, secs): @@ -544,7 +547,7 @@ def _secsToTimedelta(self, secs): return datetime.timedelta(days, secs) def _timedeltaToSecs(self, td): - return 86400*td.days + td.seconds + 1E-6*td.microseconds + return 86400 * td.days + td.seconds + 1E-6 * td.microseconds def _setupEnvironment(self, additional_env): try: @@ -554,9 +557,9 @@ def _setupEnvironment(self, additional_env): self.macro.setEnv("ScanID", serialno) env = ScanDataEnvironment( - { 'serialno' : serialno, - 'user' : USER_NAME, #TODO: this should be got from self.measurement_group.getChannelsInfo() - 'title' : self.macro.getCommand() } ) + {'serialno': serialno, + 'user': USER_NAME, # TODO: this should be got from self.measurement_group.getChannelsInfo() + 'title': self.macro.getCommand()}) # Initialize the data_desc list (and add the point number column) data_desc = [ @@ -578,27 +581,29 @@ def _setupEnvironment(self, additional_env): master = self._master instrument = master['instrument'] - #add channels from measurement group + # add channels from measurement group channels_info = self.measurement_group.getChannelsEnabledInfo() counters = [] for ci in channels_info: instrument = ci.instrument or '' try: - instrumentFullName = self.macro.findObjs(instrument, type_class=Type.Instrument)[0].getFullName() + instrumentFullName = self.macro.findObjs( + instrument, type_class=Type.Instrument)[0].getFullName() except InterruptException: raise except: instrumentFullName = '' - #substitute the axis placeholder by the corresponding moveable. + # substitute the axis placeholder by the corresponding moveable. plotAxes = [] i = 0 for a in ci.plot_axes: if a == '': plotAxes.append(ref_moveables[i]) i += 1 - else: plotAxes.append(a) + else: + plotAxes.append(a) - #create the ColumnDesc object + # create the ColumnDesc object column = ColumnDesc(name=ci.full_name, label=ci.label, dtype=ci.data_type, @@ -624,31 +629,33 @@ def _setupEnvironment(self, additional_env): data_desc.append(extra_column.getColumnDesc()) # add extra columns data_desc += self._extrainfodesc - data_desc.append(ColumnDesc(name='timestamp', label='dt', dtype='float64')) + data_desc.append(ColumnDesc(name='timestamp', + label='dt', dtype='float64')) env['datadesc'] = data_desc - #set the data compression default + # set the data compression default try: - env['DataCompressionRank'] = self.macro.getEnv('DataCompressionRank') + env['DataCompressionRank'] = self.macro.getEnv( + 'DataCompressionRank') except UnknownEnv: env['DataCompressionRank'] = -1 - #set the sample information + # set the sample information #@todo: use the instrument API to get this info try: env['SampleInfo'] = self.macro.getEnv('SampleInfo') except UnknownEnv: env['SampleInfo'] = {} - #set the source information + # set the source information #@todo: use the instrument API to get this info try: env['SourceInfo'] = self.macro.getEnv('SourceInfo') except UnknownEnv: env['SourceInfo'] = {} - #take the pre-scan snapshot + # take the pre-scan snapshot try: preScanSnapShot = self.macro.getEnv('PreScanSnapshot') except UnknownEnv: @@ -669,9 +676,11 @@ def _setupEnvironment(self, additional_env): except: env['ScanDir'] = None env['estimatedtime'], env['total_scan_intervals'] = self._estimate() - env['instrumentlist'] = self._macro.findObjs('.*', type_class=Type.Instrument) + env['instrumentlist'] = self._macro.findObjs( + '.*', type_class=Type.Instrument) - #env.update(self._getExperimentConfiguration) #add all the info from the experiment configuration to the environment + # env.update(self._getExperimentConfiguration) #add all the info from + # the experiment configuration to the environment env.update(additional_env) self._env = env @@ -703,13 +712,15 @@ def takeSnapshot(self, elements=[]): label=label, source=src) - v = PyTango.AttributeProxy(column.source).read().value #@Fixme: Tango-centric. It should work for any Taurus Attribute + # @Fixme: Tango-centric. It should work for any Taurus Attribute + v = PyTango.AttributeProxy(column.source).read().value column.pre_scan_value = v column.shape = np.shape(v) column.dtype = getattr(v, 'dtype', np.dtype(type(v))).name ret.append(column) except: - self.macro.warning('Error taking pre-scan snapshot of %s (%s)', label, src) + self.macro.warning( + 'Error taking pre-scan snapshot of %s (%s)', label, src) self.debug('Details:', exc_info=1) return ret @@ -749,7 +760,8 @@ def _estimate(self, max_iter=None): max_path_duration = 0.0 for v_motor, start, stop in zip(v_motors, start_pos, end_pos): path = MotionPath(v_motor, start, stop) - max_path_duration = max(max_path_duration, path.duration) + max_path_duration = max( + max_path_duration, path.duration) integ_time = step.get("integ_time", 0.0) acq_time += integ_time motion_time += max_path_duration @@ -833,7 +845,7 @@ def end(self): if isinstance(scan_file, (str, unicode)): scan_file = scan_file, - names = [ col.name for col in env['datadesc'] ] + names = [col.name for col in env['datadesc']] history = dict(startts=env['startts'], endts=env['endts'], estimatedtime=env['estimatedtime'], deadtime=env['deadtime'], title=env['title'], @@ -858,10 +870,11 @@ def step_scan(self): self.macro.pausePoint() yield i except ScanException, e: - #self.macro.warning(e.msg) + # self.macro.warning(e.msg) ex = e self.end() - if not ex is None: raise e + if not ex is None: + raise e finally: self.do_restore() @@ -874,10 +887,10 @@ def do_backup(self): if hasattr(self.macro, 'do_backup'): self.macro.do_backup() except: - msg = ("Failed to execute 'do_backup' method of the %s macro" % - self.macro.getName()) + msg = ("Failed to execute 'do_backup' method of the %s macro" % + self.macro.getName()) self.macro.debug(msg) - self.macro.debug('Details: ', exc_info = True) + self.macro.debug('Details: ', exc_info=True) raise ScanException('error while doing a backup') def do_restore(self): @@ -885,12 +898,13 @@ def do_restore(self): if hasattr(self.macro, 'do_restore'): self.macro.do_restore() except: - msg = ("Failed to execute 'do_restore' method of the %s macro" % + msg = ("Failed to execute 'do_restore' method of the %s macro" % self.macro.getName()) self.macro.debug(msg) - self.macro.debug('Details: ', exc_info = True) + self.macro.debug('Details: ', exc_info=True) raise ScanException('error while restoring a backup') + class SScan(GScan): """Step scan""" @@ -934,8 +948,8 @@ def stepUp(self, n, step, lstep): motion, mg = self.motion, self.measurement_group startts = self._env['startts'] - #pre-move hooks - for hook in step.get('pre-move-hooks',()): + # pre-move hooks + for hook in step.get('pre-move-hooks', ()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) @@ -960,8 +974,8 @@ def stepUp(self, n, step, lstep): curr_time = time.time() dt = curr_time - startts - #post-move hooks - for hook in step.get('post-move-hooks',()): + # post-move hooks + for hook in step.get('post-move-hooks', ()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) @@ -977,16 +991,17 @@ def stepUp(self, n, step, lstep): self.dump_information(n, step) m = "Scan aborted after problematic motion: " \ "Motion ended with %s\n" % str(state) - raise ScanException({ 'msg' : m }) + raise ScanException({'msg': m}) - #pre-acq hooks - for hook in step.get('pre-acq-hooks',()): + # pre-acq hooks + for hook in step.get('pre-acq-hooks', ()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: raise - except: pass + except: + pass integ_time = step['integ_time'] # Acquire data @@ -997,7 +1012,7 @@ def stepUp(self, n, step, lstep): self.debug("[ END ] acquisition") self._sum_acq_time += integ_time - #post-acq hooks + # post-acq hooks for hook in step.get('post-acq-hooks', ()): hook() try: @@ -1007,7 +1022,7 @@ def stepUp(self, n, step, lstep): except: pass - #hooks for backwards compatibility: + # hooks for backwards compatibility: if step.has_key('hooks'): self.macro.info('Deprecation warning: you should use ' '"post-acq-hooks" instead of "hooks" in the step ' @@ -1027,12 +1042,13 @@ def stepUp(self, n, step, lstep): for i, m in enumerate(self.moveables): data_line[m.moveable.getName()] = positions[i] - #Add extra data coming in the step['extrainfo'] dictionary - if step.has_key('extrainfo'): data_line.update(step['extrainfo']) + # Add extra data coming in the step['extrainfo'] dictionary + if step.has_key('extrainfo'): + data_line.update(step['extrainfo']) self.data.addRecord(data_line) - #post-step hooks + # post-step hooks for hook in step.get('post-step-hooks', ()): hook() try: @@ -1064,8 +1080,8 @@ def __init__(self, macro, generator=None, moveables=[], self.motion_end_event = threading.Event() data_structures = self.populate_moveables_data_structures(moveables) self._moveables_trees, \ - physical_moveables_names, \ - self._physical_moveables = data_structures + physical_moveables_names, \ + self._physical_moveables = data_structures # The physical motion object contains only physical motors - no pseudo # motors (in case the pseudomotors are involved in the scan, # it comprarises the underneath physical motors) @@ -1104,13 +1120,13 @@ def generate_moveable_node(macro, moveable): if moveable_type == "PseudoMotor": moveable_node = BranchNode(moveable) moveables_names = moveable.elements - sub_moveables = [macro.getMoveable(name) \ + sub_moveables = [macro.getMoveable(name) for name in moveables_names] for sub_moveable in sub_moveables: sub_moveable_node, \ - _physical_moveables_names, \ - _physical_moveables = generate_moveable_node(macro, - sub_moveable) + _physical_moveables_names, \ + _physical_moveables = generate_moveable_node(macro, + sub_moveable) physical_moveables_names += _physical_moveables_names physical_moveables += _physical_moveables moveable_node.addChild(sub_moveable_node) @@ -1127,7 +1143,7 @@ def generate_moveable_node(macro, moveable): for moveable in moveables: moveable_root_node, _physical_moveables_names, _physical_moveables = \ - generate_moveable_node(self.macro, moveable.moveable) + generate_moveable_node(self.macro, moveable.moveable) moveable_tree = Tree(moveable_root_node) moveable_trees.append(moveable_tree) physical_moveables_names += _physical_moveables_names @@ -1161,23 +1177,25 @@ def go_through_waypoints(self, iterate_only=False): raise e except Exception: self.macro.debug('An error occurred moving to waypoints') - self.macro.debug('Details: ', exc_info = True) + self.macro.debug('Details: ', exc_info=True) self.on_waypoints_end() raise ScanException('error while moving to waypoints') def _go_through_waypoints(self): """Internal, unprotected method to go through the different waypoints.""" raise NotImplementedError("_go_through_waypoints must be implemented " + - "in CScan derived classes") + "in CScan derived classes") def waypoint_estimation(self): """Internal, unprotected method to go through the different waypoints.""" motion, waypoints = self.motion, self.generator() total_duration = 0 #v_motors = self.get_virtual_motors() - curr_positions, last_end_positions = motion.readPosition(force=True), None + curr_positions, last_end_positions = motion.readPosition( + force=True), None for i, waypoint in enumerate(waypoints): - start_positions = waypoint.get('start_positions', last_end_positions) + start_positions = waypoint.get( + 'start_positions', last_end_positions) positions = waypoint['positions'] if start_positions is None: last_end_positions = positions @@ -1187,7 +1205,7 @@ def waypoint_estimation(self): iterate_only=True) motion_paths, delta_start, acq_duration = waypoint_info - start_path, end_path = [] , [] + start_path, end_path = [], [] for path in motion_paths: start_path.append(path.initial_user_pos) end_path.append(path.final_user_pos) @@ -1259,8 +1277,8 @@ def do_restore(self): continue motor = motor_backup['moveable'] attributes = OrderedDict(velocity=motor_backup["velocity"], - acceleration=motor_backup["acceleration"], - deceleration=motor_backup["deceleration"]) + acceleration=motor_backup["acceleration"], + deceleration=motor_backup["deceleration"]) try: self.configure_motor(motor, attributes) except ScanException, e: @@ -1293,8 +1311,8 @@ def get_max_top_velocity(self, motor): max_top_vel = float(max_top_vel) except ValueError: try: - #hack to avoid recursive velocity reduction - self._maxVelDict = getattr(self,'_maxVelDict',{}) + # hack to avoid recursive velocity reduction + self._maxVelDict = getattr(self, '_maxVelDict', {}) if not motor in self._maxVelDict: self._maxVelDict[motor] = motor.getVelocity() max_top_vel = self._maxVelDict[motor] @@ -1337,7 +1355,7 @@ def set_max_top_velocity(self, motor): motor.setVelocity(v) except: pass - + def get_min_pos(self, motor): '''Helper method to find the minimum position for a given motor. If the motor doesn't define its minimum position, then the negative @@ -1376,7 +1394,7 @@ def configure_motor(self, motor, attributes): motor._getAttrEG(param).write(value) except: self.macro.debug("Error when setting %s of %s" % - (param, motor.name), exc_info = True) + (param, motor.name), exc_info=True) msg = "setting %s of %s to %r failed" %\ (param, motor.name, value) raise ScanException(msg) @@ -1392,7 +1410,6 @@ def __init__(self, macro, waypointGenerator=None, periodGenerator=None, extrainfodesc=extrainfodesc) self._periodGenerator = periodGenerator - def _calculateTotalAcquisitionTime(self): return None @@ -1431,8 +1448,10 @@ def prepare_waypoint(self, waypoint, start_positions, iterate_only=False): max_top_vel = top_vel except AttributeError: if not iterate_only: - self.macro.warning("%s motion will not be coordinated", motor) - base_vel, top_vel, max_top_vel = 0, float('+inf'), float('+inf') + self.macro.warning( + "%s motion will not be coordinated", motor) + base_vel, top_vel, max_top_vel = 0, float( + '+inf'), float('+inf') accel_time, decel_time = 0, 0 coordinate = False @@ -1446,7 +1465,8 @@ def prepare_waypoint(self, waypoint, start_positions, iterate_only=False): real_path.apply_correction = coordinate # Find the cruise duration of motion at top velocity. For this create a - # virtual motor which has instantaneous acceleration and deceleration + # virtual motor which has instantaneous acceleration and + # deceleration ideal_vmotor = VMotor(min_vel=base_vel, max_vel=max_top_vel, accel_time=0, decel_time=0) @@ -1495,21 +1515,23 @@ def prepare_waypoint(self, waypoint, start_positions, iterate_only=False): vmotor.setAccelerationTime(accel_t) vmotor.setDecelerationTime(decel_t) disp_sign = path.positive_displacement and 1 or -1 - new_initial_pos = path.initial_user_pos - accel_t * 0.5 * disp_sign * (new_top_vel + base_vel) - disp_sign * new_top_vel * (delta_start - accel_t) + new_initial_pos = path.initial_user_pos - accel_t * 0.5 * disp_sign * \ + (new_top_vel + base_vel) - disp_sign * \ + new_top_vel * (delta_start - accel_t) path.setInitialUserPos(new_initial_pos) - new_final_pos = path.final_user_pos + disp_sign * vmotor.displacement_reach_min_vel + new_final_pos = path.final_user_pos + \ + disp_sign * vmotor.displacement_reach_min_vel path.setFinalUserPos(new_final_pos) return ideal_paths, delta_start, cruise_duration - def go_through_waypoints(self, iterate_only=False): """go through the different waypoints.""" try: self._go_through_waypoints() except: self.macro.debug('An error occurred moving to waypoints') - self.macro.debug('Details: ', exc_info = True) + self.macro.debug('Details: ', exc_info=True) self.on_waypoints_end() raise ScanException('error while moving to waypoints') @@ -1534,11 +1556,11 @@ def _go_through_waypoints(self): self.acq_duration = acq_duration - #execute pre-move hooks - for hook in waypoint.get('pre-move-hooks',[]): + # execute pre-move hooks + for hook in waypoint.get('pre-move-hooks', []): hook() - start_pos, final_pos = [] , [] + start_pos, final_pos = [], [] for path in motion_paths: start_pos.append(path.initial_user_pos) final_pos.append(path.final_user_pos) @@ -1578,8 +1600,8 @@ def _go_through_waypoints(self): if macro.isStopped(): return self.on_waypoints_end() - #execute post-move hooks - for hook in waypoint.get('post-move-hooks',[]): + # execute post-move hooks + for hook in waypoint.get('post-move-hooks', []): hook() if start_positions is None: @@ -1587,7 +1609,6 @@ def _go_through_waypoints(self): self.on_waypoints_end(positions) - def scan_loop(self): motion, mg, waypoints = self.motion, self.measurement_group, self.steps macro = self.macro @@ -1605,7 +1626,7 @@ def scan_loop(self): else: yield 0.0 - moveables = [ m.moveable for m in self.moveables ] + moveables = [m.moveable for m in self.moveables] period_steps = self.period_steps point_nb, step = -1, None data = self.data @@ -1657,17 +1678,18 @@ def scan_loop(self): elapsed_time = time.time() - acq_start_time if elapsed_time + integ_time > self.acq_duration: motion_event.clear() - break; + break - #pre-acq hooks - for hook in step.get('pre-acq-hooks',()): + # pre-acq hooks + for hook in step.get('pre-acq-hooks', ()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) except InterruptException: self._all_waypoints_finished = True raise - except: pass + except: + pass # allow scan to stop macro.checkPoint() @@ -1686,14 +1708,15 @@ def scan_loop(self): macro.checkPoint() # After acquisition, test if we are asked to stop, probably because - # the motor are stopped. In this case discard the last acquisition + # the motor are stopped. In this case discard the last + # acquisition if not self._all_waypoints_finished: for ec in self._extra_columns: data_line[ec.getName()] = ec.read() self.debug("[ END ] acquisition") - #post-acq hooks - for hook in step.get('post-acq-hooks',()): + # post-acq hooks + for hook in step.get('post-acq-hooks', ()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) @@ -1709,8 +1732,9 @@ def scan_loop(self): for i, m in enumerate(self.moveables): data_line[m.moveable.getName()] = positions[i] - #Add extra data coming in the step['extrainfo'] dictionary - if step.has_key('extrainfo'): data_line.update(step['extrainfo']) + # Add extra data coming in the step['extrainfo'] dictionary + if step.has_key('extrainfo'): + data_line.update(step['extrainfo']) self.data.addRecord(data_line) @@ -1728,7 +1752,6 @@ def scan_loop(self): for hook in macro.getHooks('post-scan'): hook() - env = self._env env['acqtime'] = sum_integ_time env['delaytime'] = sum_delay @@ -1776,11 +1799,11 @@ def eventReceived(self, event_src, event_type, event_value): value = event_value.value # value is a dictionary with at least keys: data, index # and its values are of type sequence - # e.g. dict(data=seq, index=seq) + # e.g. dict(data=seq, index=seq) _, data = self._codec.decode(('json', value), - ensure_ascii=True) + ensure_ascii=True) channelName = event_src.getParentObj().getFullName() - info = {'label' : channelName} + info = {'label': channelName} info.update(data) # info is a dictionary with at least keys: label, data, # index and its values are of type string for label and @@ -1790,10 +1813,10 @@ def eventReceived(self, event_src, event_type, event_value): self._thread_pool.add(self.data.addData, self._countdown_latch.count_down, info) except Exception, e: - #TODO: maybe here we should do some cleanup... + # TODO: maybe here we should do some cleanup... msg = 'Exception occurred processing the received event' self.debug(msg) - self.debug('Details: ', exc_info = True) + self.debug('Details: ', exc_info=True) raise Exception('"data" event callback failed') def get_theoretical_positions(self): @@ -1805,7 +1828,8 @@ def get_theoretical_positions(self): # generate theoretical positions moveable_positions = [] for start, final in zip(starts, finals): - moveable_positions.append(np.linspace(start, final, nr_of_points+1)) + moveable_positions.append( + np.linspace(start, final, nr_of_points + 1)) # prepare table header from moveables names dtype_spec = [] for moveable in moveables: @@ -1870,11 +1894,12 @@ def prepare_waypoint(self, waypoint, start_positions, iterate_only=False): dec_time = max_dec_time for moveable, start, end in \ - zip(self._physical_moveables, start_positions, positions): + zip(self._physical_moveables, start_positions, positions): total_displacement = abs(end - start) direction = 1 if end > start else -1 interval_displacement = total_displacement / self.macro.nr_interv - # move further in order to acquire the last point at constant velocity + # move further in order to acquire the last point at constant + # velocity end = end + direction * interval_displacement base_vel = moveable.getBaseRate() @@ -1910,8 +1935,8 @@ def _go_through_waypoints(self): tango_channels.append(full_name) if len(tango_channels) > 0: raise ScanException('Tango channels %r are not supported. Hint: ' - 'change measurement group or remove them from the group.' % - tango_channels) + 'change measurement group or remove them from the group.' % + tango_channels) last_positions = None for _, waypoint in waypoints: @@ -1932,11 +1957,11 @@ def _go_through_waypoints(self): self.acq_duration = acq_duration - #execute pre-move hooks - for hook in waypoint.get('pre-move-hooks',[]): + # execute pre-move hooks + for hook in waypoint.get('pre-move-hooks', []): hook() - # parepare list of start and final positions for the motion object - start_pos, final_pos = [] , [] + # parepare list of start and final positions for the motion object + start_pos, final_pos = [], [] for path in motion_paths: start_pos.append(path.initial_user_pos) final_pos.append(path.final_user_pos) @@ -1960,20 +1985,22 @@ def _go_through_waypoints(self): self.on_waypoints_end() return ############ - #validation of parameters + # validation of parameters for start, end in zip(self.macro.starts, self.macro.finals): if start == end: - raise ScanException("Scan start and end must be different.") + raise ScanException( + "Scan start and end must be different.") startTimestamp = time.time() - #extra pre configuration + # extra pre configuration if hasattr(macro, 'getHooks'): for hook in macro.getHooks('pre-configuration'): hook() self.macro.checkPoint() - # TODO: let a pseudomotor specify which motor should be used as source + # TODO: let a pseudomotor specify which motor should be used as + # source MASTER = 0 moveable = moveables[MASTER].full_name self.measurement_group.setMoveable(moveable) @@ -1989,26 +2016,27 @@ def _go_through_waypoints(self): initial_position = start total_time = abs(total_position) / path.max_vel delay_time = path.max_vel_time - synch = [{SynchParam.Delay: {SynchDomain.Time:delay_time}, - SynchParam.Initial: {SynchDomain.Position:initial_position}, - SynchParam.Active: {SynchDomain.Position:active_position, - SynchDomain.Time:active_time}, - SynchParam.Total: {SynchDomain.Position:total_position, - SynchDomain.Time:total_time}, + synch = [{SynchParam.Delay: {SynchDomain.Time: delay_time}, + SynchParam.Initial: {SynchDomain.Position: initial_position}, + SynchParam.Active: {SynchDomain.Position: active_position, + SynchDomain.Time: active_time}, + SynchParam.Total: {SynchDomain.Position: total_position, + SynchDomain.Time: total_time}, SynchParam.Repeats: repeats}] self.debug('Synchronization: %s' % synch) self.measurement_group.setSynchronization(synch) self.macro.checkPoint() - #extra post configuration + # extra post configuration if hasattr(macro, 'getHooks'): for hook in macro.getHooks('post-configuration'): hook() self.macro.checkPoint() endTimestamp = time.time() - self.debug("Configuration took %s time." % repr(endTimestamp - startTimestamp)) - ############ + self.debug("Configuration took %s time." % + repr(endTimestamp - startTimestamp)) + ############ # move to start position self.macro.debug("Moving to start position: %s" % repr(start_pos)) motion.move(start_pos) @@ -2022,13 +2050,13 @@ def _go_through_waypoints(self): motor = path.moveable self.macro.debug("Motor: %s" % motor.getName()) self.macro.debug('start_user: %f; ' % path._initial_user_pos + - 'end_user: %f; ' % path._final_user_pos + - 'start: %f; ' % path.initial_pos + + 'end_user: %f; ' % path._final_user_pos + + 'start: %f; ' % path.initial_pos + 'end: %f; ' % path.final_pos + 'ds: %f' % (path.final_pos - path.initial_pos)) attributes = OrderedDict(velocity=path.max_vel, - acceleration=path.max_vel_time, - deceleration=path.min_vel_time) + acceleration=path.max_vel_time, + deceleration=path.min_vel_time) try: self.configure_motor(motor, attributes) except ScanException, e: @@ -2066,7 +2094,8 @@ def _go_through_waypoints(self): self.timestamp_to_start = time.time() + delta_start # move to waypoint end position - self.macro.debug("Moving to waypoint position: %s" % repr(final_pos)) + self.macro.debug( + "Moving to waypoint position: %s" % repr(final_pos)) motion.move(final_pos) finally: self.measurement_group.waitFinish(id=mg_id) @@ -2074,11 +2103,11 @@ def _go_through_waypoints(self): if macro.isStopped(): self.on_waypoints_end() return - #execute post-move hooks - for hook in waypoint.get('post-move-hooks',[]): + # execute post-move hooks + for hook in waypoint.get('post-move-hooks', []): hook() - if start_positions is None: + if start_positions is None: last_positions = positions self.on_waypoints_end(positions) @@ -2121,7 +2150,7 @@ def scan_loop(self): else: yield 0.0 - moveables = [ m.moveable for m in self.moveables ] + moveables = [m.moveable for m in self.moveables] point_nb, step = -1, None data = self.data @@ -2132,7 +2161,6 @@ def scan_loop(self): self.go_through_waypoints() - if hasattr(macro, 'getHooks'): for hook in macro.getHooks('post-scan'): hook() @@ -2156,7 +2184,7 @@ def cleanup(self): except: msg = "Exception occurred trying to remove data listeners" self.debug(msg) - self.debug('Details: ', exc_info = True) + self.debug('Details: ', exc_info=True) raise ScanException('removing data listeners failed') if hasattr(self.macro, 'getHooks'): @@ -2167,7 +2195,7 @@ def cleanup(self): except: msg = "Exception while trying to execute a pre-cleanup hook" self.debug(msg) - self.debug('Details: ', exc_info = True) + self.debug('Details: ', exc_info=True) raise ScanException('pre-cleanup hook failed') if hasattr(self.macro, 'getHooks'): @@ -2179,11 +2207,12 @@ def cleanup(self): msg = "Exception while trying to execute a " + \ "post-cleanup hook" self.debug(msg) - self.debug('Details: ', exc_info = True) + self.debug('Details: ', exc_info=True) raise ScanException('post-cleanup hook failed') endTimestamp = time.time() - self.debug("Cleanup took %s time." % repr(endTimestamp - startTimestamp)) + self.debug("Cleanup took %s time." % + repr(endTimestamp - startTimestamp)) class HScan(SScan): @@ -2193,8 +2222,8 @@ def stepUp(self, n, step, lstep): motion, mg = self.motion, self.measurement_group startts = self._env['startts'] - #pre-move hooks - for hook in step.get('pre-move-hooks',()): + # pre-move hooks + for hook in step.get('pre-move-hooks', ()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) @@ -2233,7 +2262,7 @@ def stepUp(self, n, step, lstep): self.dump_information(n, step) m = "Scan aborted after problematic motion: " \ "Motion ended with %s\n" % str(m_state) - raise ScanException({ 'msg' : m }) + raise ScanException({'msg': m}) data_line = mg.getValues() @@ -2243,13 +2272,14 @@ def stepUp(self, n, step, lstep): for i, m in enumerate(self.moveables): data_line[m.moveable.getName()] = m_positions[i] - #Add extra data coming in the step['extrainfo'] dictionary - if step.has_key('extrainfo'): data_line.update(step['extrainfo']) + # Add extra data coming in the step['extrainfo'] dictionary + if step.has_key('extrainfo'): + data_line.update(step['extrainfo']) self.data.addRecord(data_line) - #post-step hooks - for hook in step.get('post-step-hooks',()): + # post-step hooks + for hook in step.get('post-step-hooks', ()): hook() try: step['extrainfo'].update(hook.getStepExtraInfo()) diff --git a/src/sardana/macroserver/scan/recorder/__init__.py b/src/sardana/macroserver/scan/recorder/__init__.py index 5c8ec1b887..6985989359 100644 --- a/src/sardana/macroserver/scan/recorder/__init__.py +++ b/src/sardana/macroserver/scan/recorder/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,4 +29,4 @@ from .datarecorder import * from .sharedmemory import * -from .storage import * \ No newline at end of file +from .storage import * diff --git a/src/sardana/macroserver/scan/recorder/datarecorder.py b/src/sardana/macroserver/scan/recorder/datarecorder.py index d5ddc68469..b80082155d 100644 --- a/src/sardana/macroserver/scan/recorder/datarecorder.py +++ b/src/sardana/macroserver/scan/recorder/datarecorder.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -71,10 +71,10 @@ def addRecord(self, recordlist, record): def addCustomData(self, value, name, **kwargs): '''Write data other than a record. - + :param value: The value to be written :param name: An identification for this value - + Optional keyword arguments can be passed with information that some recorders may need in order to record this value. For example: the NeXus recorder will make use of "nxpath" info if available to place the value @@ -87,8 +87,10 @@ def addCustomData(self, value, name, **kwargs): # Recorders # + class DataRecorder(Logger): """ Generic class for data recorder. Does nothing""" + def __init__(self, **pars): name = self.__class__.__name__ self.call__init__(Logger, name) diff --git a/src/sardana/macroserver/scan/recorder/sharedmemory.py b/src/sardana/macroserver/scan/recorder/sharedmemory.py index 6bc1d7e61b..e366ce3810 100644 --- a/src/sardana/macroserver/scan/recorder/sharedmemory.py +++ b/src/sardana/macroserver/scan/recorder/sharedmemory.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -37,7 +37,8 @@ class BaseSharedMemoryRecorder(DataRecorder): def __init__(self, **pars): DataRecorder.__init__(self, **pars) -_SharedMemoryRecorder = BaseSharedMemoryRecorder # for backwards compatibility +_SharedMemoryRecorder = BaseSharedMemoryRecorder # for backwards compatibility + def SharedMemoryRecorder(type, macro, **pars): """Factory to create shared memory recorders based on the type diff --git a/src/sardana/macroserver/scan/recorder/storage.py b/src/sardana/macroserver/scan/recorder/storage.py index f9e3fb7bde..ae3c35acda 100644 --- a/src/sardana/macroserver/scan/recorder/storage.py +++ b/src/sardana/macroserver/scan/recorder/storage.py @@ -2,31 +2,31 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """This is the macro server scan data output recorder module""" -__all__ = ["AmbiguousRecorderError", "BaseFileRecorder", - "BaseNAPI_FileRecorder", "BaseNEXUS_FileRecorder","FileRecorder"] +__all__ = ["AmbiguousRecorderError", "BaseFileRecorder", + "BaseNAPI_FileRecorder", "BaseNEXUS_FileRecorder", "FileRecorder"] __docformat__ = 'restructuredtext' @@ -52,11 +52,12 @@ class AmbiguousRecorderError(MacroServerException): class BaseFileRecorder(DataRecorder): + def __init__(self, **pars): DataRecorder.__init__(self, **pars) self.filename = None - self.fd = None - + self.fd = None + def getFileName(self): return self.filename @@ -68,77 +69,80 @@ def getFormat(self): class BaseNEXUS_FileRecorder(BaseFileRecorder): - """Base class for NeXus file recorders""" - + """Base class for NeXus file recorders""" + formats = {'w5': '.h5', 'w4': '.h4', 'wx': '.xml'} - supported_dtypes = ('float32','float64','int8', - 'int16','int32','int64','uint8', - 'uint16','uint32','uint64') #note that 'char' is not supported yet! + supported_dtypes = ('float32', 'float64', 'int8', + 'int16', 'int32', 'int64', 'uint8', + 'uint16', 'uint32', 'uint64') # note that 'char' is not supported yet! _dataCompressionRank = -1 - + def __init__(self, filename=None, macro=None, overwrite=False, **pars): BaseFileRecorder.__init__(self, **pars) try: - import nxs #check if Nexus data format is supported by this system + import nxs # check if Nexus data format is supported by this system self.nxs = nxs except ImportError: raise Exception("NeXus is not available") - + self.macro = macro self.overwrite = overwrite if filename: self.setFileName(filename) - + self.instrDict = {} self.entryname = 'entry' - + def setFileName(self, filename): - if self.fd is not None: + if self.fd is not None: self.fd.close() - + self.filename = filename - #obtain preferred nexus file mode for writing from the filename extension (defaults to hdf5) + # obtain preferred nexus file mode for writing from the filename + # extension (defaults to hdf5) extension = os.path.splitext(filename)[1] - inv_formats = dict(itertools.izip(self.formats.itervalues(), self.formats.iterkeys())) + inv_formats = dict(itertools.izip( + self.formats.itervalues(), self.formats.iterkeys())) self.nxfilemode = inv_formats.get(extension.lower(), 'w5') self.currentlist = None - + def getFormat(self): return self.nxfilemode - + def sanitizeName(self, name): '''It returns a version of the given name that can be used as a python variable (and conforms to NeXus best-practices for dataset names)''' - #make sure the name does not start with a digit - if name[0].isdigit(): name = "_%s" % name - #substitute whitespaces by underscores and remove other non-alphanumeric characters - return "".join(x for x in name.replace(' ','_') if x.isalnum() or x=='_') - - + # make sure the name does not start with a digit + if name[0].isdigit(): + name = "_%s" % name + # substitute whitespaces by underscores and remove other + # non-alphanumeric characters + return "".join(x for x in name.replace(' ', '_') if x.isalnum() or x == '_') + def _nxln(self, src, dst, name=None): '''convenience function to create NX links with just one call. On successful return, dst will be open. - + :param src: (str or NXgroup or NXfield) source group or dataset (or its path) :param dst: (str or NXgroup) the group that will hold the link (or its path) :param name: (str) name for the link. If not given, the name of the source is used - + .. note:: `groupname:nxclass` notation can be used for both paths for better performance ''' - + fd = getattr(self, 'fd') if fd is None: - fd = getattr(src,'nxfile', getattr(dst,'nxfile')) + fd = getattr(src, 'nxfile', getattr(dst, 'nxfile')) if fd is None: raise self.nxs.NeXusError('Cannot get a file handle') - + if isinstance(src, self.nxs.NXobject): src = src.nxpath if isinstance(dst, self.nxs.NXobject): dst = dst.nxpath - + fd.openpath(src) try: nid = fd.getdataID() @@ -148,31 +152,34 @@ def _nxln(self, src, dst, name=None): if name is None: fd.makelink(nid) else: - fd.makenamedlink(name,nid) + fd.makenamedlink(name, nid) + + #========================================================================= + # Unimplemented methods that must be implemented in derived classes + #========================================================================= - #=========================================================================== - # Unimplemented methods that must be implemented in derived classes - #=========================================================================== - def _startRecordList(self, recordlist): - raise NotImplementedError('_startRecordList must be implemented in BaseNEXUS_FileRecorder derived classes') - + raise NotImplementedError( + '_startRecordList must be implemented in BaseNEXUS_FileRecorder derived classes') + def _writeRecord(self, record): - raise NotImplementedError('_writeRecord must be implemented in BaseNEXUS_FileRecorder derived classes') - + raise NotImplementedError( + '_writeRecord must be implemented in BaseNEXUS_FileRecorder derived classes') + def _endRecordList(self, recordlist): - raise NotImplementedError('_endRecordList must be implemented in BaseNEXUS_FileRecorder derived classes') + raise NotImplementedError( + '_endRecordList must be implemented in BaseNEXUS_FileRecorder derived classes') class BaseNAPI_FileRecorder(BaseNEXUS_FileRecorder): """Base class for NeXus file recorders (NAPI-based)""" - - #=========================================================================== + + #========================================================================= # Convenience methods to make NAPI less tedious - #=========================================================================== - + #========================================================================= + _nxentryInPath = re.compile(r'/[^/:]+:NXentry') - + def _makedata(self, name, dtype=None, shape=None, mode='lzw', chunks=None, comprank=None): ''' combines :meth:`nxs.NeXus.makedata` and :meth:`nxs.NeXus.compmakedata` by selecting between @@ -181,19 +188,23 @@ def _makedata(self, name, dtype=None, shape=None, mode='lzw', chunks=None, compr than comprank. If comprank is not passed (or None is passed) the default dataCompressionRank will be used ''' - if comprank is None: + if comprank is None: comprank = self._dataCompressionRank - - if shape is None or comprank<0 or (len(shape) < comprank): + + if shape is None or comprank < 0 or (len(shape) < comprank): return self.fd.makedata(name, dtype=dtype, shape=shape) else: try: - self.fd.compmakedata(name, dtype=dtype, shape=shape, mode=mode, chunks=chunks) - except ValueError: #workaround for bug in nxs<4.3 (compmakedatafails if chunks is not explicitly passed) - chunks = [1]*len(shape) + self.fd.compmakedata( + name, dtype=dtype, shape=shape, mode=mode, chunks=chunks) + # workaround for bug in nxs<4.3 (compmakedatafails if chunks is not + # explicitly passed) + except ValueError: + chunks = [1] * len(shape) chunks[-1] = shape[-1] - self.fd.compmakedata(name, dtype=dtype, shape=shape, mode=mode, chunks=chunks) - + self.fd.compmakedata( + name, dtype=dtype, shape=shape, mode=mode, chunks=chunks) + def _writeData(self, name, data, dtype, shape=None, chunks=None, attrs=None): ''' convenience method that creates datasets (calling self._makedata), opens @@ -204,15 +215,16 @@ def _writeData(self, name, data, dtype, shape=None, chunks=None, attrs=None): if shape is None: if dtype == 'char': shape = [len(data)] - chunks = chunks or list(shape) #for 'char', write the whole block in one chunk + # for 'char', write the whole block in one chunk + chunks = chunks or list(shape) else: - shape = getattr(data,'shape',[1]) + shape = getattr(data, 'shape', [1]) self._makedata(name, dtype=dtype, shape=shape, chunks=chunks) self.fd.opendata(name) self.fd.putdata(data) if attrs is not None: - for k,v in attrs.items(): - self.fd.putattr(k,v) + for k, v in attrs.items(): + self.fd.putattr(k, v) nid = self.fd.getdataID() self.fd.closedata() return nid @@ -227,18 +239,18 @@ def _newentryname(self, prefix='entry', suffix='', offset=1): if suffix: entry += " - " + suffix try: - self.fd.opengroup(entry,'NXentry') + self.fd.opengroup(entry, 'NXentry') self.fd.closegroup() i += 1 - except ValueError: #no such group name exists + except ValueError: # no such group name exists return entry - + def _nxln(self, src, dst): '''convenience function to create NX links with just one call. On successful return, dst will be open. - + :param src: (str) the nxpath to the source group or dataset :param dst: (str) the nxpath to the group that will hold the link - + .. note:: `groupname:nxclass` notation can be used for both paths for better performance ''' self.fd.openpath(src) @@ -248,14 +260,14 @@ def _nxln(self, src, dst): nid = self.fd.getgroupID() self.fd.openpath(dst) self.fd.makelink(nid) - + def _createBranch(self, path): """ Navigates the nexus tree starting in / and finishing in path. - + If path does not start with `/:NXentry`, the current entry is prepended to it. - + This method creates the groups if they do not exist. If the path is given using `name:nxclass` notation, the given nxclass is used. Otherwise, the class name is obtained from self.instrDict values (and if @@ -264,7 +276,8 @@ def _createBranch(self, path): """ m = self._nxentryInPath.match(path) if m is None: - self._createBranch("/%s:NXentry" % self.entryname) #if at all, it will recurse just once + # if at all, it will recurse just once + self._createBranch("/%s:NXentry" % self.entryname) # self.fd.openpath("/%s:NXentry" % self.entryname) else: self.fd.openpath("/") @@ -273,9 +286,9 @@ def _createBranch(self, path): for g in path.split('/'): if len(g) == 0: continue - relpath = relpath + "/"+ g + relpath = relpath + "/" + g if ':' in g: - g,group_type = g.split(':') + g, group_type = g.split(':') else: try: group_type = self.instrDict[relpath].klass diff --git a/src/sardana/macroserver/scan/scandata.py b/src/sardana/macroserver/scan/scandata.py index beec40f153..335f4e6e11 100644 --- a/src/sardana/macroserver/scan/scandata.py +++ b/src/sardana/macroserver/scan/scandata.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -55,13 +55,13 @@ def __init__(self, **kwargs): Any keyword not in the previous list will be converted to a member of the :class:`ColumnDesc`""" - #enforce that the mandatory arguments are present + # enforce that the mandatory arguments are present try: self.name = kwargs.pop('name') except: raise TypeError('"name" parameter is mandatory') - #make sure that at least the required members exist + # make sure that at least the required members exist self.label = kwargs.pop('label', self.name) self.setDtype(kwargs.pop('dtype', self.__class__._dtype)) self.setShape(kwargs.pop('shape', self.__class__._shape)) @@ -119,7 +119,7 @@ def toDict(self): def clone(self): return copy.deepcopy(self) - #return self.__class__(**self.toDict()) + # return self.__class__(**self.toDict()) class MoveableDesc(ColumnDesc): @@ -191,8 +191,8 @@ class RecordEnvironment(dict): """ A RecordEnvironment is a set of arbitrary pairs of type label/value in the form of a dictionary. """ - __needed = ['title', 'labels'] #@TODO: it seems that this has changed - #now labels are separated in moveables and counters + __needed = ['title', 'labels'] # @TODO: it seems that this has changed + # now labels are separated in moveables and counters def isValid(self): """ Check valid environment = all needed keys present """ @@ -266,8 +266,8 @@ def getEnviron(self): def start(self): self.recordno = 0 - ####@TODO: it is necessary only by continuous scan - #### think how to separate this two cases + # @TODO: it is necessary only by continuous scan + # think how to separate this two cases self.columnIndexDict = {} self.labels = [] self.refMoveablesLabels = [] @@ -286,7 +286,7 @@ def start(self): for label in self.labels: self.columnIndexDict[label] = 0 #### - self.datahandler.startRecordList(self) + self.datahandler.startRecordList(self) def initRecord(self): '''Init a dummy record and add it to the records list. @@ -300,7 +300,7 @@ def initRecord(self): initial_data = self.initial_data.get(recordno) else: initial_data = dict() - rc = Record({'point_nb' : recordno}) + rc = Record({'point_nb': recordno}) rc.data['timestamp'] = initial_data.get('timestamp') rc.setRecordNo(self.recordno) for label in self.channelLabels: @@ -323,7 +323,7 @@ def addRecord(self, record): self[self.recordno] = rc self.recordno += 1 self.datahandler.addRecord(self, rc) - self.currentIndex +=1 + self.currentIndex += 1 def applyZeroOrderInterpolation(self, record): ''' Apply a zero order interpolation to the given record @@ -352,7 +352,7 @@ def addData(self, data): recordsLen = len(self.records) # Calculate missing records missingRecords = recordsLen - (maxIdx + 1) - #TODO: implement proper handling of timestamps and moveables + # TODO: implement proper handling of timestamps and moveables if missingRecords < 0: missingRecords = abs(missingRecords) self.initRecords(missingRecords) @@ -365,14 +365,14 @@ def addData(self, data): def tryToAdd(self, idx, label): start = self.currentIndex - for i in range(start, idx+1): + for i in range(start, idx + 1): if self.isRecordCompleted(i): rc = self.records[i] self[self.currentIndex] = rc if self.applyInterpolation: self.applyZeroOrderInterpolation(rc) self.datahandler.addRecord(self, rc) - self.currentIndex +=1 + self.currentIndex += 1 def isRecordCompleted(self, recordno): rc = self.records[recordno] @@ -424,4 +424,3 @@ def getDataHandler(self): def getScanData(self, dh, apply_interpolation=False): return ScanData(data_handler=dh, apply_interpolation=apply_interpolation) - diff --git a/src/sardana/macroserver/scan/test/__init__.py b/src/sardana/macroserver/scan/test/__init__.py index 2684e35b2a..785a4380bd 100644 --- a/src/sardana/macroserver/scan/test/__init__.py +++ b/src/sardana/macroserver/scan/test/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/scan/test/helper.py b/src/sardana/macroserver/scan/test/helper.py index d1ad7a70f6..e62ed2b6cc 100644 --- a/src/sardana/macroserver/scan/test/helper.py +++ b/src/sardana/macroserver/scan/test/helper.py @@ -20,9 +20,10 @@ from sardana.macroserver.scan.recorder import DataHandler from sardana.macroserver.recorders.storage import NXscan_FileRecorder -from sardana.macroserver.scan.scandata import (ScanData, ScanDataEnvironment, +from sardana.macroserver.scan.scandata import (ScanData, ScanDataEnvironment, ColumnDesc) + class DummyEventSource(threading.Thread): def __init__(self, name, scanData, values, intervals=None): @@ -33,18 +34,18 @@ def __init__(self, name, scanData, values, intervals=None): def run(self): i = 0 - for v,t in zip(self.values, self.intervals): + for v, t in zip(self.values, self.intervals): try: - idx = range(i, i+len(v)) + idx = range(i, i + len(v)) i += len(v) skip = float('NaN') in v - except TypeError: # if v is not a list + except TypeError: # if v is not a list idx = [i] i += 1 v = [v] skip = float('NaN') in v if skip: - continue + continue time.sleep(t) _dict = dict(data=v, index=idx, label=self.name) self.scan_data.addData(_dict) @@ -52,15 +53,16 @@ def run(self): def get_obj(self): return self -def createScanDataEnvironment(columns, scanDir='/tmp/', + +def createScanDataEnvironment(columns, scanDir='/tmp/', scanFile='data_nxs.hdf5'): serialno = 1 env = ScanDataEnvironment( - { 'serialno' : serialno, - 'user' : "USER_NAME", - 'title' : "title_macro" } ) - + {'serialno': serialno, + 'user': "USER_NAME", + 'title': "title_macro"}) + env['name'] = "env_name" env['estimatedtime'] = -1.0 env['ScanDir'] = scanDir @@ -74,7 +76,7 @@ def createScanDataEnvironment(columns, scanDir='/tmp/', # Initialize the data_desc list (and add the point number column) data_desc = [] - column_master = ColumnDesc(name='point_nb', + column_master = ColumnDesc(name='point_nb', label='#Pt No', dtype='int64') data_desc.append(column_master) @@ -91,7 +93,7 @@ def main(): data_handler = DataHandler() file_name = "/tmp/data_nxs.hdf5" nx_recorder = NXscan_FileRecorder(filename=file_name, - macro="dscan", overwrite=True) + macro="dscan", overwrite=True) data_handler.addRecorder(nx_recorder) scan_dir, scan_file = os.path.split(file_name) columns = ['ch1', 'ch2'] @@ -119,6 +121,5 @@ def main(): ch1 = m['ch1'] print ch1.nxdata -if __name__=="__main__": +if __name__ == "__main__": main() - diff --git a/src/sardana/macroserver/scan/test/test_gscan.py b/src/sardana/macroserver/scan/test/test_gscan.py index 7777744ba2..621e80da62 100755 --- a/src/sardana/macroserver/scan/test/test_gscan.py +++ b/src/sardana/macroserver/scan/test/test_gscan.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -28,6 +28,7 @@ from taurus.external import unittest from taurus.test import insertTest + @insertTest(helper_name='prepare_waypoint', conf={"acc_time": 0.5, "dec_time": 0.5, "base_rate": 10, @@ -100,7 +101,8 @@ def prepare_waypoint(self, conf, expected): "active_time": 0.3 } start_positions = [conf["start_user_pos"]] - ideal_paths, _, _ = scan.prepare_waypoint(waypoint, start_positions) + ideal_paths, _, _ = scan.prepare_waypoint( + waypoint, start_positions) path = ideal_paths[0] # Asserts msg = 'Initial positions do not match. (expected={0}, got={1})'.format( diff --git a/src/sardana/macroserver/scan/test/test_recorddata.py b/src/sardana/macroserver/scan/test/test_recorddata.py index ce07752568..fa07bafa85 100644 --- a/src/sardana/macroserver/scan/test/test_recorddata.py +++ b/src/sardana/macroserver/scan/test/test_recorddata.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -35,21 +35,22 @@ DummyEventSource) data = { - 'ch1':[10., float('Nan'), 12., [float('Nan')]*3, 16.], - 'ch2':[20., 21., [22., 23., 24.], float('Nan'), [26.]], - 'ch3':[float('Nan'), float('Nan'), 32., 33., 34., 35., 36.] - } + 'ch1': [10., float('Nan'), 12., [float('Nan')] * 3, 16.], + 'ch2': [20., 21., [22., 23., 24.], float('Nan'), [26.]], + 'ch3': [float('Nan'), float('Nan'), 32., 33., 34., 35., 36.] +} data1 = { - 'ch1':[10., float('Nan'), 12., [float('Nan')]*3, 16.], - 'ch2':[20., 21., [22., 23., 24.], float('Nan'), [26.]], - 'ch3':[float('Nan'), float('Nan'), 32., 33., 34., 35.] - } + 'ch1': [10., float('Nan'), 12., [float('Nan')] * 3, 16.], + 'ch2': [20., 21., [22., 23., 24.], float('Nan'), [26.]], + 'ch3': [float('Nan'), float('Nan'), 32., 33., 34., 35.] +} data3 = { - 'ch1':[10., float('Nan'), 12., [float('Nan')]*3, 16.], - 'ch2':[20., 21., [22., 23., 24.], float('Nan'), [26.]] - } + 'ch1': [10., float('Nan'), 12., [float('Nan')] * 3, 16.], + 'ch2': [20., 21., [22., 23., 24.], float('Nan'), [26.]] +} + @insertTest(helper_name='recorddata', data=data1, apply_interpolation=False) @insertTest(helper_name='recorddata', data=data, apply_interpolation=False) @@ -60,6 +61,7 @@ class ScanDataTestCase(unittest.TestCase): data and verify that the stored data in the NeXus file corresponds with the initial data that has been sent for storage. """ + def setUp(self): """SetUp """ @@ -67,20 +69,20 @@ def setUp(self): self.data_handler = DataHandler() self.file_name = "/tmp/data_nxs.hdf5" nx_recorder = NXscan_FileRecorder(filename=self.file_name, - macro="dscan", overwrite=True) + macro="dscan", overwrite=True) self.data_handler.addRecorder(nx_recorder) def prepareScandData(self, data, apply_interpolation=False): scan_dir, scan_file = os.path.split(self.file_name) env = createScanDataEnvironment(data.keys(), scan_dir, scan_file) self.scan_data = ScanData(environment=env, - data_handler=self.data_handler, - apply_interpolation=apply_interpolation) + data_handler=self.data_handler, + apply_interpolation=apply_interpolation) self.srcs = [] self.inputs = {} max_len = -1 for name, dat in data.items(): - des = DummyEventSource(name, self.scan_data, dat, [0]*len(dat)) + des = DummyEventSource(name, self.scan_data, dat, [0] * len(dat)) self.srcs.append(des) input_list = [] for e in dat: @@ -95,7 +97,7 @@ def prepareScandData(self, data, apply_interpolation=False): # Pading the list to fill it with float('Nan') for name, dat in self.inputs.items(): diff = max_len - len(dat) - self.inputs[name] = dat + [float('Nan')]*diff + self.inputs[name] = dat + [float('Nan')] * diff def recorddata(self, data, apply_interpolation): """Verify that the data sent for storage is equal @@ -114,13 +116,13 @@ def recorddata(self, data, apply_interpolation): m = f['entry1']['measurement'] for chn in data.keys(): chn_data = m[chn].nxdata - #check the data element by element + # check the data element by element for i in range(len(chn_data)): msg = ('%s: input data is not equal to stored data. ' - 'Expected: %s , Read: %s' %\ + 'Expected: %s , Read: %s' % (chn, self.inputs[chn][i], chn_data[i])) if math.isnan(chn_data[i]) and \ - math.isnan(self.inputs[chn][i]): + math.isnan(self.inputs[chn][i]): continue self.assertEqual(chn_data[i], self.inputs[chn][i], msg) @@ -141,17 +143,16 @@ def zeroOrderInterpolation(self, data, apply_interpolation): m = f['entry1']['measurement'] for chn in data.keys(): chn_data = m[chn].nxdata - #check the interpolations + # check the interpolations for i in range(len(chn_data)): msg = '%s[%s]: has a "Nan" value.' % (chn, i) if math.isnan(self.inputs[chn][i]): self.assertFalse(math.isnan(chn_data[i]), msg) if i > 0: msg = ('%s[%s]: data has not been interpolated ' - 'properly. Expected: %s , Read: %s' %\ - (chn, i, chn_data[i], chn_data[i-1])) - self.assertEqual(chn_data[i-1], chn_data[i], msg) + 'properly. Expected: %s , Read: %s' % + (chn, i, chn_data[i], chn_data[i - 1])) + self.assertEqual(chn_data[i - 1], chn_data[i], msg) def tearDown(self): unittest.TestCase.tearDown(self) - diff --git a/src/sardana/macroserver/test/__init__.py b/src/sardana/macroserver/test/__init__.py index 37597d559c..b9f9196959 100755 --- a/src/sardana/macroserver/test/__init__.py +++ b/src/sardana/macroserver/test/__init__.py @@ -2,23 +2,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/test/res/__init__.py b/src/sardana/macroserver/test/res/__init__.py index 37597d559c..b9f9196959 100755 --- a/src/sardana/macroserver/test/res/__init__.py +++ b/src/sardana/macroserver/test/res/__init__.py @@ -2,23 +2,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/macroserver/test/res/fakerecorders.py b/src/sardana/macroserver/test/res/fakerecorders.py index 329326eafc..6ab8d279b7 100755 --- a/src/sardana/macroserver/test/res/fakerecorders.py +++ b/src/sardana/macroserver/test/res/fakerecorders.py @@ -2,29 +2,30 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## from sardana.macroserver.scan.recorder.storage import BaseFileRecorder + class FakeScanRecorder(BaseFileRecorder): """ Fake ScanRecorder class for test purpose""" pass diff --git a/src/sardana/macroserver/test/res/recorders/path1/fakerecorders.py b/src/sardana/macroserver/test/res/recorders/path1/fakerecorders.py index 05b09d8c3b..ada09294a4 100755 --- a/src/sardana/macroserver/test/res/recorders/path1/fakerecorders.py +++ b/src/sardana/macroserver/test/res/recorders/path1/fakerecorders.py @@ -2,33 +2,35 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## from sardana.macroserver.scan.recorder.storage import BaseFileRecorder + class FakeScanRecorder(BaseFileRecorder): """ Fake ScanRecorder class for test purpose""" pass + class FakeScanRecorderFormat(BaseFileRecorder): """ Fake ScanRecorder class for test purpose""" formats = {'Spec': '.spec'} diff --git a/src/sardana/macroserver/test/res/recorders/path2/fakerecorders.py b/src/sardana/macroserver/test/res/recorders/path2/fakerecorders.py index 05b09d8c3b..ada09294a4 100755 --- a/src/sardana/macroserver/test/res/recorders/path2/fakerecorders.py +++ b/src/sardana/macroserver/test/res/recorders/path2/fakerecorders.py @@ -2,33 +2,35 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## from sardana.macroserver.scan.recorder.storage import BaseFileRecorder + class FakeScanRecorder(BaseFileRecorder): """ Fake ScanRecorder class for test purpose""" pass + class FakeScanRecorderFormat(BaseFileRecorder): """ Fake ScanRecorder class for test purpose""" formats = {'Spec': '.spec'} diff --git a/src/sardana/macroserver/test/res/recorders/path3/fakerecorders.py b/src/sardana/macroserver/test/res/recorders/path3/fakerecorders.py index 05b09d8c3b..ada09294a4 100755 --- a/src/sardana/macroserver/test/res/recorders/path3/fakerecorders.py +++ b/src/sardana/macroserver/test/res/recorders/path3/fakerecorders.py @@ -2,33 +2,35 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## from sardana.macroserver.scan.recorder.storage import BaseFileRecorder + class FakeScanRecorder(BaseFileRecorder): """ Fake ScanRecorder class for test purpose""" pass + class FakeScanRecorderFormat(BaseFileRecorder): """ Fake ScanRecorder class for test purpose""" formats = {'Spec': '.spec'} diff --git a/src/sardana/macroserver/test/res/recorders/pathexternal/specrecorder.py b/src/sardana/macroserver/test/res/recorders/pathexternal/specrecorder.py index 9715326da6..98ad01678e 100644 --- a/src/sardana/macroserver/test/res/recorders/pathexternal/specrecorder.py +++ b/src/sardana/macroserver/test/res/recorders/pathexternal/specrecorder.py @@ -2,29 +2,30 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## from sardana.macroserver.scan.recorder import BaseFileRecorder + class SPEC_FileRecorder(BaseFileRecorder): """ Saves data to a file """ diff --git a/src/sardana/macroserver/test/test_msparameter.py b/src/sardana/macroserver/test/test_msparameter.py index 2252e64247..1e357d10e5 100644 --- a/src/sardana/macroserver/test/test_msparameter.py +++ b/src/sardana/macroserver/test/test_msparameter.py @@ -6,6 +6,7 @@ from sardana.macroserver.mstypemanager import TypeManager + class FakeMacroServer(object): name = "FakeMacroServer" @@ -60,6 +61,7 @@ class FakeMacroServer(object): doc3 = "Decode macro with one simple repeat parameter with correct value" doc4 = "Decode macro with one simple repeat parameter with min=0 and no values" + @insertTest(helper_name="decode", test_method_name="test_decode1", test_method_doc=doc1, params_def=params_def1, params_raw=params_raw1, expected_params=expected_params1) @@ -118,8 +120,8 @@ def decode(self, params_def, params_raw, expected_params=None, if expected_exception: msg = ("decoding exception type (%s) does not match with the" " expected exception type (%s)" % (type(exception), - expected_exception)) + expected_exception)) self.assertIsInstance(exception, expected_exception, msg) def tearDown(self): - unittest.TestCase.tearDown(self) \ No newline at end of file + unittest.TestCase.tearDown(self) diff --git a/src/sardana/macroserver/test/test_msrecordermanager.py b/src/sardana/macroserver/test/test_msrecordermanager.py index bd4f476e45..4d2152098c 100755 --- a/src/sardana/macroserver/test/test_msrecordermanager.py +++ b/src/sardana/macroserver/test/test_msrecordermanager.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -61,7 +61,7 @@ class RecorderManagerTest(unittest.TestCase): def setUp(self): name = self.ms_fullname.split("/")[1] self._macro_server = MacroServer(self.ms_fullname, name, macro_path=[], - recorder_path=[]) + recorder_path=[]) self.manager = self._macro_server.recorder_manager def tearDown(self): @@ -110,13 +110,13 @@ def getRecorderClass(self, klass_name, extra_paths=[]): """ self.manager.setRecorderPath(extra_paths) klass = self.manager.getRecorderClass(klass_name) - msg = "Recoder manager does not found the class %s" %(klass_name) + msg = "Recoder manager does not found the class %s" % (klass_name) self.assertNotEqual(klass, None, msg) _name = klass.__name__ - msg = "The class %s is not subclass of DataRecorder" %(_name) + msg = "The class %s is not subclass of DataRecorder" % (_name) self.assertTrue(issubclass(klass, DataRecorder), msg) msg = "The class name giveb by the recorder manager is different." +\ - "Expected %s, get %s" %(klass_name, _name) + "Expected %s, get %s" % (klass_name, _name) self.assertEqual(_name, klass_name, msg) def test_SameClassNames(self): @@ -148,7 +148,7 @@ def test_SameFormats(self): # set three paths containing recorders of the same format self._updateRecorderManager(recorder_path) klasses = self.manager.getRecorderMetaClasses(filter=BaseFileRecorder, - extension='.spec') + extension='.spec') klass = klasses.values()[0] # retrieve path to the recorder library path = os.sep.join(klass.lib.full_name.split(os.sep)[:-1]) @@ -158,7 +158,7 @@ def test_SameFormats(self): def test_ExternalVsBuiltinPrecedence(self): """Test if external recorders are of higher priority than the built-in) """ - external_path = os.path.join(_TEST_DIR, 'res', 'recorders', + external_path = os.path.join(_TEST_DIR, 'res', 'recorders', 'pathexternal') # set three paths containing recorders with the same class names diff --git a/src/sardana/pool/__init__.py b/src/sardana/pool/__init__.py index 4e1af10f3d..232369c6cb 100644 --- a/src/sardana/pool/__init__.py +++ b/src/sardana/pool/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/controller.py b/src/sardana/pool/controller.py index b86a7a1494..eb3fcee53f 100644 --- a/src/sardana/pool/controller.py +++ b/src/sardana/pool/controller.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -75,8 +75,8 @@ #: and :obj:`NotMemorized` Memorize = "memorized" -#: Constant memorized (to be used as a *value* in the :obj:`Memorize` field -#: definition in :attr:`~Controller.axis_attributes` or +#: Constant memorized (to be used as a *value* in the :obj:`Memorize` field +#: definition in :attr:`~Controller.axis_attributes` or #: :attr:`~Controller.ctrl_attributes`) Memorized = "true" @@ -97,7 +97,7 @@ class Controller(object): """Base controller class. Do **NOT** inherit from this class directly - + :param str inst: controller instance name :param dict props: a dictionary containning pairs of property name, property value @@ -130,19 +130,19 @@ class Controller(object): #: #: - for :obj:`DefaultValue`, value is a python object or None if no #: default value exists for the property. - #: + #: #: Example:: #: #: from sardana.pool.controller import MotorController, \ #: Type, Description, DefaultValue - #: + #: #: class MyCtrl(MotorController): - #: + #: #: ctrl_properties = \ #: { #: 'host' : { Type : str, #: Description : "host name" }, - #: 'port' : { Type : int, + #: 'port' : { Type : int, #: Description : "port number", #: DefaultValue: 5000 } #: } @@ -159,7 +159,7 @@ class Controller(object): #: - for :obj:`Type`, value is one of the values described in #: :ref:`sardana-controller-data-type` #: - #: - for :obj:`Access`, value is one of + #: - for :obj:`Access`, value is one of #: :obj:`~sardana.sardanadefs.DataAccess` ("read" or "read_write" #: (case insensitive) strings are also accepted) [default: ReadWrite] #: @@ -194,22 +194,22 @@ class Controller(object): #: .. versionadded:: 1.1 #: #: .. versionadded:: 1.0 - #: + #: #: Example:: - #: + #: #: from sardana.pool.controller import PseudoMotorController, \ #: Type, Description, DefaultValue, DataAccess - #: + #: #: class HKLCtrl(PseudoMotorController): - #: + #: #: ctrl_attributes = \ #: { #: 'ReflectionMatrix' : { Type : ( (float,), ), #: Description : "The reflection matrix", #: Access : DataAccess.ReadOnly, - #: FGet : 'getReflectionMatrix', }, + #: FGet : 'getReflectionMatrix', }, #: } - #: + #: #: def getReflectionMatrix(self): #: return ( (1.0, 0.0), (0.0, 1.0) ) ctrl_attributes = {} @@ -224,7 +224,7 @@ class Controller(object): #: - for :obj:`Type`, value is one of the values described in #: :ref:`sardana-controller-data-type` #: - #: - for :obj:`Access`, value is one of + #: - for :obj:`Access`, value is one of #: :obj:`~sardana.sardanadefs.DataAccess` ("read" or "read_write" #: (case insensitive) strings are also accepted) #: @@ -252,25 +252,25 @@ class Controller(object): #: .. versionadded:: 1.1 #: #: .. versionadded:: 1.0 - #: + #: #: Example:: - #: + #: #: from sardana.pool.controller import MotorController, \ #: Type, Description, DefaultValue, DataAccess - #: + #: #: class MyMCtrl(MotorController): - #: + #: #: axis_attributes = \ #: { #: 'EncoderSource' : { Type : str, #: Description : 'motor encoder source', }, #: } - #: + #: #: def getAxisPar(self, axis, name): #: name = name.lower() #: if name == 'encodersource': #: return self._encodersource[axis] - #: + #: #: def setAxisPar(self, axis, name, value): #: name = name.lower() #: if name == 'encodersource': @@ -295,7 +295,7 @@ class Controller(object): #: A :obj:`str` containning the path to the image logo file logo = None - + def __init__(self, inst, props, *args, **kwargs): self._inst_name = inst self._log = Logger("Controller.%s" % inst) @@ -679,7 +679,7 @@ def LoadOne(self, axis, value, repetitions): """**Controller API**. Override is MANDATORY! Called to load the integration time / monitor value. Default implementation raises :exc:`NotImplementedError`. - + :param int axis: axis number :param float value: integration time /monitor value :param int repetitions: number of repetitions @@ -775,34 +775,34 @@ class MotorController(Controller, Startable, Stopable, Readable): #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { - 'Position' : { 'type' : float, - 'description' : 'Position', }, - 'DialPosition' : { 'type' : float, - 'description' : 'Dial Position', }, - 'Offset' : { 'type' : float, - 'description' : 'Offset', }, - 'Sign' : { 'type' : float, - 'description' : 'Sign', }, - 'Step_per_unit' : { 'type' : float, - 'description' : 'Steps per unit', }, - 'Acceleration' : { 'type' : float, - 'description' : 'Acceleration time (s)', }, - 'Deceleration' : { 'type' : float, - 'description' : 'Deceleration time (s)', }, - 'Base_rate' : { 'type' : float, - 'description' : 'Base rate', }, - 'Velocity' : { 'type' : float, - 'description' : 'Velocity', }, - 'Backlash' : { 'type' : float, - 'description' : 'Backlash', }, - 'Limit_switches' : { 'type' : (bool,), - 'description' : "This attribute is the motor "\ - "limit switches state. It's an array with 3 \n"\ - "elements which are:\n"\ - "0 - The home switch\n"\ - "1 - The upper limit switch\n"\ - "2 - The lower limit switch\n"\ - "False means not active. True means active", }, + 'Position': {'type': float, + 'description': 'Position', }, + 'DialPosition': {'type': float, + 'description': 'Dial Position', }, + 'Offset': {'type': float, + 'description': 'Offset', }, + 'Sign': {'type': float, + 'description': 'Sign', }, + 'Step_per_unit': {'type': float, + 'description': 'Steps per unit', }, + 'Acceleration': {'type': float, + 'description': 'Acceleration time (s)', }, + 'Deceleration': {'type': float, + 'description': 'Deceleration time (s)', }, + 'Base_rate': {'type': float, + 'description': 'Base rate', }, + 'Velocity': {'type': float, + 'description': 'Velocity', }, + 'Backlash': {'type': float, + 'description': 'Backlash', }, + 'Limit_switches': {'type': (bool,), + 'description': "This attribute is the motor " + "limit switches state. It's an array with 3 \n" + "elements which are:\n" + "0 - The home switch\n" + "1 - The upper limit switch\n" + "2 - The lower limit switch\n" + "False means not active. True means active", }, } standard_axis_attributes.update(Controller.standard_axis_attributes) @@ -871,10 +871,10 @@ class CounterTimerController(Controller, Readable, Startable, Stopable, Loadable #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { - 'Value' : { 'type' : float, - 'description' : 'Value', }, - 'Data' : { 'type' : str, - 'description' : 'Data', }, + 'Value': {'type': float, + 'description': 'Value', }, + 'Data': {'type': str, + 'description': 'Data', }, } standard_axis_attributes.update(Controller.standard_axis_attributes) @@ -988,7 +988,7 @@ class TriggerGateController(Controller, Synchronizer, Stopable, Startable): """Base class for a trigger/gate controller. Inherit from this class to implement your own trigger/gate controller for the device pool. """ - + #: A :obj:`str` representing the controller gender gender = 'Trigger/Gate controller' @@ -1003,11 +1003,11 @@ class ZeroDController(Controller, Readable, Stopable): #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { - 'Value' : { 'type' : float, - 'description' : 'Value', }, + 'Value': {'type': float, + 'description': 'Value', }, } standard_axis_attributes.update(Controller.standard_axis_attributes) - + #: A :obj:`str` representing the controller gender gender = '0D controller' @@ -1022,13 +1022,13 @@ def AbortOne(self, axis): class OneDController(Controller, Readable, Startable, Stopable, Loadable): """Base class for a 1D controller. Inherit from this class to implement your own 1D controller for the device pool. - + .. versionadded:: 1.2""" standard_axis_attributes = { - 'Value' : { 'type' : (float,), - 'description' : 'Value', - 'maxdimsize' : (16*1024,) }, + 'Value': {'type': (float,), + 'description': 'Value', + 'maxdimsize': (16 * 1024,)}, } standard_axis_attributes.update(Controller.standard_axis_attributes) @@ -1038,7 +1038,7 @@ class OneDController(Controller, Readable, Startable, Stopable, Loadable): def __init__(self, inst, props, *args, **kwargs): Controller.__init__(self, inst, props, *args, **kwargs) self._latency_time = 0 - + def GetAxisPar(self, axis, parameter): """**Controller API**. Override is MANDATORY. Called to get a parameter value on the given axis. @@ -1059,9 +1059,9 @@ class TwoDController(Controller, Readable, Startable, Stopable, Loadable): implement your own 2D controller for the device pool.""" standard_axis_attributes = { - 'Value' : { 'type' : ((float,),), - 'description' : 'Value', - 'maxdimsize' : (4*1024, 4*1024) }, + 'Value': {'type': ((float,),), + 'description': 'Value', + 'maxdimsize': (4 * 1024, 4 * 1024)}, } standard_axis_attributes.update(Controller.standard_axis_attributes) @@ -1138,13 +1138,13 @@ class PseudoMotorController(PseudoController): #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { - 'Position' : { 'type' : float, - 'description' : 'Position', }, + 'Position': {'type': float, + 'description': 'Position', }, } #: A :obj:`str` representing the controller gender gender = 'Pseudo motor controller' - + def __init__(self, inst, props, *args, **kwargs): self.__motor_role_elements = {} self.__pseudo_motor_role_elements = {} @@ -1169,7 +1169,7 @@ def CalcAllPseudo(self, physical_pos, curr_pseudo_pos): .. versionadded:: 1.0""" ret = [] for i in range(len(self.pseudo_motor_roles)): - ret.append(self.CalcPseudo(i+1, physical_pos, curr_pseudo_pos)) + ret.append(self.CalcPseudo(i + 1, physical_pos, curr_pseudo_pos)) return ret def CalcAllPhysical(self, pseudo_pos, curr_physical_pos): @@ -1190,7 +1190,7 @@ def CalcAllPhysical(self, pseudo_pos, curr_physical_pos): .. versionadded:: 1.0""" ret = [] for i in range(len(self.motor_roles)): - pos = self.CalcPhysical(i+1, pseudo_pos, curr_physical_pos) + pos = self.CalcPhysical(i + 1, pseudo_pos, curr_physical_pos) ret.append(pos) return ret @@ -1245,10 +1245,9 @@ def calc_all_pseudo(self, physical_pos): implement :meth:`~PseudoMotorController.CalcAllPseudo` instead""" ret = [] for i in range(len(self.pseudo_motor_roles)): - ret.append(self.calc_pseudo(i+1, physical_pos)) + ret.append(self.calc_pseudo(i + 1, physical_pos)) return ret - def calc_all_physical(self, pseudo_pos): """**Pseudo Motor Controller API**. Override if necessary. Calculates the positions of all motors that belong to the pseudo @@ -1266,7 +1265,7 @@ def calc_all_physical(self, pseudo_pos): instead""" ret = [] for i in range(len(self.motor_roles)): - pos = self.calc_physical(i+1, pseudo_pos) + pos = self.calc_physical(i + 1, pseudo_pos) ret.append(pos) return ret @@ -1282,7 +1281,8 @@ def calc_pseudo(self, axis, physical_pos): .. deprecated:: 1.0 implement :meth:`~PseudoMotorController.CalcPseudo` instead""" - raise NotImplementedError("CalcPseudo must be defined in te controller") + raise NotImplementedError( + "CalcPseudo must be defined in te controller") def calc_physical(self, axis, pseudo_pos): """**Pseudo Motor Controller API**. Override is **MANDATORY**. @@ -1336,7 +1336,8 @@ def GetPseudoMotor(self, index_or_role): dict_axis = self._getPoolController().get_element_axis() pseudo_motor_ids = [] for akey, aname in dict_axis.items(): - pseudo_motor_ids.append(dict_ids.keys()[dict_ids.values().index(aname)]) + pseudo_motor_ids.append( + dict_ids.keys()[dict_ids.values().index(aname)]) return self._getElem(index_or_role, self.pseudo_motor_roles, self.__pseudo_motor_role_elements, pseudo_motor_ids) @@ -1366,13 +1367,13 @@ class PseudoCounterController(Controller): #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { - 'Value' : { 'type' : float, - 'description' : 'Value', }, + 'Value': {'type': float, + 'description': 'Value', }, } #: A :obj:`str` representing the controller gender gender = 'Pseudo counter controller' - + def Calc(self, axis, values): """**Pseudo Counter Controller API**. Override is **MANDATORY**. Calculate pseudo counter position given the counter values. @@ -1416,7 +1417,7 @@ def CalcAll(self, values): .. versionadded:: 1.2""" f, n = self.Calc, len(self.pseudo_counter_roles) - return [ f(i+1, values) for i in range(n) ] + return [f(i + 1, values) for i in range(n)] class IORegisterController(Controller, Readable): @@ -1431,17 +1432,16 @@ class IORegisterController(Controller, Readable): #: A :class:`dict` containing the standard attributes present on each axis #: device standard_axis_attributes = { - 'Value' : { 'type' : float, - 'description' : 'Value', }, + 'Value': {'type': float, + 'description': 'Value', }, } #: A :obj:`str` representing the controller gender gender = 'I/O register controller' - + def __init__(self, inst, props, *args, **kwargs): Controller.__init__(self, inst, props, *args, **kwargs) def WriteOne(self): """**IORegister Controller API**. Override if necessary.""" pass - diff --git a/src/sardana/pool/pool.py b/src/sardana/pool/pool.py index ca099a041f..783d546e60 100644 --- a/src/sardana/pool/pool.py +++ b/src/sardana/pool/pool.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -39,7 +39,7 @@ from taurus.core.taurusvalidator import AttributeNameValidator as\ TangoAttributeNameValidator except ImportError: - #TODO: For Taurus 4 compatibility + # TODO: For Taurus 4 compatibility from taurus.core.tango.tangovalidator import TangoAttributeNameValidator from taurus.core.util.containers import CaselessDict @@ -142,7 +142,7 @@ def __init__(self, full_name, name=None): PoolObject.__init__(self, full_name=full_name, name=name, id=InvalidId, pool=self, elem_type=ElementType.Pool) self._monitor = PoolMonitor(self, "PMonitor", auto_start=False) - #self.init_local_logging() + # self.init_local_logging() ControllerManager().set_pool(self) # TODO: not ready to use. path must be the same as the one calculated in @@ -232,9 +232,9 @@ def get_motion_loop_states_per_position(self): return self._motion_loop_states_per_position motion_loop_states_per_position = property(get_motion_loop_states_per_position, - set_motion_loop_states_per_position, - doc="Number of State reads done before doing a position read in the " - "motion loop") + set_motion_loop_states_per_position, + doc="Number of State reads done before doing a position read in the " + "motion loop") def set_acq_loop_sleep_time(self, acq_loop_sleep_time): self._acq_loop_sleep_time = acq_loop_sleep_time @@ -253,9 +253,9 @@ def get_acq_loop_states_per_value(self): return self._acq_loop_states_per_value acq_loop_states_per_value = property(get_acq_loop_states_per_value, - set_acq_loop_states_per_value, - doc="Number of State reads done before doing a value read in the " - "acquisition loop") + set_acq_loop_states_per_value, + doc="Number of State reads done before doing a value read in the " + "acquisition loop") def set_drift_correction(self, drift_correction): self._drift_correction = drift_correction @@ -266,6 +266,7 @@ def get_drift_correction(self): drift_correction = property(get_drift_correction, set_drift_correction, doc="drift correction") + @property def monitor(self): return self._monitor @@ -305,7 +306,8 @@ def get_controller_libs_summary_info(self): libs = self.get_controller_libs() ret = [] for ctrl_lib_info in libs: - elem = "%s (%s)" % (ctrl_lib_info.getName(), ctrl_lib_info.getFileName()) + elem = "%s (%s)" % (ctrl_lib_info.getName(), + ctrl_lib_info.getFileName()) ret.append(elem) return ret @@ -314,9 +316,11 @@ def get_controller_classes_summary_info(self): ret = [] for ctrl_class_info in ctrl_classes: types = ctrl_class_info.getTypes() - types_str = [ TYPE_MAP_OBJ[t].name for t in types if t != ElementType.Controller ] + types_str = [TYPE_MAP_OBJ[ + t].name for t in types if t != ElementType.Controller] types_str = ", ".join(types_str) - elem = "%s (%s) %s" % (ctrl_class_info.getName(), ctrl_class_info.getFileName(), types_str) + elem = "%s (%s) %s" % (ctrl_class_info.getName(), + ctrl_class_info.getFileName(), types_str) ret.append(elem) return ret @@ -332,7 +336,7 @@ def get_elements_str_info(self, obj_type=None): else: objs = self.get_elements_by_type(obj_type) name = self.full_name - return [ obj.str(pool=name) for obj in objs ] + return [obj.str(pool=name) for obj in objs] def get_elements_info(self, obj_type=None): if obj_type is None: @@ -347,7 +351,7 @@ def get_elements_info(self, obj_type=None): else: objs = self.get_elements_by_type(obj_type) name = self.full_name - return [ obj.serialize(pool=name) for obj in objs ] + return [obj.serialize(pool=name) for obj in objs] def get_acquisition_elements_info(self): ret = [] @@ -454,9 +458,9 @@ def create_element(self, **kwargs): raise Exception("Cannot create %s in %s controller" % (etype, ctrl_type_str)) - #check if controller is online - #check if axis is allowed - #create the element in the controller + # check if controller is online + # check if axis is allowed + # create the element in the controller eid = kwargs.get('id') if eid is None: @@ -648,8 +652,8 @@ def reload_controller_lib(self, lib_name): new_elements.extend(new_lib.get_controllers()) new_elements.append(new_lib) else: - new_names = set([ ctrl.name for ctrl in new_lib.get_controllers() ]) - old_names = set([ ctrl.name for ctrl in old_lib.get_controllers() ]) + new_names = set([ctrl.name for ctrl in new_lib.get_controllers()]) + old_names = set([ctrl.name for ctrl in old_lib.get_controllers()]) changed_names = set.intersection(new_names, old_names) deleted_names = old_names.difference(new_names) new_names = new_names.difference(old_names) @@ -661,8 +665,8 @@ def reload_controller_lib(self, lib_name): for deleted_name in deleted_names: deleted_elements.append(old_lib.get_controller(deleted_name)) - evt = { "new" : new_elements, "change" : changed_elements, - "del" : deleted_elements } + evt = {"new": new_elements, "change": changed_elements, + "del": deleted_elements} self.fire_event(EventType("ElementsChanged"), evt) @@ -680,7 +684,7 @@ def get_element_id_graph(self): elem_type_map = self.get_element_type_map() for elem_type in TYPE_PHYSICAL_ELEMENTS: physical_elems_id_map.update(elem_type_map[elem_type]) - #TODO + # TODO def _build_element_id_dependencies(self, elem_id, graph=None): if graph is None: diff --git a/src/sardana/pool/poolacquisition.py b/src/sardana/pool/poolacquisition.py index 0194b7984f..bb995a6be6 100644 --- a/src/sardana/pool/poolacquisition.py +++ b/src/sardana/pool/poolacquisition.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -45,27 +45,28 @@ from sardana.pool.poolsynchronization import PoolSynchronization #: enumeration representing possible motion states -AcquisitionState = Enumeration("AcquisitionState", (\ +AcquisitionState = Enumeration("AcquisitionState", ( "Stopped", -# "StoppedOnError", -# "StoppedOnAbort", + # "StoppedOnError", + # "StoppedOnAbort", "Acquiring", "Invalid")) AS = AcquisitionState AcquiringStates = AS.Acquiring, -StoppedStates = AS.Stopped, #MS.StoppedOnError, MS.StoppedOnAbort +StoppedStates = AS.Stopped, # MS.StoppedOnError, MS.StoppedOnAbort AcquisitionMap = { - #AS.Stopped : State.On, - AS.Acquiring : State.Moving, - AS.Invalid : State.Invalid, + # AS.Stopped : State.On, + AS.Acquiring: State.Moving, + AS.Invalid: State.Invalid, } + def split_MGConfigurations(mg_cfg_in): """Split MeasurementGroup configuration with channels triggered by SW Trigger and channels triggered by HW trigger - + TODO: (technical debt) All the MeasurementGroup configuration logic should be encapsulate in a dedicated class instead of using a basic data structures like dict or lists... @@ -104,9 +105,10 @@ def split_MGConfigurations(mg_cfg_in): mg_hw_cfg_out['monitor'] = ctrls_hw_out.values()[0]['monitor'] return (mg_hw_cfg_out, mg_sw_cfg_out, mg_0d_cfg_out) + def getTGConfiguration(MGcfg): '''Build TG configuration from complete MG configuration. - + TODO: (technical debt) All the MeasurementGroup configuration logic should be encapsulate in a dedicated class instead of using a basic data structures like dict or lists... @@ -123,8 +125,8 @@ def getTGConfiguration(MGcfg): for ctrl in MGcfg["controllers"]: tg_element = MGcfg["controllers"][ctrl].get('synchronizer', None) if (tg_element != None and - tg_element != "software" and - tg_element not in _tg_element_list): + tg_element != "software" and + tg_element not in _tg_element_list): _tg_element_list.append(tg_element) # Intermediate dictionary to organize each ctrl with its elements. @@ -145,10 +147,11 @@ def getTGConfiguration(MGcfg): ctrls['channels'] = {} for tg_elem in ctrl_tgelem_dict[ctrl]: ch = ctrls['channels'][tg_elem] = {} - ch['full_name']= tg_elem.full_name - #TODO: temporary returning tg_elements + ch['full_name'] = tg_elem.full_name + # TODO: temporary returning tg_elements return TGcfg, _tg_element_list + def extract_integ_time(synchronization): """Extract integration time(s) from synchronization dict. If there is only one group in the synchronization than returns float with the integration @@ -266,9 +269,9 @@ def event_received(self, *args, **kwargs): def is_running(self): return self._0d_acq.is_running() or\ - self._sw_acq.is_running() or\ - self._hw_acq.is_running() or\ - self._synch.is_running() + self._sw_acq.is_running() or\ + self._hw_acq.is_running() or\ + self._synch.is_running() def run(self, *args, **kwargs): for elem in self.get_elements(): @@ -277,7 +280,7 @@ def run(self, *args, **kwargs): synchronization = kwargs["synchronization"] integ_time = extract_integ_time(synchronization) repetitions = extract_repetitions(synchronization) - # TODO: this code splits the global mg configuration into + # TODO: this code splits the global mg configuration into # experimental channels triggered by hw and experimental channels # triggered by sw. Refactor it!!!! (hw_acq_cfg, sw_acq_cfg, zerod_acq_cfg) = split_MGConfigurations(config) @@ -348,7 +351,7 @@ def remove_element(self, element): :raises: ValueError""" for action in self._get_acq_for_element(element): - action.remove_element(element) + action.remove_element(element) def get_elements(self, copy_of=False): """Returns a sequence of all elements involved in this action. @@ -360,7 +363,7 @@ def get_elements(self, copy_of=False): :return: a sequence of all elements involved in this action. :rtype: seq""" return (self._hw_acq.get_elements() + self._sw_acq.get_elements() + - self._0d_acq.get_elements() + self._synch.get_elements()) + self._0d_acq.get_elements() + self._synch.get_elements()) def get_pool_controller_list(self): """Returns a list of all controller elements involved in this action. @@ -393,7 +396,7 @@ def read_value(self, ret=None, serial=False): :return: a map containing value information per element :rtype: dict<:class:~`sardana.pool.poolelement.PoolElement`, :class:~`sardana.sardanavalue.SardanaValue`>""" - #TODO: this is broken now - fix it + # TODO: this is broken now - fix it ret = self._ct_acq.read_value(ret=ret, serial=serial) ret.update(self._0d_acq.read_value(ret=ret, serial=serial)) return ret @@ -568,7 +571,7 @@ def start_action(self, *args, **kwargs): try: res = ctrl.PreLoadOne(axis, master_value, repetitions) except TypeError: - #TODO: raise correctly deprecation warning + # TODO: raise correctly deprecation warning self.warning("PreLoadOne API has changed") res = ctrl.PreLoadOne(axis, master_value) if not res: @@ -578,7 +581,7 @@ def start_action(self, *args, **kwargs): try: ctrl.LoadOne(axis, master_value, repetitions) except TypeError: - #TODO: raise correctly deprecation warning + # TODO: raise correctly deprecation warning self.warning("LoadOne API has changed") ctrl.LoadOne(axis, master_value) ctrl.LoadAll() @@ -645,6 +648,7 @@ class PoolAcquisitionHardware(PoolAcquisitionBase): (up to and including removal of the module) may occur if deemed necessary by the core developers. """ + def __init__(self, main_element, name="AcquisitionHardware"): PoolAcquisitionBase.__init__(self, main_element, name) @@ -691,8 +695,8 @@ def action_loop(self): if acquirable in values: value = values[acquirable] if isinstance(value, SardanaValue) and value.error: - self.warning("Error when reading value: %r" % - value.exc_info) + self.warning("Error when reading value: %r" % + value.exc_info) elif len(value) > 0: channel = self._channels[acquirable] channel._fill_idx(value) @@ -795,7 +799,6 @@ def __init__(self, main_element, name="CTAcquisition", slaves=None): def get_read_value_loop_ctrls(self): return self._pool_ctrl_dict_loop - def in_acquisition(self, states): """Determines if we are in acquisition or if the acquisition has ended based on the current unit trigger modes and states returned by the @@ -826,7 +829,7 @@ def action_loop(self): # read values to send a first event when starting to acquire with ActionContext(self): self.raw_read_value_loop(ret=values) - for acquirable, value in values.items(): + for acquirable, value in values.items(): acquirable.put_value(value, propagate=2) while True: @@ -837,7 +840,7 @@ def action_loop(self): # read value every n times if not i % nb_states_per_value: self.read_value_loop(ret=values) - for acquirable, value in values.items(): + for acquirable, value in values.items(): acquirable.put_value(value) time.sleep(nap) @@ -950,7 +953,8 @@ def action_loop(self): while True: self.read_value(ret=values) for acquirable, value in values.items(): - acquirable.put_value(value, index=self.conf['idx'], propagate=0) + acquirable.put_value(value, index=self.conf[ + 'idx'], propagate=0) if self._stopped or self._aborted: break time.sleep(nap) diff --git a/src/sardana/pool/poolaction.py b/src/sardana/pool/poolaction.py index 069c2cb5dc..a3ad50a027 100644 --- a/src/sardana/pool/poolaction.py +++ b/src/sardana/pool/poolaction.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -456,7 +456,8 @@ def action_loop(self): NotImplementedError :raises: NotImplementedError""" - raise NotImplementedError("action_loop must be implemented in subclass") + raise NotImplementedError( + "action_loop must be implemented in subclass") def read_state_info(self, ret=None, serial=False): """Reads state information of all elements involved in this action @@ -521,7 +522,8 @@ def _get_ctrl_error_state_info(self, pool_ctrl): return State.Fault, "Unknown controller error" else: if pool_ctrl.is_online(): - err_msg = "".join(traceback.format_exception(exc_t, exc_v, trb)) + err_msg = "".join( + traceback.format_exception(exc_t, exc_v, trb)) return State.Fault, "Unexpected controller error:\n" + err_msg return State.Fault, pool_ctrl.get_ctrl_error_str() diff --git a/src/sardana/pool/poolbasechannel.py b/src/sardana/pool/poolbasechannel.py index 8c790fc52a..dac28bc5bb 100644 --- a/src/sardana/pool/poolbasechannel.py +++ b/src/sardana/pool/poolbasechannel.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -61,7 +61,7 @@ def __init__(self, **kwargs): def get_value_attribute(self): """Returns the value attribute object for this experiment channel - + :return: the value attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._value @@ -178,6 +178,7 @@ def start_acquisition(self, value=None): if value is None: value = self.get_write_value() if value is None: - raise Exception("Invalid integration_time '%s'. Hint set a new value for 'value' first" % value) + raise Exception( + "Invalid integration_time '%s'. Hint set a new value for 'value' first" % value) if not self._simulation_mode: acq = self.acquisition.run(integ_time=value) diff --git a/src/sardana/pool/poolbaseelement.py b/src/sardana/pool/poolbaseelement.py index fc96719674..13f0eb723e 100644 --- a/src/sardana/pool/poolbaseelement.py +++ b/src/sardana/pool/poolbaseelement.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -43,7 +43,7 @@ class PoolBaseElement(PoolObject): """A Pool object that besides the name, reference to the pool, ID, full_name and user_full_name has: - + - _simulation_mode : boolean telling if in simulation mode - _state : element state - _status : element status""" @@ -80,7 +80,7 @@ def __exit__(self, exc_type, exc_value, traceback): def lock(self, blocking=True): """Acquires the this element lock - + :param blocking: whether or not to block if lock is already acquired [default: True] :type blocking: bool""" @@ -105,7 +105,7 @@ def serialize(self, *args, **kwargs): def get_simulation_mode(self, cache=True, propagate=1): """Returns the simulation mode for this object. - + :param cache: not used [default: True] :type cache: bool :param propagate: [default: 1] @@ -139,7 +139,7 @@ def get_state(self, cache=True, propagate=1): returns the current state stored in cache (it will force an update if cache is empty). If propagate > 0 and if the state changed since last read, it will propagate the state event to all listeners. - + :param cache: tells if return value from local cache or update from HW read [default: True] @@ -197,7 +197,7 @@ def get_status(self, cache=True, propagate=1): returns the current status stored in cache (it will force an update if cache is empty). If propagate > 0 and if the status changed since last read, it will propagate the status event to all listeners. - + :param cache: tells if return value from local cache or update from HW read [default: True] @@ -238,6 +238,7 @@ def put_status(self, status): # -------------------------------------------------------------------------- _STD_STATUS = "{name} is {state}\n{ctrl_status}" + def calculate_state_info(self, status_info=None): """Transforms the given state information. This specific base implementation transforms the given state,status tuple into a @@ -245,7 +246,7 @@ def calculate_state_info(self, status_info=None): plus the given status. It is assumed that the given status comes directly from the controller status information. - + :param status_info: given status information [default: None, meaning use current state status. :type status_info: tuple @@ -357,4 +358,4 @@ def set_operation(self, operation): self._operation = operation def clear_operation(self): - return self.set_operation(None) \ No newline at end of file + return self.set_operation(None) diff --git a/src/sardana/pool/poolbasegroup.py b/src/sardana/pool/poolbasegroup.py index 8986730b60..8928c5d0c0 100644 --- a/src/sardana/pool/poolbasegroup.py +++ b/src/sardana/pool/poolbasegroup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -34,7 +34,7 @@ from taurus.core.taurusvalidator import AttributeNameValidator as\ TangoAttributeNameValidator except ImportError: - #TODO: For Taurus 4 compatibility + # TODO: For Taurus 4 compatibility from taurus.core.tango.tangovalidator import TangoAttributeNameValidator from sardana import State, ElementType, TYPE_PHYSICAL_ELEMENTS @@ -57,8 +57,8 @@ def __init__(self, **kwargs): try: self._build_elements() except KeyError: - self.info("failed to build element information. No problem. " \ - "Probably one or more underlying elements have not " \ + self.info("failed to build element information. No problem. " + "Probably one or more underlying elements have not " "been constructed yet") def _get_pool(self): @@ -109,14 +109,16 @@ def _calculate_states(self, state_info=None): for elem in user_elements: if elem.get_type() == ElementType.External: continue - # cannot call get_state(us) here since it may lead to dead lock! + # cannot call get_state(us) here since it may lead to dead + # lock! si = elem.inspect_state(), elem.inspect_status() state_info[elem] = si for elem, elem_state_info in state_info.items(): elem_type = elem.get_type() if elem_type == ElementType.External: continue - u_state, u_status = self._calculate_element_state(elem, elem_state_info) + u_state, u_status = self._calculate_element_state( + elem, elem_state_info) if u_state == State.Moving: moving.add(elem) elif u_state == State.On: @@ -139,9 +141,9 @@ def _calculate_states(self, state_info=None): state = State.Alarm elif moving: state = State.Moving - self._state_statistics = { State.On : on, State.Fault : fault, - State.Alarm : alarm, State.Moving : moving, - State.Unknown : unknown, None : none } + self._state_statistics = {State.On: on, State.Fault: fault, + State.Alarm: alarm, State.Moving: moving, + State.Unknown: unknown, None: none} status = "\n".join(status) return state, status @@ -189,7 +191,7 @@ def set_user_element_ids(self, new_element_ids): def get_user_element_ids(self): """Returns the sequence of user element IDs - + :return: the sequence of user element IDs :rtype: sequence< :obj:`int`>""" return self._user_element_ids @@ -198,7 +200,7 @@ def get_user_element_ids(self): def get_user_elements(self): """Returns the sequence of user elements - + :return: the sequence of user elements :rtype: sequence< :class:`~sardana.pool.poolelement.PoolElement`>""" if self._pending: @@ -207,7 +209,7 @@ def get_user_elements(self): def get_user_elements_attribute_iterator(self): """Returns an iterator over the main attribute of each user element. - + :return: an iterator over the main attribute of each user element. :rtype: iter< :class:`~sardana.sardanaattribute.SardanaAttribute` >""" for element in self.get_user_elements(): @@ -218,17 +220,17 @@ def get_user_elements_attribute_iterator(self): def get_user_elements_attribute_sequence(self): """Returns a sequence of main attribute of each user element. - + In loops use preferably :meth:`get_user_elements_attribute_iterator` for performance and memory reasons. - + :return: a sequence of main attribute of each user element. :rtype: sequence< :class:`~sardana.sardanaattribute.SardanaAttribute` >""" return list(self.get_user_elements_attribute_iterator()) def get_user_elements_attribute_map(self): """Returns a dictionary of main attribute of each user element. - + :return: a dictionary of main attribute of each user element. :rtype: dict< :class:`~sardana.pool.poolelement.PoolElement`, :class:`~sardana.sardanaattribute.SardanaAttribute` >""" @@ -240,7 +242,7 @@ def get_user_elements_attribute_map(self): def get_physical_elements(self): """Returns a dictionary or physical elements where key is a controller object and value is a sequence of pool elements - + :return: a dictionary of physical elements :rtype: dict< :class:`~sardana.pool.poolcontroller.PoolController, sequence<:class:`~sardana.pool.poolelement.PoolElement`>""" @@ -250,9 +252,9 @@ def get_physical_elements(self): def get_physical_elements_iterator(self): """Returns an iterator over the physical elements. - + .. warning:: The order is non deterministic. - + :return: an iterator over the physical elements. :rtype: iter<:class:`~sardana.pool.poolelement.PoolElement` >""" for _, elements in self.get_physical_elements().items(): @@ -261,9 +263,9 @@ def get_physical_elements_iterator(self): def get_physical_elements_attribute_iterator(self): """Returns an iterator over the main attribute of each physical element. - + .. warning:: The order is non deterministic. - + :return: an iterator over the main attribute of each physical element. :rtype: iter< :class:`~sardana.sardanaattribute.SardanaAttribute` >""" for element in self.get_physical_elements_iterator(): @@ -349,7 +351,6 @@ def clear_user_elements(self): self._user_element_ids = None self._physical_elements = None - # -------------------------------------------------------------------------- # stop # -------------------------------------------------------------------------- diff --git a/src/sardana/pool/poolbaseobject.py b/src/sardana/pool/poolbaseobject.py index 37bb609a1f..7dbc4109d6 100644 --- a/src/sardana/pool/poolbaseobject.py +++ b/src/sardana/pool/poolbaseobject.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -35,24 +35,23 @@ class PoolBaseObject(SardanaBaseObject): """The Pool most abstract object.""" - + def __init__(self, **kwargs): kwargs['manager'] = kwargs.pop('pool') SardanaBaseObject.__init__(self, **kwargs) - + def get_pool(self): """Return the :class:`sardana.pool.pool.Pool` which *owns* this pool object. - + :return: the pool which *owns* this pool object. :rtype: :class:`sardana.pool.pool.Pool`""" return self.get_manager() - + def serialize(self, *args, **kwargs): kwargs = SardanaBaseObject.serialize(self, *args, **kwargs) kwargs['pool'] = self.pool.name return kwargs - + pool = property(get_pool, doc="reference to the :class:`sardana.pool.pool.Pool`") - diff --git a/src/sardana/pool/poolcontainer.py b/src/sardana/pool/poolcontainer.py index 43b77c9db6..2fbecdf8f6 100644 --- a/src/sardana/pool/poolcontainer.py +++ b/src/sardana/pool/poolcontainer.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -35,17 +35,17 @@ class PoolContainer(SardanaContainer): """A container class for pool elements""" - + def get_controller_class(self, **kwargs): eid = kwargs.get("id") if eid is not None: return self.get_controller_class_by_id(eid, **kwargs) - + name = kwargs.pop("name") self.get_controller_class_by_name(name, **kwargs) - + def get_controller_class_by_id(self, eid, **kwargs): raise NotImplementedError - + def get_controller_class_by_name(self, name, **kwargs): - raise NotImplementedError \ No newline at end of file + raise NotImplementedError diff --git a/src/sardana/pool/poolcontroller.py b/src/sardana/pool/poolcontroller.py index 5e1e60b6a6..29a67c077c 100644 --- a/src/sardana/pool/poolcontroller.py +++ b/src/sardana/pool/poolcontroller.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -50,6 +50,7 @@ class PoolBaseController(PoolBaseElement): """Base class for all controllers""" + def __init__(self, **kwargs): self._ctrl = None self._ctrl_error = None @@ -102,13 +103,13 @@ def add_element(self, elem, propagate=1): self._element_axis[axis] = elem self._element_names[name] = elem else: - #TODO: raise exception + # TODO: raise exception self._pending_element_ids[eid] = elem self._pending_element_axis[axis] = elem self._pending_element_names[name] = elem if propagate: elements = self.get_elements() - elements = [ elements[_id].name for _id in sorted(elements) ] + elements = [elements[_id].name for _id in sorted(elements)] self.fire_event(EventType("elementlist", priority=propagate), elements) @@ -132,7 +133,7 @@ def remove_element(self, elem, propagate=1): self.error("Unable to delete %s(%s)", name, axis, exc_info=1) if propagate: elements = self.get_elements() - elements = [ elements[_id].name for _id in sorted(elements) ] + elements = [elements[_id].name for _id in sorted(elements)] self.fire_event(EventType("elementlist", priority=propagate), elements) @@ -199,7 +200,7 @@ def get_element(self, **kwargs): def read_axis_states(self, axes=None): """Reads the state for the given axes. If axes is None, reads the state of all active axes. - + :param axes: the list of axis to get the state. Default is None meaning all active axis in this controller :type axes: seq or None @@ -211,7 +212,7 @@ def read_axis_states(self, axes=None): def read_axis_values(self, axes=None): """Reads the value for the given axes. If axes is None, reads the value of all active axes. - + :param axes: the list of axis to get the value. Default is None meaning all active axis in this controller :type axes: seq or None @@ -243,6 +244,7 @@ def get_status(self, cache=True, propagate=1): return self._status _STD_STATUS = '{name} is {state}' + def calculate_state_info(self, status_info=None): """Transforms the given state information. This specific base implementation transforms the given state,status tuple into a @@ -265,11 +267,12 @@ def check_ctrl(fn): @functools.wraps(fn) def wrapper(pool_ctrl, *args, **kwargs): if not pool_ctrl.is_online(): - raise Exception("Cannot execute '%s' because '%s' is offline" % \ + raise Exception("Cannot execute '%s' because '%s' is offline" % (fn.__name__, pool_ctrl.name)) return fn(pool_ctrl, *args, **kwargs) return wrapper + def ctrl_access(fn): @functools.wraps(fn) def wrapper(pool_ctrl, *args, **kwargs): @@ -346,7 +349,8 @@ def _init(self): def re_init(self): self.set_state(State.Init, propagate=2) - status = "{0} is Initializing (temporarily unavailable)".format(self.name) + status = "{0} is Initializing (temporarily unavailable)".format( + self.name) self.set_status(status, propagate=2) manager = self.pool.ctrl_manager old_e_ids = self._element_ids @@ -400,22 +404,24 @@ def is_online(self): def get_ctrl(self): return self._ctrl - + def set_ctrl(self, ctrl): self._ctrl = ctrl - ctrl = property(fget=get_ctrl, fset=set_ctrl, doc="actual controller object") + ctrl = property(fget=get_ctrl, fset=set_ctrl, + doc="actual controller object") def get_ctrl_info(self): return self._ctrl_info - ctrl_info = property(fget=get_ctrl_info, doc="controller information object") + ctrl_info = property(fget=get_ctrl_info, + doc="controller information object") def set_operator(self, operator): """Defines the current operator object for this controller. For example, in acquisition, it should be a :class:`PoolMeasurementGroup` object. - + :param operator: the new operator object :type operator: object""" self._operator = operator @@ -423,9 +429,10 @@ def set_operator(self, operator): def get_operator(self): return self._operator - operator = property(fget=get_operator, fset=set_operator, doc="current controller operator") + operator = property(fget=get_operator, fset=set_operator, + doc="current controller operator") - # START API WHICH ACCESSES CONTROLLER API ---------------------------------- + # START API WHICH ACCESSES CONTROLLER API -------------------------------- @check_ctrl def set_log_level(self, level): @@ -498,10 +505,9 @@ def set_axis_par(self, axis, name, value): def get_axis_par(self, axis, name): return self.ctrl.GetAxisPar(axis, name) + # END API WHICH ACCESSES CONTROLLER API ---------------------------------- - # END API WHICH ACCESSES CONTROLLER API ------------------------------------ - - # START API WHICH ACCESSES CRITICAL CONTROLLER API (like StateOne) --------- + # START API WHICH ACCESSES CRITICAL CONTROLLER API (like StateOne) ------- def __build_exc_info(self, ctrl_states, axes, exc_info): status = "".join(traceback.format_exception(*exc_info)) @@ -521,7 +527,7 @@ def _format_exception(exc_info): def raw_read_axis_states(self, axes=None, ctrl_states=None): """**Unsafe method**. Reads the state for the given axes. If axes is None, reads the state of all active axes. - + :param axes: the list of axis to get the state. Default is None meaning all active axis in this controller :type axes: seq or None @@ -571,7 +577,7 @@ def raw_read_axis_states(self, axes=None, ctrl_states=None): def read_axis_states(self, axes=None): """Reads the state for the given axes. If axes is None, reads the state of all active axes. - + :param axes: the list of axis to get the state. Default is None meaning all active axis in this controller :type axes: seq or None @@ -588,9 +594,9 @@ def _read_axis_value(self, element): msg = '%s.ReadOne(%s[%d]) return error: Expected value(s), ' \ 'got None instead' % (self.name, element.name, axis) raise ValueError(msg) - if (type_ == ElementType.CTExpChannel and is_non_str_seq(ctrl_value) or\ - type_ == ElementType.OneDExpChannel and not is_number(ctrl_value[0]) or\ - type_ == ElementType.TwoDExpChannel and not is_number(ctrl_value[0][0])): + if (type_ == ElementType.CTExpChannel and is_non_str_seq(ctrl_value) or + type_ == ElementType.OneDExpChannel and not is_number(ctrl_value[0]) or + type_ == ElementType.TwoDExpChannel and not is_number(ctrl_value[0][0])): value = [translate_ctrl_value(v) for v in ctrl_value] else: value = translate_ctrl_value(ctrl_value) @@ -601,7 +607,7 @@ def _read_axis_value(self, element): def raw_read_axis_values(self, axes=None, ctrl_values=None): """**Unsafe method**. Reads the value for the given axes. If axes is None, reads the value of all active axes. - + :param axes: the list of axis to get the value. Default is None meaning all active axis in this controller :type axes: seq or None @@ -636,7 +642,7 @@ def raw_read_axis_values(self, axes=None, ctrl_values=None): def read_axis_values(self, axes=None): """Reads the value for the given axes. If axes is None, reads the value of all active axes. - + :param axes: the list of axis to get the value. Default is None meaning all active axis in this controller :type axes: seq or None @@ -685,7 +691,7 @@ def stop_one(self, axis): @check_ctrl def stop_axes(self, axes=None): """Stops the given axes. If axes is None, stops all active axes. - + :param axes: the list of axis to stop. Default is None meaning all active axis in this controller :type axes: seq or None @@ -699,7 +705,7 @@ def stop_axes(self, axes=None): @check_ctrl def stop_elements(self, elements=None): """Stops the given elements. If axes is None, stops all active axes. - + :param elements: the list of elements to stop. Default is None meaning all active axis in this controller :type axes: seq or None @@ -749,7 +755,7 @@ def abort_one(self, axis): @check_ctrl def abort_axes(self, axes=None): """Aborts the given axes. If axes is None, aborts all active axes. - + :param axes: the list of axis to abort. Default is None meaning all active axis in this controller :type axes: seq or None @@ -763,7 +769,7 @@ def abort_axes(self, axes=None): @check_ctrl def abort_elements(self, elements=None): """Aborts the given elements. If axes is None, aborts all active axes. - + :param elements: the list of elements to abort. Default is None meaning all active axis in this controller :type axes: seq or None @@ -780,7 +786,7 @@ def abort_elements(self, elements=None): def emergency_break(self, elements=None): """Stops the given elements. If axes is None, stops all active axes. If stop raises exception, an abort is attempted. - + :param elements: the list of elements to stop. Default is None meaning all active axis in this controller :type axes: seq or None @@ -801,9 +807,9 @@ def emergency_break(self, elements=None): def send_to_controller(self, stream): return self.ctrl.SendToCtrl(stream) - # END API WHICH ACCESSES CRITICAL CONTROLLER API (like StateOne) ----------- + # END API WHICH ACCESSES CRITICAL CONTROLLER API (like StateOne) --------- - # START SPECIFIC TO MOTOR CONTROLLER --------------------------------------- + # START SPECIFIC TO MOTOR CONTROLLER ------------------------------------- def raw_move(self, axis_pos): ctrl = self.ctrl @@ -811,7 +817,7 @@ def raw_move(self, axis_pos): for axis, dial_position in axis_pos.items(): ret = ctrl.PreStartOne(axis, dial_position) if not ret: - raise Exception("%s.PreStartOne(%d, %f) returns False" \ + raise Exception("%s.PreStartOne(%d, %f) returns False" % (self.name, axis, dial_position)) for axis, dial_position in axis_pos.items(): @@ -833,14 +839,14 @@ def wants_rounding(self): def define_position(self, axis, position): return self.ctrl.DefinePosition(axis, position) - # END SPECIFIC TO MOTOR CONTROLLER ----------------------------------------- + # END SPECIFIC TO MOTOR CONTROLLER --------------------------------------- - # START SPECIFIC TO IOR CONTROLLER ----------------------------------------- + # START SPECIFIC TO IOR CONTROLLER --------------------------------------- def write_one(self, axis, value): self.ctrl.WriteOne(axis, value) - # END SPECIFIC TO IOR CONTROLLER ------------------------------------------- + # END SPECIFIC TO IOR CONTROLLER ----------------------------------------- class PoolPseudoMotorController(PoolController): diff --git a/src/sardana/pool/poolcontrollermanager.py b/src/sardana/pool/poolcontrollermanager.py index 3e0cafd47a..70888d97c7 100644 --- a/src/sardana/pool/poolcontrollermanager.py +++ b/src/sardana/pool/poolcontrollermanager.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -115,7 +115,7 @@ def cleanUp(self): if self._state == ManagerState.CLEANED: return - #if self._modules: + # if self._modules: # ModuleManager().unloadModules(self._modules.keys()) self._controller_path = None @@ -132,10 +132,10 @@ def get_pool(self): def setControllerPath(self, controller_path, reload=True): """Registers a new list of controller directories in this manager. - + :param seq controller_path: a sequence of absolute paths where this manager should look for controllers - + .. warning:: as a consequence all the controller modules will be reloaded. This means that if any reference to an old controller object was @@ -146,7 +146,7 @@ def setControllerPath(self, controller_path, reload=True): p.extend(item.split(":")) # filter empty and commented paths - p = [ i for i in p if i and not i.startswith("#") ] + p = [i for i in p if i and not i.startswith("#")] # add basic dummy controller directory(ies) pool_dir = os.path.dirname(os.path.abspath(__file__)) @@ -170,7 +170,7 @@ def setControllerPath(self, controller_path, reload=True): def getControllerPath(self): """Returns the current sequence of absolute paths used to look for controllers. - + :return: sequence of absolute paths :rtype: seq""" return self._controller_path @@ -210,14 +210,14 @@ def getOrCreateControllerLib(self, lib_name, controller_name=None): """Gets the exiting controller lib or creates a new controller lib file. If name is not None, a controller template code for the given controller name is appended to the end of the file. - + :param str lib_name: module name, python file name, or full file name (with path) :param str controller_name: an optional controller name. If given a controller template code is appended to the end of the file [default: None, meaning no controller code is added) - + :return: a sequence with three items: full_filename, code, line number line number is 0 if no controller is created or n representing the first line of code for the given controller name. @@ -236,13 +236,15 @@ def getOrCreateControllerLib(self, lib_name, controller_name=None): code = f.read() f.close() else: - # if given controller name + # if given controller name if controller_lib is None: - f_name, code, line_nb = self.createController(lib_name, controller_name) + f_name, code, line_nb = self.createController( + lib_name, controller_name) else: controller = controller_lib.get_controller(controller_name) if controller is None: - f_name, code, line_nb = self.createController(lib_name, controller_name) + f_name, code, line_nb = self.createController( + lib_name, controller_name) else: _, line_nb = controller.getCode() f_name = controller.getFileName() @@ -250,12 +252,12 @@ def getOrCreateControllerLib(self, lib_name, controller_name=None): code = f.read() f.close() - return [ f_name, code, line_nb ] + return [f_name, code, line_nb] def setControllerLib(self, lib_name, code): """Creates a new controller library file with the given name and code. The new module is imported and becomes imediately available. - + :param str lib_name: name of the new library :param str code: python code of the new library""" f_name = self._fromNameToFileName(lib_name) @@ -272,7 +274,8 @@ def createControllerLib(self, lib_name, path=None): f_name = self._fromNameToFileName(lib_name, path) if os.path.exists(f_name): - raise Exception("Unable to create controller lib: '%s' already exists" % f_name) + raise Exception( + "Unable to create controller lib: '%s' already exists" % f_name) f = open(f_name, 'w') f.close() @@ -292,7 +295,8 @@ def createController(self, lib_name, controller_name): template += '\n' t = open(f_name, 'rU') line_nb = -1 - for line_nb, _ in enumerate(t): pass + for line_nb, _ in enumerate(t): + pass line_nb += 3 t.close() @@ -306,7 +310,8 @@ def createController(self, lib_name, controller_name): template += f_templ.read() f_templ.close() except: - self.debug("Failed to open template controller file. Using simplified template") + self.debug( + "Failed to open template controller file. Using simplified template") template += CONTROLLER_TEMPLATE if f_templ: f_templ.close() @@ -323,11 +328,11 @@ def createController(self, lib_name, controller_name): def reloadController(self, controller_name, path=None): """Reloads the module corresponding to the given controller name - + :raises: :exc:`sardana.pool.poolexception.UnknownController` in case the controller is unknown or :exc:`ImportError` if the reload process is not successfull - + :param str controller_name: controller class name :param seq path: a list of absolute path to search for libraries [default: None, meaning the current ControllerPath @@ -336,28 +341,29 @@ def reloadController(self, controller_name, path=None): def reloadControllers(self, controller_names, path=None): """Reloads the modules corresponding to the given controller names - + :raises: :exc:`sardana.pool.poolexception.UnknownController` in case the controller is unknown or :exc:`ImportError` if the reload process is not successful - + :param seq controller_names: a list of controller class names :param seq path: a list of absolute path to search for libraries [default: None, meaning the current ControllerPath will be used]""" module_names = [] for controller_name in controller_names: - module_name = self.getControllerMetaClass(controller_name).get_module_name() + module_name = self.getControllerMetaClass( + controller_name).get_module_name() module_names.append(module_name) self.reloadControllerLibs(module_names, path=path) def reloadControllerLibs(self, module_names, path=None, reload=True): """Reloads the given library(=module) names - + :raises: :exc:`sardana.pool.poolexception.UnknownController` in case the controller is unknown or :exc:`ImportError` if the reload process is not successful - + :param seq module_names: a list of module names :param seq path: a list of absolute path to search for libraries [default: None, meaning the current ControllerPath @@ -366,7 +372,8 @@ def reloadControllerLibs(self, module_names, path=None, reload=True): for module_name in module_names: try: m = self.reloadControllerLib(module_name, path, reload=reload) - if m: ret.append(m) + if m: + ret.append(m) except: self.info("Failed to reload controller library %s", module_name) self.debug("Failed to reload controller library %s details", @@ -376,16 +383,16 @@ def reloadControllerLibs(self, module_names, path=None, reload=True): def reloadControllerLib(self, module_name, path=None, reload=True): """Reloads the given library(=module) names - + :raises: :exc:`sardana.pool.poolexception.UnknownController` in case the controller is unknown or :exc:`ImportError` if the reload process is not successful - + :param str module_name: controller library name (=python module name) :param seq path: a list of absolute path to search for libraries [default: None, meaning the current ControllerPath will be used] - + :return: the ControllerLib object for the reloaded controller lib :rtype: sardana.pool.poolmetacontroller.ControllerLibrary """ @@ -485,7 +492,8 @@ def getControllers(self, filter=None): return sorted(self._controller_dict.values()) expr = re.compile(filter, re.IGNORECASE) - ret = [ kls for n, kls in self._controller_dict.iteritems() if not expr.match(n) is None ] + ret = [kls for n, kls in self._controller_dict.iteritems() + if not expr.match(n) is None] ret.sort() return ret @@ -534,14 +542,15 @@ def decodeControllerParameters(self, in_par_list): if type(controller_class) in types.StringTypes: controller_class = self.getControllerClass(controller_class) if controller_class is None: - raise UnknownController("Unknown controller %s" % controller_name_or_klass) + raise UnknownController("Unknown controller %s" % + controller_name_or_klass) from sardana.macroserver.msparameter import ParamDecoder out_par_list = ParamDecoder(controller_class, in_par_list) return controller_class, in_par_list, out_par_list def strControllerParamValues(self, par_list): """Creates a short string representation of the parameter values list. - + :param par_list: list of strings representing the parameter values. :type par_list: list :return: a list containning an abreviated version of the par_list @@ -555,4 +564,3 @@ def strControllerParamValues(self, par_list): param_str = param_str[:9] + "..." ret.append(param_str) return ret - diff --git a/src/sardana/pool/poolcontrollers/DiscretePseudoMotorController.py b/src/sardana/pool/poolcontrollers/DiscretePseudoMotorController.py index 96885064bc..b9684e161e 100644 --- a/src/sardana/pool/poolcontrollers/DiscretePseudoMotorController.py +++ b/src/sardana/pool/poolcontrollers/DiscretePseudoMotorController.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -43,29 +43,28 @@ class DiscretePseudoMotorController(PseudoMotorController): """A discrete pseudo motor controller which converts physical motor positions to discrete values""" - + gender = "DiscretePseudoMotorController" - model = "PseudoMotor" + model = "PseudoMotor" organization = "Sardana team" image = "" pseudo_motor_roles = ("OutputMotor",) motor_roles = ("InputMotor",) - axis_attributes = {CALIBRATION:#type hackish until arrays supported - {Type : str, - Description : 'Flatten list of a list of triples and [min,cal,max]', - Access : DataAccess.ReadWrite, - 'fget' : 'get%s' % CALIBRATION, - 'fset' : 'set%s' % CALIBRATION}, - LABELS:#type hackish until arrays supported - {Type : str, - Description : 'String list with the meaning of each discrete position', - Access : DataAccess.ReadWrite, - 'fget' : 'get%s' % LABELS, - 'fset' : 'set%s' % LABELS} - } - + axis_attributes = {CALIBRATION: # type hackish until arrays supported + {Type: str, + Description: 'Flatten list of a list of triples and [min,cal,max]', + Access: DataAccess.ReadWrite, + 'fget': 'get%s' % CALIBRATION, + 'fset': 'set%s' % CALIBRATION}, + LABELS: # type hackish until arrays supported + {Type: str, + Description: 'String list with the meaning of each discrete position', + Access: DataAccess.ReadWrite, + 'fget': 'get%s' % LABELS, + 'fset': 'set%s' % LABELS} + } def __init__(self, inst, props, *args, **kwargs): PseudoMotorController.__init__(self, inst, props, *args, **kwargs) @@ -73,14 +72,12 @@ def __init__(self, inst, props, *args, **kwargs): self._positions = None self._labels = None - def GetAxisAttributes(self, axis): axis_attrs = PseudoMotorController.GetAxisAttributes(self, axis) axis_attrs = dict(axis_attrs) axis_attrs['Position']['type'] = float return axis_attrs - def CalcPseudo(self, axis, physical_pos, curr_pseudo_pos): llabels = len(self._labels) positions = self._positions @@ -88,72 +85,78 @@ def CalcPseudo(self, axis, physical_pos, curr_pseudo_pos): lcalibration = len(calibration) value = physical_pos[0] - #case 0: nothing to translate, only round about integer the attribute value + # case 0: nothing to translate, only round about integer the attribute + # value if llabels == 0: return int(value) - #case 1: only uses the labels. Available positions in POSITIONS + # case 1: only uses the labels. Available positions in POSITIONS elif lcalibration == 0: value = int(value) - try: positions.index(value) - except: raise Exception("Invalid position.") - else: return value - #case 1+fussy: the physical position must be in one of the defined - #ranges, and the DiscretePseudoMotor position is defined in labels + try: + positions.index(value) + except: + raise Exception("Invalid position.") + else: + return value + # case 1+fussy: the physical position must be in one of the defined + # ranges, and the DiscretePseudoMotor position is defined in labels elif llabels == lcalibration: for fussyPos in calibration: if value >= fussyPos[0] and value <= fussyPos[2]: return positions[calibration.index(fussyPos)] - #if the loop ends, current value is not in the fussy areas. + # if the loop ends, current value is not in the fussy areas. raise Exception("Invalid position.") else: raise Exception("Bad configuration on axis attributes.") - def CalcPhysical(self, axis, pseudo_pos, curr_physical_pos): - #If Labels is well defined, the write value must be one this struct + # If Labels is well defined, the write value must be one this struct llabels = len(self._labels) positions = self._positions calibration = self._calibration lcalibration = len(calibration) value = pseudo_pos[0] - #case 0: nothing to translate, what is written goes to the attribute + # case 0: nothing to translate, what is written goes to the attribute if llabels == 0: return value - #case 1: only uses the labels. Available positions in POSITIONS + # case 1: only uses the labels. Available positions in POSITIONS elif lcalibration == 0: self._log.debug("Value = %s", value) - try: positions.index(value) - except: raise Exception("Invalid position.") + try: + positions.index(value) + except: + raise Exception("Invalid position.") return value - #case 1+fussy: the write to the to the DiscretePseudoMotorController - #is translated to the central position of the calibration. + # case 1+fussy: the write to the to the DiscretePseudoMotorController + # is translated to the central position of the calibration. elif llabels == lcalibration: self._log.debug("Value = %s", value) - try: destination = positions.index(value) - except: raise Exception("Invalid position.") + try: + destination = positions.index(value) + except: + raise Exception("Invalid position.") self._log.debug("destination = %s", destination) - calibrated_position = calibration[destination][1]#central element + calibrated_position = calibration[ + destination][1] # central element self._log.debug("calibrated_position = %s", calibrated_position) return calibrated_position - - def getLabels(self,axis): - #hackish until we support DevVarDoubleArray in extra attrs + def getLabels(self, axis): + # hackish until we support DevVarDoubleArray in extra attrs labels = self._labels positions = self._positions labels_str = "" for i in range(len(labels)): - labels_str += "%s:%d "%(labels[i],positions[i]) - return labels_str[:-1]#remove the final space + labels_str += "%s:%d " % (labels[i], positions[i]) + return labels_str[:-1] # remove the final space - - def setLabels(self,axis,value): - #hackish until we support DevVarStringArray in extra attrs + def setLabels(self, axis, value): + # hackish until we support DevVarStringArray in extra attrs labels = [] positions = [] for pair in value.split(): - l,p = pair.split(':') + l, p = pair.split(':') labels.append(l) positions.append(int(p)) if len(labels) == len(positions): @@ -162,12 +165,10 @@ def setLabels(self,axis,value): else: raise Exception("Rejecting labels: invalid structure") - - def getCalibration(self,axis): + def getCalibration(self, axis): return json.dumps(self._calibration) - - def setCalibration(self,axis,value): + def setCalibration(self, axis, value): try: self._calibration = json.loads(value) except: diff --git a/src/sardana/pool/poolcontrollers/DummyCounterTimerController.py b/src/sardana/pool/poolcontrollers/DummyCounterTimerController.py index e90487b0d8..77780b519f 100644 --- a/src/sardana/pool/poolcontrollers/DummyCounterTimerController.py +++ b/src/sardana/pool/poolcontrollers/DummyCounterTimerController.py @@ -1,37 +1,38 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## -import time, copy +import time +import copy from sardana.sardanavalue import SardanaValue from sardana import State, DataAccess from sardana.pool import AcqSynch from sardana.pool.controller import CounterTimerController, Type, Access,\ - Description, Memorize, NotMemorized + Description, Memorize, NotMemorized class Channel: - - def __init__(self,idx): + + def __init__(self, idx): self.idx = idx # 1 based index self.value = 0.0 self.is_counting = False @@ -46,11 +47,11 @@ class DummyCounterTimerController(CounterTimerController): "This class is the Tango Sardana CounterTimer controller for tests" gender = "Simulation" - model = "Basic" + model = "Basic" organization = "Sardana team" MaxDevice = 1024 - + StoppedMode = 0 TimerMode = 1 MonitorMode = 2 @@ -60,30 +61,30 @@ def __init__(self, inst, props, *args, **kwargs): CounterTimerController.__init__(self, inst, props, *args, **kwargs) self._synchronization = AcqSynch.SoftwareTrigger self._latency_time = 0 - self.channels = self.MaxDevice*[None,] + self.channels = self.MaxDevice * [None, ] self.reset() - + def reset(self): self.start_time = None self.integ_time = None self.monitor_count = None self.read_channels = {} self.counting_channels = {} - - def AddDevice(self,ind): + + def AddDevice(self, ind): idx = ind - 1 self.channels[idx] = Channel(ind) - - def DeleteDevice(self,ind): + + def DeleteDevice(self, ind): idx = ind - 1 self.channels[idx] = None def PreStateAll(self): pass - + def PreStateOne(self, ind): pass - + def StateAll(self): pass @@ -103,9 +104,9 @@ def StateOne(self, ind): ret = (sta, status) self._log.debug('StateOne(%d): returning %s' % (ind, repr(ret))) return sta, status - - def _updateChannelState(self, ind, elapsed_time): - channel = self.channels[ind-1] + + def _updateChannelState(self, ind, elapsed_time): + channel = self.channels[ind - 1] if channel.mode == AcqSynch.SoftwareTrigger: if self.integ_time is not None: # counting in time @@ -113,20 +114,20 @@ def _updateChannelState(self, ind, elapsed_time): self._finish(elapsed_time) elif self.monitor_count is not None: # monitor counts - v = int(elapsed_time*100*ind) + v = int(elapsed_time * 100 * ind) if v >= self.monitor_count: self._finish(elapsed_time) elif channel.mode in (AcqSynch.HardwareTrigger, AcqSynch.HardwareGate): if self.integ_time is not None: - # counting in time - #if elapsed_time >= self.integ_time*channel.repetitions: + # counting in time + # if elapsed_time >= self.integ_time*channel.repetitions: if elapsed_time > channel.repetitions * (self.integ_time + self._latency_time): - #if elapsed_time >= self.integ_time: + # if elapsed_time >= self.integ_time: self._finish(elapsed_time) - + def _updateChannelValue(self, ind, elapsed_time): - channel = self.channels[ind-1] + channel = self.channels[ind - 1] if channel.mode == AcqSynch.SoftwareTrigger: if self.integ_time is not None: @@ -138,7 +139,7 @@ def _updateChannelValue(self, ind, elapsed_time): else: channel.value = t * channel.idx elif self.monitor_count is not None: - channel.value = int(elapsed_time*100*ind) + channel.value = int(elapsed_time * 100 * ind) if ind == self._monitor: if not channel.is_counting: channel.value = self.monitor_count @@ -149,14 +150,14 @@ def _updateChannelValue(self, ind, elapsed_time): cp = 0 if n > channel.repetitions: cp = n - channel.repetitions - n = n - channel._counter -cp - t = self.integ_time + n = n - channel._counter - cp + t = self.integ_time if ind == self._timer: - channel.buffer_values = [t]*n + channel.buffer_values = [t] * n else: - channel.buffer_values = [t * channel.idx]*n - - def _finish(self, elapsed_time, ind=None): + channel.buffer_values = [t * channel.idx] * n + + def _finish(self, elapsed_time, ind=None): if ind is None: for ind, channel in self.counting_channels.items(): channel.is_counting = False @@ -167,15 +168,15 @@ def _finish(self, elapsed_time, ind=None): channel.is_counting = False self._updateChannelValue(ind, elapsed_time) else: - channel = self.channels[ind-1] + channel = self.channels[ind - 1] channel.is_counting = False self.counting_channels = {} - + def PreReadAll(self): self.read_channels = {} - - def PreReadOne(self,ind): - channel = self.channels[ind-1] + + def PreReadOne(self, ind): + channel = self.channels[ind - 1] self.read_channels[ind] = channel def ReadAll(self): @@ -187,7 +188,7 @@ def ReadAll(self): self._updateChannelState(ind, elapsed_time) if channel.is_counting: self._updateChannelValue(ind, elapsed_time) - + def ReadOne(self, ind): self._log.debug('ReadOne(%d): entering...' % ind) channel = self.read_channels[ind] @@ -204,10 +205,10 @@ def ReadOne(self, ind): ret = SardanaValue(v) self._log.debug('ReadOne(%d): returning %s' % (ind, repr(ret))) return ret - + def PreStartAll(self): self.counting_channels = {} - + def PreStartOne(self, ind, value=None): self._log.debug('PreStartOne(%d): entering...' % ind) idx = ind - 1 @@ -217,14 +218,14 @@ def PreStartOne(self, ind, value=None): channel.buffer_values = [] self.counting_channels[ind] = channel return True - + def StartOne(self, ind, value=None): self._log.debug('StartOne(%d): entering...' % ind) self.counting_channels[ind].is_counting = True - + def StartAll(self): self.start_time = time.time() - + def LoadOne(self, ind, value, repetitions): if value > 0: self.integ_time = value @@ -236,7 +237,7 @@ def LoadOne(self, ind, value, repetitions): for channel in self.channels: if channel: channel.repetitions = repetitions - + def AbortOne(self, ind): now = time.time() if ind in self.counting_channels: diff --git a/src/sardana/pool/poolcontrollers/DummyIORController.py b/src/sardana/pool/poolcontrollers/DummyIORController.py index bd0317eaf7..88075a6e50 100644 --- a/src/sardana/pool/poolcontrollers/DummyIORController.py +++ b/src/sardana/pool/poolcontrollers/DummyIORController.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -30,13 +30,13 @@ class DummyIORController(IORegisterController): 1024).""" gender = "Simulation" - model = "Basic" + model = "Basic" organization = "Sardana team" MaxDevice = 1024 - - predefined_values = "0", "Online", "1" , "Offline", "2", "Standby" - + + predefined_values = "0", "Online", "1", "Offline", "2", "Standby" + def __init__(self, inst, props, *args, **kwargs): IORegisterController.__init__(self, inst, props, *args, **kwargs) self.myvalue = 1 @@ -48,13 +48,13 @@ def DeleteDevice(self, axis): pass def StateOne(self, axis): - return (State.On,"Device in On state") + return (State.On, "Device in On state") def ReadOne(self, axis): return self.myvalue def WriteOne(self, axis, value): self.myvalue = value - - def SendToCtrl(self,in_data): + + def SendToCtrl(self, in_data): return "" diff --git a/src/sardana/pool/poolcontrollers/DummyMotorController.py b/src/sardana/pool/poolcontrollers/DummyMotorController.py index 4a341d104c..2910c00752 100644 --- a/src/sardana/pool/poolcontrollers/DummyMotorController.py +++ b/src/sardana/pool/poolcontrollers/DummyMotorController.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -60,7 +60,7 @@ def __init__(self): self.small_motion = False # position where maximum velocity will be reached - self.curr_max_vel_pos = -1 + self.curr_max_vel_pos = -1 # necessary displacement to reach maximum velocity self.curr_dsplmnt_reach_max_vel = -1 @@ -108,7 +108,7 @@ def __init__(self): self.__recalculate_acc_constants() - def setMinVelocity(self,vi): + def setMinVelocity(self, vi): """ Sets the minimum velocity in ms^-1. A.k.a. base rate""" vi = float(vi) if vi < 0: @@ -128,7 +128,7 @@ def setMinVelocity(self,vi): def getMinVelocity(self): return self.min_vel - def setMaxVelocity(self,vf): + def setMaxVelocity(self, vf): """ Sets the maximum velocity in ms^-1.""" vf = float(vf) if vf <= 0: @@ -148,7 +148,7 @@ def setMaxVelocity(self,vf): def getMaxVelocity(self): return self.max_vel - def setAccelerationTime(self,at): + def setAccelerationTime(self, at): """Sets the time to go from minimum velocity to maximum velocity in seconds""" at = float(at) if at <= 0: @@ -162,7 +162,7 @@ def setAccelerationTime(self,at): def getAccelerationTime(self): return self.accel_time - def setDecelerationTime(self,dt): + def setDecelerationTime(self, dt): """Sets the time to go from maximum velocity to minimum velocity in seconds""" dt = float(dt) if dt <= 0: @@ -176,7 +176,7 @@ def setDecelerationTime(self,dt): def getDecelerationTime(self): return self.decel_time - def setAcceleration(self,a): + def setAcceleration(self, a): """Sets the acceleration in ms^-2""" a = float(a) if a < 0: @@ -191,7 +191,7 @@ def setAcceleration(self,a): self.__recalculate_acc_constants() - def setDeceleration(self,d): + def setDeceleration(self, d): """Sets the deceleration in ms^-2""" d = float(d) if d > 0: @@ -215,10 +215,10 @@ def setStepPerUnit(self, spu): def __recalculate_acc_constants(self): """pre-computations assuming maximum speed can be reached in a motion""" - self.dsplmnt_reach_max_vel = 0.5 * self.accel * pow(self.accel_time,2) + self.dsplmnt_reach_max_vel = 0.5 * self.accel * pow(self.accel_time, 2) self.dsplmnt_reach_max_vel += self.min_vel * self.accel_time - self.dsplmnt_reach_min_vel = 0.5 * self.decel * pow(self.decel_time,2) + self.dsplmnt_reach_min_vel = 0.5 * self.decel * pow(self.decel_time, 2) self.dsplmnt_reach_min_vel += self.max_vel * self.decel_time def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): @@ -257,7 +257,6 @@ def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): self.curr_accel = -self.accel self.curr_decel = -self.decel - if not self.small_motion: # necessary displacement to reach maximum velocity @@ -277,21 +276,26 @@ def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): self.curr_max_vel_pos = self.init_pos - self.curr_dsplmnt_reach_max_vel # displacement at maximum velocity - self.curr_at_max_vel_dsplmnt = self.dsplmnt - (self.curr_dsplmnt_reach_max_vel + self.curr_dsplmnt_reach_min_vel) + self.curr_at_max_vel_dsplmnt = self.dsplmnt - \ + (self.curr_dsplmnt_reach_max_vel + self.curr_dsplmnt_reach_min_vel) else: # Small movement # position where maximum velocity will be reached - self.curr_max_vel_pos = self.init_pos * self.curr_accel - self.final_pos * self.curr_decel + self.curr_max_vel_pos = self.init_pos * \ + self.curr_accel - self.final_pos * self.curr_decel self.curr_max_vel_pos /= self.curr_accel - self.curr_decel # necessary displacement to reach maximum velocity - self.curr_dsplmnt_reach_max_vel = abs(self.curr_max_vel_pos - self.init_pos) + self.curr_dsplmnt_reach_max_vel = abs( + self.curr_max_vel_pos - self.init_pos) # necessary diplacement to reach minimum velocity - self.curr_dsplmnt_reach_min_vel = abs(self.final_pos - self.curr_max_vel_pos) + self.curr_dsplmnt_reach_min_vel = abs( + self.final_pos - self.curr_max_vel_pos) # maximum velocity possible - cnst = 2 * self.curr_accel * self.curr_decel * self.dsplmnt / (self.curr_decel - self.curr_accel) + cnst = 2 * self.curr_accel * self.curr_decel * \ + self.dsplmnt / (self.curr_decel - self.curr_accel) max_vel_2 = pow(self.min_vel, 2) + cnst self.curr_max_vel = sqrt(abs(max_vel_2)) @@ -306,13 +310,16 @@ def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): self.curr_at_max_vel_dsplmnt = 0.0 # time to reach maximum velocity - self.curr_max_vel_time = abs((self.curr_max_vel - self.curr_min_vel) / self.curr_accel) + self.curr_max_vel_time = abs( + (self.curr_max_vel - self.curr_min_vel) / self.curr_accel) # time to reach minimum velocity - self.curr_min_vel_time = abs((self.curr_min_vel - self.curr_max_vel) / self.curr_decel) + self.curr_min_vel_time = abs( + (self.curr_min_vel - self.curr_max_vel) / self.curr_decel) # time at maximum velocity - self.curr_at_max_vel_time = abs(self.curr_at_max_vel_dsplmnt / self.curr_max_vel) + self.curr_at_max_vel_time = abs( + self.curr_at_max_vel_dsplmnt / self.curr_max_vel) # instant when maximum velocity should be reached self.curr_max_vel_instant = self.start_instant + self.curr_max_vel_time @@ -321,7 +328,8 @@ def startMotion(self, initial_user_pos, final_user_pos, start_instant=None): self.curr_min_vel_instant = self.curr_max_vel_instant + self.curr_at_max_vel_time # time the motion will take - self.duration = self.curr_max_vel_time + self.curr_at_max_vel_time + self.curr_min_vel_time + self.duration = self.curr_max_vel_time + \ + self.curr_at_max_vel_time + self.curr_min_vel_time # instant the motion will end self.final_instant = self.start_instant + self.duration @@ -368,9 +376,10 @@ def abortMotion(self, curr_instant=None): self.inMotion = False return self.curr_pos - def isInMotion(self,curr_instant=None): + def isInMotion(self, curr_instant=None): curr_instant = curr_instant or time.time() - #we call getCurrentPosition because inside it updates the inMotion flag + # we call getCurrentPosition because inside it updates the inMotion + # flag self.getCurrentPosition(curr_instant) return self.inMotion @@ -388,7 +397,7 @@ def getCurrentPosition(self, curr_instant=None): self.inMotion = False pos = self.final_pos else: - pos = self.init_pos + pos = self.init_pos if curr_instant > self.curr_min_vel_instant: if self.positive_dsplmnt: pos += self.curr_dsplmnt_reach_max_vel @@ -397,7 +406,8 @@ def getCurrentPosition(self, curr_instant=None): pos -= self.curr_dsplmnt_reach_max_vel pos -= self.curr_at_max_vel_dsplmnt dt = curr_instant - self.curr_min_vel_instant - pos += self.curr_max_vel * dt + 0.5 * self.curr_decel * pow(dt,2) + pos += self.curr_max_vel * dt + \ + 0.5 * self.curr_decel * pow(dt, 2) elif curr_instant > self.curr_max_vel_instant: if self.positive_dsplmnt: pos += self.curr_dsplmnt_reach_max_vel @@ -406,8 +416,9 @@ def getCurrentPosition(self, curr_instant=None): dt = curr_instant - self.curr_max_vel_instant pos += self.curr_max_vel * dt else: - dt = curr_instant - self.start_instant - pos += self.curr_min_vel * dt + 0.5 * self.curr_accel * pow(dt,2) + dt = curr_instant - self.start_instant + pos += self.curr_min_vel * dt + \ + 0.5 * self.curr_accel * pow(dt, 2) else: pos = self.curr_pos if pos <= self.lower_ls: @@ -420,7 +431,7 @@ def getCurrentPosition(self, curr_instant=None): return pos def setCurrentUserPosition(self, user_pos): - self.setCurrentPosition(user_pos*self.step_per_unit) + self.setCurrentPosition(user_pos * self.step_per_unit) def getCurrentUserPosition(self, curr_instant=None): return self.getCurrentPosition(curr_instant=curr_instant) / self.step_per_unit @@ -461,37 +472,37 @@ def setPower(self, power): self.power = power def info(self): - print "Small movement =",self.small_motion - print "length =",self.dsplmnt - print "position where maximum velocity will be reached =",self.curr_max_vel_pos - print "necessary displacement to reach maximum velocity =",self.curr_dsplmnt_reach_max_vel - print "necessary displacement to stop from maximum velocity =",self.curr_dsplmnt_reach_min_vel - print "maximum velocity possible =",self.curr_max_vel - print "time at top velocity =",self.curr_at_max_vel_time - print "displacement at top velocity =",self.curr_at_max_vel_dsplmnt - print "time to reach maximum velocity =",self.curr_max_vel_time - print "time to reach minimum velocity =",self.curr_min_vel_time - print "time the motion will take =",self.duration - print "instant when maximum velocity should be reached =",self.curr_max_vel_instant - print "instant when should start decelerating =",self.curr_min_vel_instant - print "instant the motion will end",self.final_instant + print "Small movement =", self.small_motion + print "length =", self.dsplmnt + print "position where maximum velocity will be reached =", self.curr_max_vel_pos + print "necessary displacement to reach maximum velocity =", self.curr_dsplmnt_reach_max_vel + print "necessary displacement to stop from maximum velocity =", self.curr_dsplmnt_reach_min_vel + print "maximum velocity possible =", self.curr_max_vel + print "time at top velocity =", self.curr_at_max_vel_time + print "displacement at top velocity =", self.curr_at_max_vel_dsplmnt + print "time to reach maximum velocity =", self.curr_max_vel_time + print "time to reach minimum velocity =", self.curr_min_vel_time + print "time the motion will take =", self.duration + print "instant when maximum velocity should be reached =", self.curr_max_vel_instant + print "instant when should start decelerating =", self.curr_min_vel_instant + print "instant the motion will end", self.final_instant print "" - print "For long movements (where top vel is possible), necessary displacement to reach maximum velocity =",self.dsplmnt_reach_max_vel - print "For long movements (where top vel is possible), necessary displacement to stop from maximum velocity =",self.dsplmnt_reach_min_vel + print "For long movements (where top vel is possible), necessary displacement to reach maximum velocity =", self.dsplmnt_reach_max_vel + print "For long movements (where top vel is possible), necessary displacement to stop from maximum velocity =", self.dsplmnt_reach_min_vel class BasicDummyMotorController(MotorController): """This class represents a basic, dummy Sardana motor controller.""" gender = "Simulation" - model = "Basic" + model = "Basic" organization = "Sardana team" MaxDevice = 1024 def __init__(self, inst, props, *args, **kwargs): MotorController.__init__(self, inst, props, *args, **kwargs) - self.m = self.MaxDevice*[None,] + self.m = self.MaxDevice * [None, ] def GetAxisAttributes(self, axis): axis_attrs = MotorController.GetAxisAttributes(self, axis) @@ -500,7 +511,7 @@ def GetAxisAttributes(self, axis): new_axis_attrs[attr] = axis_attrs[attr] return new_axis_attrs - def AddDevice(self,axis): + def AddDevice(self, axis): MotorController.AddDevice(self, axis) idx = axis - 1 if len(self.m) < axis: @@ -552,9 +563,9 @@ def ReadOne(self, axis): #raise Exception("Cannot ReadOne") idx = axis - 1 m = self.m[idx] - ts = time.time() #simulate as if we got it from hardware + ts = time.time() # simulate as if we got it from hardware return SardanaValue(m.getCurrentUserPosition(), timestamp=ts) - #return m.getCurrentUserPosition() + # return m.getCurrentUserPosition() def PreStartAll(self): #raise Exception("Cannot move on PreStartAll") @@ -585,17 +596,18 @@ def AbortOne(self, axis): def SendToCtrl(self, stream): return stream + class FastDummyMotorController(MotorController): gender = "Simulation" - model = "Basic" + model = "Basic" organization = "Sardana team" MaxDevice = 1024 def __init__(self, inst, props, *args, **kwargs): MotorController.__init__(self, inst, props, *args, **kwargs) - self.m = self.MaxDevice*[None,] + self.m = self.MaxDevice * [None, ] def GetAxisAttributes(self, axis): axis_attrs = MotorController.GetAxisAttributes(self, axis) @@ -604,7 +616,7 @@ def GetAxisAttributes(self, axis): new_axis_attrs[attr] = axis_attrs[attr] return new_axis_attrs - def AddDevice(self,axis): + def AddDevice(self, axis): MotorController.AddDevice(self, axis) idx = axis - 1 if len(self.m) < axis: @@ -678,7 +690,7 @@ def ReadOne(self, axis): pos = BasicDummyMotorController.ReadOne(self, axis) return int(pos) - + class DummyMotorController(BasicDummyMotorController): """This class represents a dummy Sardana motor controller.""" @@ -687,41 +699,41 @@ class DummyMotorController(BasicDummyMotorController): model = "Best" ctrl_attributes = { - 'LowerLimitSwitch' : { Type : float, - Description : 'lower limit switch position', - FGet : 'getLowerLimitSwitch', - FSet : 'setLowerLimitSwitch', - DefaultValue: -9999.9999, }, - 'UpperLimitSwitch' : { Type : float, - Description : 'upper limit switch position', - DefaultValue: 8888.8888 } + 'LowerLimitSwitch': {Type: float, + Description: 'lower limit switch position', + FGet: 'getLowerLimitSwitch', + FSet: 'setLowerLimitSwitch', + DefaultValue: -9999.9999, }, + 'UpperLimitSwitch': {Type: float, + Description: 'upper limit switch position', + DefaultValue: 8888.8888} } axis_attributes = { - 'LowerLimitSwitch' : { Type : float, - Description : 'lower limit switch position', - FGet : 'getLLS', - FSet : 'setLLS', - DefaultValue: -9999.9999 }, - 'UpperLimitSwitch' : { Type : float, - Description : 'upper limit switch position', - FGet : 'getULS', - FSet : 'setULS', - DefaultValue: 8888.8888 }, - 'Power' : { Type : bool, - Description : 'motor power', - FGet : 'getPower', - FSet : 'setPower', - DefaultValue: True }, + 'LowerLimitSwitch': {Type: float, + Description: 'lower limit switch position', + FGet: 'getLLS', + FSet: 'setLLS', + DefaultValue: -9999.9999}, + 'UpperLimitSwitch': {Type: float, + Description: 'upper limit switch position', + FGet: 'getULS', + FSet: 'setULS', + DefaultValue: 8888.8888}, + 'Power': {Type: bool, + Description: 'motor power', + FGet: 'getPower', + FSet: 'setPower', + DefaultValue: True}, } ctrl_properties = { - 'Prop1' : { Type : str, - Description : 'demo property 1', - DefaultValue : 'test property 1'}, - 'Prop2' : { Type : int, - Description : 'demo property 1', - DefaultValue : 531}, + 'Prop1': {Type: str, + Description: 'demo property 1', + DefaultValue: 'test property 1'}, + 'Prop2': {Type: int, + Description: 'demo property 1', + DefaultValue: 531}, } def __init__(self, inst, props, *args, **kwargs): diff --git a/src/sardana/pool/poolcontrollers/DummyOneDController.py b/src/sardana/pool/poolcontrollers/DummyOneDController.py index 06806bafec..f9100aedad 100644 --- a/src/sardana/pool/poolcontrollers/DummyOneDController.py +++ b/src/sardana/pool/poolcontrollers/DummyOneDController.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/axisex.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/axisex.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -28,12 +28,14 @@ from sardana.pool.controller import OneDController, MaxDimSize from sardana.pool.controller import DefaultValue, Description, FGet, FSet, Type + def gauss(x, mean, ymax, fwhm, yoffset=0): - return yoffset + ymax*numpy.power(2,-4*((x-mean)/fwhm)**2) + return yoffset + ymax * numpy.power(2, -4 * ((x - mean) / fwhm)**2) + class Channel: - - def __init__(self,idx): + + def __init__(self, idx): self.idx = idx # 1 based axisex self.value = [] self.is_counting = False @@ -42,14 +44,14 @@ def __init__(self,idx): class BaseValue(object): - + def __init__(self, value): self.raw_value = value self.init() - + def init(self): self.value = float(self.raw_value) - + def get(self): return self.value @@ -58,7 +60,7 @@ def get_value_name(self): class TangoValue(BaseValue): - + def init(self): import PyTango self.attr_proxy = PyTango.AttributeProxy(self.raw_value) @@ -71,25 +73,25 @@ class DummyOneDController(OneDController): "This class is the Tango Sardana OneDController controller for tests" gender = "Simulation" - model = "Basic" + model = "Basic" organization = "Sardana team" MaxDevice = 1024 - + BufferSize = 1024, axis_attributes = { - 'Amplitude' : { - Type : str, - FGet : 'getAmplitude', - FSet : 'setAmplitude', - Description : 'Amplitude. Maybe a number or a tango attribute(must start with tango://)', - DefaultValue : '1.0' }, + 'Amplitude': { + Type: str, + FGet: 'getAmplitude', + FSet: 'setAmplitude', + Description: 'Amplitude. Maybe a number or a tango attribute(must start with tango://)', + DefaultValue: '1.0'}, } - + def __init__(self, inst, props, *args, **kwargs): OneDController.__init__(self, inst, props, *args, **kwargs) - self.channels = self.MaxDevice*[None,] + self.channels = self.MaxDevice * [None, ] self.reset() def GetAxisAttributes(self, axis): @@ -98,32 +100,32 @@ def GetAxisAttributes(self, axis): attrs = super(DummyOneDController, self).GetAxisAttributes(axis) attrs['Value'][MaxDimSize] = self.BufferSize return attrs - + def reset(self): self.start_time = None self.integ_time = None self.monitor_count = None self.read_channels = {} self.counting_channels = {} - - def AddDevice(self,axis): + + def AddDevice(self, axis): idx = axis - 1 self.channels[idx] = channel = Channel(axis) channel.value = numpy.zeros(self.BufferSize, dtype=numpy.float64) - - def DeleteDevice(self,axis): + + def DeleteDevice(self, axis): idx = axis - 1 self.channels[idx] = None def PreStateAll(self): pass - + def PreStateOne(self, axis): pass - + def StateAll(self): pass - + def StateOne(self, axis): idx = axis - 1 sta = State.On @@ -137,28 +139,28 @@ def StateOne(self, axis): sta = State.Moving status = "Acquiring" return sta, status - + def _updateChannelState(self, axis, elapsed_time): - channel = self.channels[axis-1] + channel = self.channels[axis - 1] if self.integ_time is not None: # counting in time if elapsed_time >= self.integ_time: self._finish(elapsed_time) elif self.monitor_count is not None: # monitor counts - v = int(elapsed_time*100*axis) + v = int(elapsed_time * 100 * axis) if v >= self.monitor_count: self._finish(elapsed_time) - + def _updateChannelValue(self, axis, elapsed_time): - channel = self.channels[axis-1] + channel = self.channels[axis - 1] t = elapsed_time if self.integ_time is not None and not channel.is_counting: t = self.integ_time x = numpy.linspace(-10, 10, self.BufferSize[0]) amplitude = axis * t * channel.amplitude.get() channel.value = gauss(x, 0, amplitude, 4) - + def _finish(self, elapsed_time, axis=None): if axis is None: for axis, channel in self.counting_channels.items(): @@ -170,15 +172,15 @@ def _finish(self, elapsed_time, axis=None): channel.is_counting = False self._updateChannelValue(axis, elapsed_time) else: - channel = self.channels[axis-1] + channel = self.channels[axis - 1] channel.is_counting = False self.counting_channels = {} - + def PreReadAll(self): self.read_channels = {} - - def PreReadOne(self,axis): - channel = self.channels[axis-1] + + def PreReadOne(self, axis): + channel = self.channels[axis - 1] self.read_channels[axis] = channel def ReadAll(self): @@ -190,28 +192,28 @@ def ReadAll(self): self._updateChannelState(axis, elapsed_time) if channel.is_counting: self._updateChannelValue(axis, elapsed_time) - + def ReadOne(self, axis): self._log.debug("ReadOne(%s)", axis) v = self.read_channels[axis].value return v - + def PreStartAll(self): self.counting_channels = {} - + def PreStartOne(self, axis, value): idx = axis - 1 channel = self.channels[idx] channel.value = 0.0 self.counting_channels[axis] = channel return True - + def StartOne(self, axis, value): self.counting_channels[axis].is_counting = True - + def StartAll(self): self.start_time = time.time() - + def LoadOne(self, axis, value): idx = axis - 1 if value > 0: @@ -220,24 +222,23 @@ def LoadOne(self, axis, value): else: self.integ_time = None self.monitor_count = -value - + def AbortOne(self, axis): now = time.time() if axis in self.counting_channels: elapsed_time = now - self.start_time self._finish(elapsed_time, axis=axis) - + def getAmplitude(self, axis): idx = axis - 1 channel = self.channels[idx] return channel.amplitude.get_value_name() - + def setAmplitude(self, axis, value): idx = axis - 1 channel = self.channels[idx] - + klass = BaseValue if value.startswith("tango://"): klass = TangoValue - channel.amplitude = klass(value) - + channel.amplitude = klass(value) diff --git a/src/sardana/pool/poolcontrollers/DummyTriggerGateController.py b/src/sardana/pool/poolcontrollers/DummyTriggerGateController.py index c44a511e70..caf7841eca 100644 --- a/src/sardana/pool/poolcontrollers/DummyTriggerGateController.py +++ b/src/sardana/pool/poolcontrollers/DummyTriggerGateController.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -27,6 +27,7 @@ from sardana.sardanathreadpool import get_thread_pool from sardana.pool.pooldefs import SynchDomain + class DummyTriggerGateController(TriggerGateController): """Basic controller intended for demonstration purposes only. """ @@ -65,7 +66,7 @@ def StateOne(self, axis): if tg.is_running() or tg.is_started(): sta = State.Moving status = "Moving" - self._log.debug('StateOne(%d): returning (%s, %s)' % \ + self._log.debug('StateOne(%d): returning (%s, %s)' % (axis, sta, status)) except Exception, e: print e diff --git a/src/sardana/pool/poolcontrollers/DummyTwoDController.py b/src/sardana/pool/poolcontrollers/DummyTwoDController.py index 492e45c346..cae3e32018 100644 --- a/src/sardana/pool/poolcontrollers/DummyTwoDController.py +++ b/src/sardana/pool/poolcontrollers/DummyTwoDController.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/axisex.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/axisex.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -27,12 +27,14 @@ from sardana import State from sardana.pool.controller import TwoDController, MaxDimSize + def gauss(x, mean, ymax, fwhm, yoffset=0): - return yoffset + ymax*numpy.power(2,-4*((x-mean)/fwhm)**2) + return yoffset + ymax * numpy.power(2, -4 * ((x - mean) / fwhm)**2) + class Channel: - - def __init__(self,idx): + + def __init__(self, idx): self.idx = idx # 1 based axisex self.value = [] self.is_counting = False @@ -41,14 +43,14 @@ def __init__(self,idx): class BaseValue(object): - + def __init__(self, value): self.raw_value = value self.init() - + def init(self): self.value = float(self.raw_value) - + def get(self): return self.value @@ -57,7 +59,7 @@ def get_value_name(self): class TangoValue(BaseValue): - + def init(self): import PyTango self.attr_proxy = PyTango.AttributeProxy(self.raw_value) @@ -70,25 +72,25 @@ class DummyTwoDController(TwoDController): "This class is the Tango Sardana OneDController controller for tests" gender = "Simulation" - model = "Basic" + model = "Basic" organization = "Sardana team" MaxDevice = 1024 - + BufferSize = 1024, 1024 axis_attributes = { - 'Amplitude' : { - 'type' : str, - 'fget' : 'getAmplitude', - 'fset' : 'setAmplitude', - 'description' : 'Amplitude. Maybe a number or a tango attribute(must start with tango://)', - 'defaultvalue': '1.0' }, + 'Amplitude': { + 'type': str, + 'fget': 'getAmplitude', + 'fset': 'setAmplitude', + 'description': 'Amplitude. Maybe a number or a tango attribute(must start with tango://)', + 'defaultvalue': '1.0'}, } - + def __init__(self, inst, props, *args, **kwargs): TwoDController.__init__(self, inst, props, *args, **kwargs) - self.channels = self.MaxDevice*[None,] + self.channels = self.MaxDevice * [None, ] self.reset() def GetAxisAttributes(self, axis): @@ -97,32 +99,32 @@ def GetAxisAttributes(self, axis): attrs = super(DummyTwoDController, self).GetAxisAttributes(axis) attrs['Value'][MaxDimSize] = self.BufferSize return attrs - + def reset(self): self.start_time = None self.integ_time = None self.monitor_count = None self.read_channels = {} self.counting_channels = {} - - def AddDevice(self,axis): + + def AddDevice(self, axis): idx = axis - 1 self.channels[idx] = channel = Channel(axis) channel.value = numpy.zeros(self.BufferSize, dtype=numpy.float64) - - def DeleteDevice(self,axis): + + def DeleteDevice(self, axis): idx = axis - 1 self.channels[idx] = None def PreStateAll(self): pass - + def PreStateOne(self, axis): pass - + def StateAll(self): pass - + def StateOne(self, axis): idx = axis - 1 sta = State.On @@ -136,21 +138,21 @@ def StateOne(self, axis): sta = State.Moving status = "Acquiring" return sta, status - + def _updateChannelState(self, axis, elapsed_time): - channel = self.channels[axis-1] + channel = self.channels[axis - 1] if self.integ_time is not None: # counting in time if elapsed_time >= self.integ_time: self._finish(elapsed_time) elif self.monitor_count is not None: # monitor counts - v = int(elapsed_time*100*axis) + v = int(elapsed_time * 100 * axis) if v >= self.monitor_count: self._finish(elapsed_time) - + def _updateChannelValue(self, axis, elapsed_time): - channel = self.channels[axis-1] + channel = self.channels[axis - 1] t = elapsed_time if self.integ_time is not None and not channel.is_counting: t = self.integ_time @@ -159,7 +161,7 @@ def _updateChannelValue(self, axis, elapsed_time): x, y = numpy.meshgrid(x, y) amplitude = axis * t * channel.amplitude.get() channel.value = gauss(x, 0, amplitude, 4) * gauss(y, 0, amplitude, 4) - + def _finish(self, elapsed_time, axis=None): if axis is None: for axis, channel in self.counting_channels.items(): @@ -171,15 +173,15 @@ def _finish(self, elapsed_time, axis=None): channel.is_counting = False self._updateChannelValue(axis, elapsed_time) else: - channel = self.channels[axis-1] + channel = self.channels[axis - 1] channel.is_counting = False self.counting_channels = {} - + def PreReadAll(self): self.read_channels = {} - - def PreReadOne(self,axis): - channel = self.channels[axis-1] + + def PreReadOne(self, axis): + channel = self.channels[axis - 1] self.read_channels[axis] = channel def ReadAll(self): @@ -191,27 +193,27 @@ def ReadAll(self): self._updateChannelState(axis, elapsed_time) if channel.is_counting: self._updateChannelValue(axis, elapsed_time) - + def ReadOne(self, axis): self._log.debug("ReadOne(%s)", axis) return self.read_channels[axis].value - + def PreStartAll(self): self.counting_channels = {} - + def PreStartOne(self, axis, value): idx = axis - 1 channel = self.channels[idx] channel.value = 0.0 self.counting_channels[axis] = channel return True - + def StartOne(self, axis, value): self.counting_channels[axis].is_counting = True - + def StartAll(self): self.start_time = time.time() - + def LoadOne(self, axis, value): idx = axis - 1 if value > 0: @@ -220,24 +222,23 @@ def LoadOne(self, axis, value): else: self.integ_time = None self.monitor_count = -value - + def AbortOne(self, axis): now = time.time() if axis in self.counting_channels: elapsed_time = now - self.start_time self._finish(elapsed_time, axis=axis) - + def getAmplitude(self, axis): idx = axis - 1 channel = self.channels[idx] return channel.amplitude.get_value_name() - + def setAmplitude(self, axis, value): idx = axis - 1 channel = self.channels[idx] - + klass = BaseValue if value.startswith("tango://"): klass = TangoValue - channel.amplitude = klass(value) - + channel.amplitude = klass(value) diff --git a/src/sardana/pool/poolcontrollers/DummyZeroDController.py b/src/sardana/pool/poolcontrollers/DummyZeroDController.py index f686a41a82..b65092c33d 100644 --- a/src/sardana/pool/poolcontrollers/DummyZeroDController.py +++ b/src/sardana/pool/poolcontrollers/DummyZeroDController.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -26,9 +26,10 @@ from sardana import State from sardana.pool.controller import ZeroDController + class Channel: - - def __init__(self,idx): + + def __init__(self, idx): self.idx = idx # 1 based index self.value = 0.0 self.active = False @@ -38,7 +39,7 @@ class DummyZeroDController(ZeroDController): """This class represents a dummy Sardana 0D controller.""" gender = "Simulation" - model = "Basic" + model = "Basic" organization = "Sardana team" MaxDevice = 1024 @@ -46,32 +47,32 @@ class DummyZeroDController(ZeroDController): def __init__(self, inst, props, *args, **kwargs): ZeroDController.__init__(self, inst, props, *args, **kwargs) - self.channels = [ Channel(i+1) for i in xrange(self.MaxDevice) ] + self.channels = [Channel(i + 1) for i in xrange(self.MaxDevice)] self.read_channels = {} - - def AddDevice(self,ind): + + def AddDevice(self, ind): self.channels[ind].active = True - - def DeleteDevice(self,ind): + + def DeleteDevice(self, ind): self.channels[ind].active = False - def StateOne(self,ind): + def StateOne(self, ind): return State.On, "OK" - + def _setChannelValue(self, channel): - channel.value = 100 * channel.idx + 10*(random.random()-0.5) + channel.value = 100 * channel.idx + 10 * (random.random() - 0.5) def PreReadAll(self): self.read_channels = {} - def PreReadOne(self,ind): - channel = self.channels[ind-1] + def PreReadOne(self, ind): + channel = self.channels[ind - 1] self.read_channels[ind] = channel def ReadAll(self): for channel in self.read_channels.values(): self._setChannelValue(channel) - def ReadOne(self,ind): + def ReadOne(self, ind): v = self.read_channels[ind].value return v diff --git a/src/sardana/pool/poolcontrollers/HklPseudoMotorController.py b/src/sardana/pool/poolcontrollers/HklPseudoMotorController.py index 5e8caf5cf9..c866c6f669 100644 --- a/src/sardana/pool/poolcontrollers/HklPseudoMotorController.py +++ b/src/sardana/pool/poolcontrollers/HklPseudoMotorController.py @@ -72,6 +72,7 @@ class AxisPar(object): + def __init__(self, engine, name): self.engine = engine self.name = name @@ -97,9 +98,9 @@ def modeparameters(self): @property def modeparametersvalues(self): - return [p.value_get(USER) - for p in [self.engine.parameter_get(n) - for n in self.modeparameters]] + return [p.value_get(USER) + for p in [self.engine.parameter_get(n) + for n in self.modeparameters]] @modeparametersvalues.setter def modeparametersvalues(self, value): @@ -109,7 +110,9 @@ def modeparametersvalues(self, value): p.value_set(v, USER) self.engine.parameter_set(parameter, p) -# TODO: all the fit attributes (AFit or GammaFit)should change its type to bool +# TODO: all the fit attributes (AFit or GammaFit)should change its type to bool + + class DiffracBasis(PseudoMotorController): """ The PseudoMotor controller for the diffractometer""" @@ -132,7 +135,8 @@ class DiffracBasis(PseudoMotorController): Memorize: MemorizedNoInit, Access: ReadWrite}, 'EngineModeList': {Type: (str,), Access: ReadOnly}, - 'HKLModeList': {Type: (str,), Access: ReadOnly}, # TODO delete + # TODO delete + 'HKLModeList': {Type: (str,), Access: ReadOnly}, 'UBMatrix': {Type: ((float,), ), Description: "The reflection matrix", Access: ReadOnly}, @@ -256,7 +260,7 @@ class DiffracBasis(PseudoMotorController): 'ReflectionAngles': {Type: ((float,), (float,)), Description: "Angles between reflections", # noqa Access: ReadOnly}, - 'ModeParametersNames': {Type: (str,), # TODO delete + 'ModeParametersNames': {Type: (str,), # TODO delete Description: "Name of the parameters of the current mode (if any)", # noqa Access: ReadOnly}, 'ModeParametersValues': {Type: (float,), # TODO delete @@ -323,7 +327,7 @@ def GetAxisExtraPar(self, axis, name): return getattr(self.axispar[axis - 1], name.lower()) def SetAxisExtraPar(self, axis, name, value): - setattr(self.axispar[axis - 1], name.lower(), value) + setattr(self.axispar[axis - 1], name.lower(), value) MaxDevice = 1 @@ -386,30 +390,30 @@ def __init__(self, inst, props, *args, **kwargs): self._substitutereflection = [-1.] self._swapreflections01 = -1 self._loadreflections = " " # Only to create the member, the - # value will be overwritten by - # the one in stored in the - # database + # value will be overwritten by + # the one in stored in the + # database self._savereflections = " " # Only to create the member, the - # value will be overwritten by - # the one in stored in the - # database + # value will be overwritten by + # the one in stored in the + # database self._loadcrystal = " " # Only to create the member, the - # value will be overwritten by the - # one in stored in the database + # value will be overwritten by the + # one in stored in the database self._savecrystal = -1 self._savedirectory = " " # Only to create the member, the - # value will be overwritten by the - # one in stored in the database + # value will be overwritten by the + # one in stored in the database self._energydevice = " " # Only to create the member, the - # value will be overwritten by the - # one in stored in the database + # value will be overwritten by the + # one in stored in the database self._autoenergyupdate = 0 # Only to create the member, the - # value will be overwritten by the - # one in stored in the database + # value will be overwritten by the + # one in stored in the database self._computehkl = [] self.energy_device = None - self.lambda_to_e = 12398.424 # Amstrong * eV + self.lambda_to_e = 12398.424 # Amstrong * eV def _solutions(self, values, curr_physical_position): # set all the motor min and max to restrain the solutions @@ -486,12 +490,11 @@ def CalcAllPseudo(self, physical_pos, curr_pseudo_pos): # TODO howto avoid this nb_ph_axes, does the length of the # physical values are not equal to the expected len of the # geometry axes. - + # getWavelength updates wavelength in the library in case automatic # energy update is set. Needed before computing trajectories. self.getWavelength() - # write the physical motor into the geometry self.geometry.axis_values_set(physical_pos[:self.nb_ph_axes], USER) @@ -510,10 +513,10 @@ def getCrystal(self): def setCrystal(self, value): self.sample = self.samples[value] # Used this part and comment the above one out if memorized crystal (memcrystal) - #if self.first_crystal_set == 0: + # if self.first_crystal_set == 0: # if value in self.samples: # self.sample = self.samples[value] - #else: + # else: # self.samples[value] = Hkl.Sample.new( # value) # By default a crystal is created with lattice parameters 1.54, 1.54, 1.54, 90., 90., 90. # self.sample = self.samples[value] @@ -538,9 +541,10 @@ def getWavelength(self): if self._energydevice != " " and self._autoenergyupdate: try: if self.energy_device == None: - self.energy_device = PyTango.DeviceProxy(self._energydevice) + self.energy_device = PyTango.DeviceProxy( + self._energydevice) energy = self.energy_device.Position - wavelength = self.lambda_to_e/energy + wavelength = self.lambda_to_e / energy self.setWavelength(wavelength) except: self._log.warning("Not able to get energy from energy device") @@ -574,6 +578,7 @@ def getHKLModeList(self): new_engines.init(self.geometry, self.detector, self.sample) hkl_engine = new_engines.engine_get_by_name("hkl") return hkl_engine.modes_names_get() + def getUBMatrix(self): UB = self.sample.UB_get() return [[UB.get(i, j) for j in range(3)] for i in range(3)] @@ -756,16 +761,16 @@ def setComputeTrajectoriesSim(self, values): # self.engine.name_get()) # getWavelength updates wavelength in the library in case automatic # energy update is set. Needed before computing trajectories. - + self.getWavelength() - + # Read current motor positions motor_position = [] for i in range(0, self.nb_ph_axes): motor = self.GetMotor(i) motor_position.append(motor.get_position(cache=False).value) self.geometry.axis_values_set(motor_position, USER) - + curr_physical_pos = self.geometry.axis_values_get(USER) solutions = self._solutions(values, curr_physical_pos) self.trajectorylist = [item.geometry_get().axis_values_get(USER) @@ -879,7 +884,8 @@ def setSwapReflections01(self, value): nb_ref = len(reflections) if nb_ref < 2: - self._log.warning("Only %d reflection(s) defined. Swap not possible" % (nb_ref,)) + self._log.warning( + "Only %d reflection(s) defined. Swap not possible" % (nb_ref,)) return hkla = [] @@ -923,7 +929,6 @@ def setSwapReflections01(self, value): self.setSubstituteReflection(hkla[0]) self.setAdjustAnglesToReflection(angles[0]) - def getReflectionList(self): reflectionslist = [] i = 0 @@ -947,7 +952,8 @@ def setRemoveReflection(self, value): # value: reflexion index self.sample.del_reflection(ref) i = i + 1 - def setLoadReflections(self, value): # value: complete path of the file with the reflections to set + # value: complete path of the file with the reflections to set + def setLoadReflections(self, value): # Read the file with open(value, 'r') as f: self._loadreflections = value @@ -989,18 +995,20 @@ def setLoadCrystal(self, value): self._loadcrystal = value nb_ref = 0 - + for line in crystal_file: - line = line.replace("\n","") + line = line.replace("\n", "") if line.find("Crystal") != -1: # Add crystal line = line.replace(" ", "") - crystal = line.split("Crystal",1)[1] + crystal = line.split("Crystal", 1)[1] self.setAddCrystal(crystal) # Set crystal self.sample = self.samples[crystal] - self.engines.init(self.geometry, self.detector, self.sample) - # Remove all reflections from crystal (there should not be any ... but just in case) + self.engines.init( + self.geometry, self.detector, self.sample) + # Remove all reflections from crystal (there should not be + # any ... but just in case) for ref in self.sample.reflections_get(): self.sample.del_reflection(ref) elif line.find("A") != -1 and line.find("B") != -1 and line.find("C") != -1: @@ -1010,7 +1018,8 @@ def setLoadCrystal(self, value): cvalue = float(par_line[5]) lattice = self.sample.lattice_get() a, b, c, alpha, beta, gamma = lattice.get(USER) - lattice.set(avalue,bvalue,cvalue, alpha, beta, gamma, USER) + lattice.set(avalue, bvalue, cvalue, + alpha, beta, gamma, USER) # For getting the UB matrix changing self.sample.lattice_set(lattice) self._a = avalue @@ -1023,7 +1032,8 @@ def setLoadCrystal(self, value): gammavalue = float(par_line[5]) lattice = self.sample.lattice_get() a, b, c, alpha, beta, gamma = lattice.get(USER) - lattice.set(a,b,c, alphavalue, betavalue, gammavalue, USER) + lattice.set(a, b, c, alphavalue, + betavalue, gammavalue, USER) # For getting the UB matrix changing self.sample.lattice_set(lattice) self._alpha = alphavalue @@ -1046,15 +1056,18 @@ def setLoadCrystal(self, value): try: self.setPsiRefH(psirefh) except: - self._log.warning("PsiRefH not set. Psi not available in current mode") + self._log.warning( + "PsiRefH not set. Psi not available in current mode") try: self.setPsiRefK(psirefk) except: - self._log.warning("PsiRefK not set. Psi not available in current mode") + self._log.warning( + "PsiRefK not set. Psi not available in current mode") try: self.setPsiRefL(psirefl) except: - self._log.warning("PsiRefL not set. Psi not available in current mode") + self._log.warning( + "PsiRefL not set. Psi not available in current mode") elif line.find("R0") != -1 or line.find("R1") != -1: if line.find("R0") != -1: line = line.split("R0 ")[1] @@ -1064,7 +1077,10 @@ def setLoadCrystal(self, value): ref_values = [] for value in line.split(' '): try: - ref_values.append(float(value)) # index 0 -> reflec. index; index 1,2, 3 hkl; 4 relevance; 5 affinement; last ones (2, 4 or 6) angles + # index 0 -> reflec. index; index 1,2, 3 hkl; 4 + # relevance; 5 affinement; last ones (2, 4 or 6) + # angles + ref_values.append(float(value)) except: pass # Set hkl values to the reflection @@ -1089,11 +1105,11 @@ def setLoadCrystal(self, value): self._autoenergyupdate = int(line[1]) if nb_ref > 1: - values = [0,1] + values = [0, 1] self.setComputeUB(values) - - def setSaveReflections(self, value): # value: directory, the file would be given by the name of the sample + # value: directory, the file would be given by the name of the sample + def setSaveReflections(self, value): complete_file_name = value + str(self.sample.name_get()) + ".ref" complete_file_name = complete_file_name.replace(' ', '') complete_file_name = complete_file_name.replace('(', '_') @@ -1121,23 +1137,22 @@ def setSaveCrystal(self, value): # value: not used with open(default_file_name, 'w') as crys_file: # date - + date_str = "Created at " + time.strftime("%Y-%m-%d %H:%M") + "\n\n" crys_file.write(date_str) - + # write crystal name - + crystal_name = self.sample.name_get() - crys_str = "Crystal " + crystal_name + "\n\n" + crys_str = "Crystal " + crystal_name + "\n\n" crys_file.write(crys_str) - + # write wavelength - + wavelength = self.geometry.wavelength_get(USER) wl_str = "Wavelength " + str(wavelength) + "\n\n" crys_file.write(wl_str) - - + # write lattice parameters apar = self.sample.lattice_get().a_get() a = apar.value_get(USER) @@ -1153,9 +1168,10 @@ def setSaveCrystal(self, value): # value: not used gamma = gammapar.value_get(USER) par_str = "A " + str(a) + " B " + str(b) + " C " + str(c) + "\n" crys_file.write(par_str) - par_str = "Alpha " + str(alpha) + " Beta " + str(beta) + " Gamma " + str(gamma) + "\n\n" + par_str = "Alpha " + str(alpha) + " Beta " + \ + str(beta) + " Gamma " + str(gamma) + "\n\n" crys_file.write(par_str) - + # write reflections reflections = self.getReflectionList() ref_in = 0 @@ -1172,50 +1188,56 @@ def setSaveCrystal(self, value): # value: not used ref_str = "No reflections\n" crys_file.write(ref_str) crys_file.write("\n") - + # write engine - engine_str = "Engine " + self.engine.name_get() + "\n\n" + engine_str = "Engine " + self.engine.name_get() + "\n\n" crys_file.write(engine_str) - + # write mode - mode_str = "Mode " + self.engine.current_mode_get() + "\n\n" + mode_str = "Mode " + self.engine.current_mode_get() + "\n\n" crys_file.write(mode_str) - + # write psiref (if available in mode) - + psirefh = self.getPsiRefH() psirefk = self.getPsiRefK() psirefl = self.getPsiRefL() if psirefh != -999 or psirefk != -999 or psirefl != -999: - psi_str = "PsiRef " + str(psirefh) + " " + str(psirefk) + " " + str(psirefl) + "\n\n" + psi_str = "PsiRef " + \ + str(psirefh) + " " + str(psirefk) + \ + " " + str(psirefl) + "\n\n" else: psi_str = "PsiRef not available in current engine mode\n\n" - + crys_file.write(psi_str) - + # write autoenergyupdate value - - autoenergyupdate_str = "AutoEnergyUpdate " + str(self._autoenergyupdate) + "\n\n" + + autoenergyupdate_str = "AutoEnergyUpdate " + \ + str(self._autoenergyupdate) + "\n\n" crys_file.write(autoenergyupdate_str) - + # Only for info in the file but not for loading: - + # write ub matrix - for i in range(0,3): + for i in range(0, 3): ub_str = "" - for j in range(0,3): + for j in range(0, 3): #ub_str = ub_str + "U" + str(i) + str(j) + " " + str(self.sample.UB_get().get(i, j)) + " " - ub_str = ub_str + "U" + str(i) + str(j) + " %.3f" % self.sample.UB_get().get(i, j) + " " + ub_str = ub_str + "U" + \ + str(i) + str(j) + \ + " %.3f" % self.sample.UB_get().get(i, j) + " " ub_str = ub_str + "\n" crys_file.write(ub_str) crys_file.write("\n") - + # write u vector - u_str = "Ux " + str(self.sample.ux_get().value_get(USER)) + " Uy " + str(self.sample.uy_get().value_get(USER)) + " Uz " + str(self.sample.uz_get().value_get(USER)) + "\n\n" + u_str = "Ux " + str(self.sample.ux_get().value_get(USER)) + " Uy " + str(self.sample.uy_get( + ).value_get(USER)) + " Uz " + str(self.sample.uz_get().value_get(USER)) + "\n\n" crys_file.write(u_str) - + # write directory where the file is saved - + dir_str = "SaveDirectory " + self._savedirectory + "\n" crys_file.write(dir_str) @@ -1225,7 +1247,8 @@ def setSaveCrystal(self, value): # value: not used def setSaveDirectory(self, value): self._savedirectory = value - def setAdjustAnglesToReflection(self, value): # value: reflexion index + new angles + # value: reflexion index + new angles + def setAdjustAnglesToReflection(self, value): ref_index = value[0] new_angles = value[1:] i = 0 @@ -1257,7 +1280,6 @@ def getReflectionAngles(self): def getModeParametersNames(self): return self.engine.parameters_names_get() - def getModeParametersValues(self): return [p.value_get(USER) @@ -1341,28 +1363,26 @@ def setAutoEnergyUpdate(self, value): self._autoenergyupdate = value def setComputeHKL(self, value): - + # getWavelength updates wavelength in the library in case automatic # energy update is set. Needed before computing trajectories. - + self.getWavelength() - # write the physical motor into the geometry - if len(value) >= self.nb_ph_axes: + if len(value) >= self.nb_ph_axes: self.geometry.axis_values_set(value[:self.nb_ph_axes], USER) self.engines.get() - else: - raise Exception("Not enough arguments. %d are need " % (self.nb_ph_axes)) + else: + raise Exception("Not enough arguments. %d are need " % + (self.nb_ph_axes)) # extract hkl values values = [] engine = self.engines.engine_get_by_name("hkl") values = engine.pseudo_axis_values_get(USER) - - self._computehkl = values - + self._computehkl = values # 6C Diffractometers #################### diff --git a/src/sardana/pool/poolcontrollers/IoverI0.py b/src/sardana/pool/poolcontrollers/IoverI0.py index 4c5049c479..c7326bed0e 100644 --- a/src/sardana/pool/poolcontrollers/IoverI0.py +++ b/src/sardana/pool/poolcontrollers/IoverI0.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -34,17 +34,17 @@ class IoverI0(PseudoCounterController): """ A simple pseudo counter which receives two counter values (I and I0) and returns I/I0""" - + gender = "IoverI0" - model = "Default I/I0" + model = "Default I/I0" organization = "Sardana team" - + counter_roles = "I", "I0" def Calc(self, axis, counter_values): i, i0 = counter_values try: - i = float(i/i0) + i = float(i / i0) except ZeroDivisionError: pass return i diff --git a/src/sardana/pool/poolcontrollers/Slit.py b/src/sardana/pool/poolcontrollers/Slit.py index e34526d09b..f62f730133 100644 --- a/src/sardana/pool/poolcontrollers/Slit.py +++ b/src/sardana/pool/poolcontrollers/Slit.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -32,58 +32,59 @@ from sardana.pool.controller import PseudoMotorController from sardana.pool.controller import DefaultValue, Description, Access, Type - + class Slit(PseudoMotorController): """A Slit pseudo motor controller for handling gap and offset pseudo motors. The system uses to real motors sl2t (top slit) and sl2b (bottom slit)""" - + gender = "Slit" - model = "Default Slit" + model = "Default Slit" organization = "Sardana team" - + pseudo_motor_roles = "Gap", "Offset" motor_roles = "sl2t", "sl2b" - - ctrl_properties = { 'sign' : { Type : float, - Description : 'Gap = sign * calculated gap\nOffset = sign * calculated offet', - DefaultValue : 1 }, } - - axis_attributes = { 'example' : { Type : int, - Access : DataAccess.ReadWrite, - Description : 'test purposes' }, } + + ctrl_properties = {'sign': {Type: float, + Description: 'Gap = sign * calculated gap\nOffset = sign * calculated offet', + DefaultValue: 1}, } + + axis_attributes = {'example': {Type: int, + Access: DataAccess.ReadWrite, + Description: 'test purposes'}, } def __init__(self, inst, props, *args, **kwargs): PseudoMotorController.__init__(self, inst, props, *args, **kwargs) self._log.debug("Created SLIT %s", inst) self._example = {} - + def CalcPhysical(self, index, pseudo_pos, curr_physical_pos): - half_gap = pseudo_pos[0]/2.0 + half_gap = pseudo_pos[0] / 2.0 if index == 1: ret = self.sign * (pseudo_pos[1] + half_gap) else: ret = self.sign * (half_gap - pseudo_pos[1]) - self._log.debug("Slit.CalcPhysical(%d, %s) -> %f", index, pseudo_pos, ret) + self._log.debug("Slit.CalcPhysical(%d, %s) -> %f", + index, pseudo_pos, ret) return ret - + def CalcPseudo(self, index, physical_pos, curr_pseudo_pos): gap = physical_pos[1] + physical_pos[0] if index == 1: ret = self.sign * gap else: - ret = self.sign * (physical_pos[0] - gap/2.0) + ret = self.sign * (physical_pos[0] - gap / 2.0) return ret - + def CalcAllPseudo(self, physical_pos, curr_pseudo_pos): """Calculates the positions of all pseudo motors that belong to the pseudo motor system from the positions of the physical motors.""" gap = physical_pos[1] + physical_pos[0] return (self.sign * gap, - self.sign * (physical_pos[0] - gap/2.0)) - - #def CalcAllPhysical(self, pseudo_pos, curr_physical_pos): - # """Calculates the positions of all motors that belong to the pseudo + self.sign * (physical_pos[0] - gap / 2.0)) + + # def CalcAllPhysical(self, pseudo_pos, curr_physical_pos): + # """Calculates the positions of all motors that belong to the pseudo # motor system from the positions of the pseudo motors.""" # half_gap = pseudo_pos[0]/2.0 # return (self.sign * (pseudo_pos[1] + half_gap), @@ -91,6 +92,6 @@ def CalcAllPseudo(self, physical_pos, curr_pseudo_pos): def SetAxisExtraPar(self, axis, parameter, value): self._example[axis] = value - + def GetAxisExtraPar(self, axis, parameter): return self._example.get(axis, -1) diff --git a/src/sardana/pool/poolcontrollers/TangoController.py b/src/sardana/pool/poolcontrollers/TangoController.py index dced73c959..f961001013 100644 --- a/src/sardana/pool/poolcontrollers/TangoController.py +++ b/src/sardana/pool/poolcontrollers/TangoController.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -35,18 +35,19 @@ TangoAttribute = "TangoAttribute" Formula = "Formula" + class ReadTangoAttributes(object): """ Generic class that has as many devices as the user wants. Each device has a tango attribute and a formula and the 'hardware' tango calls are optimized in the sense that only one call per tango device is issued. """ axis_attributes = { - TangoAttribute : { Type : str, Access : DataAccess.ReadWrite, - Description : 'Attribute to read (e.g. a/b/c/attr)' }, - Formula : { Type : str, Access : DataAccess.ReadWrite, - DefaultValue : "VALUE", - Description : 'The Formula to get the desired value.\n' - 'e.g. "math.sqrt(VALUE)"' }, + TangoAttribute: {Type: str, Access: DataAccess.ReadWrite, + Description: 'Attribute to read (e.g. a/b/c/attr)'}, + Formula: {Type: str, Access: DataAccess.ReadWrite, + DefaultValue: "VALUE", + Description: 'The Formula to get the desired value.\n' + 'e.g. "math.sqrt(VALUE)"'}, } def __init__(self): @@ -63,7 +64,8 @@ def __init__(self): self._axis_formulas = {} def add_device(self, axis): - self._pending[axis] = "No tango attribute associated to this device yet" + self._pending[ + axis] = "No tango attribute associated to this device yet" self._axis_formulas[axis] = self.axis_attribute[Formula][DefaultValue] def delete_device(self, axis): @@ -120,7 +122,8 @@ def set_extra_attribute_par(self, axis, name, value): if len(df): self._pending[axis] = df[0].reason + ": " + df[0].desc else: - self._pending[axis] = "Unknwon PyTango Error: " + str(df) + self._pending[ + axis] = "Unknwon PyTango Error: " + str(df) raise self._devices[dev_name] = dev_info = proxy, [] data[2] = dev_info[0] @@ -129,6 +132,7 @@ def set_extra_attribute_par(self, axis, name, value): elif name == Formula: self._axis_formulas[axis] = value + class TangoCounterTimerController(ReadTangoAttributes, CounterTimerController): """This controller offers as many channels as the user wants. Each channel has two _MUST_HAVE_ extra attributes: @@ -197,4 +201,3 @@ def StartAllCT(self): def LoadOne(self, axis, value): pass - diff --git a/src/sardana/pool/poolcontrollers/__init__.py b/src/sardana/pool/poolcontrollers/__init__.py index 59eb13f428..bcb3403cea 100644 --- a/src/sardana/pool/poolcontrollers/__init__.py +++ b/src/sardana/pool/poolcontrollers/__init__.py @@ -2,25 +2,25 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## -""" """ \ No newline at end of file +""" """ diff --git a/src/sardana/pool/poolcontrollers/test/__init__.py b/src/sardana/pool/poolcontrollers/test/__init__.py index 77e4f7c3b3..f7a77b2d69 100644 --- a/src/sardana/pool/poolcontrollers/test/__init__.py +++ b/src/sardana/pool/poolcontrollers/test/__init__.py @@ -1 +1 @@ -from base import * \ No newline at end of file +from base import * diff --git a/src/sardana/pool/poolcontrollers/test/base.py b/src/sardana/pool/poolcontrollers/test/base.py index a794847d89..6fe43e1422 100644 --- a/src/sardana/pool/poolcontrollers/test/base.py +++ b/src/sardana/pool/poolcontrollers/test/base.py @@ -2,30 +2,31 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## __all__ = ['BaseControllerTestCase', 'TriggerGateControllerTestCase', 'PositionGenerator', 'TriggerGateReceiver'] -import time, threading +import time +import threading import numpy from taurus.external import unittest @@ -36,6 +37,7 @@ from sardana.sardanaattribute import SardanaAttribute from taurus.core.util.log import Logger + class BaseControllerTestCase(object): """ Base test case for unit testing arbitrary controllers. This class will create a controller instance and define an axis from the @@ -74,7 +76,7 @@ def axisPar(self, name, value, expected_value=None): self.ctrl.SetAxisPar(axis, name, value) r_value = self.ctrl.GetAxisPar(axis, name) msg = ('The %s value is %s, and the expected value is %s' - %(name, r_value, expected_value)) + % (name, r_value, expected_value)) self.assertEqual(r_value, expected_value, msg) def stateOne(self, expected_state=State.On): @@ -82,7 +84,7 @@ def stateOne(self, expected_state=State.On): """ sta, status = self.ctrl.StateOne(self.AXIS) msg = ('The current state of axis(%d) is %d when expected, %d' - %(self.AXIS, sta, expected_state)) + % (self.AXIS, sta, expected_state)) self.assertEqual(sta, expected_state, msg) def start_action(self, configuration): @@ -91,9 +93,11 @@ def start_action(self, configuration): for key, value in configuration.items(): self.axisPar(key, value) self.ctrl.SynchOne(configuration) + def pre_AddDevice_hook(self): pass + class TriggerGateControllerTestCase(unittest.TestCase, BaseControllerTestCase): def setUp(self): @@ -135,7 +139,7 @@ def generation(self, configuration): self.post_generation_hook() state, status = self.ctrl.StateOne(self.AXIS) msg = ('The axis %d is not Stopped, its status is %s' - %(self.AXIS, status)) + % (self.AXIS, status)) self.assertEqual(state, State.get('On'), msg) def abort(self, configuration, abort): @@ -154,13 +158,15 @@ def abort(self, configuration, abort): self.post_generation_hook() state, status = self.ctrl.StateOne(self.AXIS) msg = ('The axis %d is not Stopped, its status is %s' - %(self.AXIS, status)) + % (self.AXIS, status)) self.assertEqual(state, State.get('On'), msg) + class PositionGenerator(threading.Thread): """ It is a position generator. A Sardana Motion class is used for simulate the motor. The attribute value has the current user position of the motor. """ + def __init__(self, start_pos, end_pos, period): """ :param start_pos: start position for the motion @@ -227,7 +233,8 @@ class TriggerGateReceiver(object): comes. Provides useful methods for calculating the event generation performance ''' - #TODO: add more jitter measurements e.g. drift + # TODO: add more jitter measurements e.g. drift + def __init__(self): self.active_events = {} self.passive_events = {} @@ -251,7 +258,7 @@ def event_received(self, *args, **kwargs): raise ValueError('Unknown EventType') def calc_characteristics(self): - #TODO: refactor the characteristics calculation method to use numpy + # TODO: refactor the characteristics calculation method to use numpy i = 0 count = self.count characteristics = {} @@ -260,7 +267,7 @@ def calc_characteristics(self): while i < (count - 1): t1 = self.active_events[i] t2 = self.passive_events[i] - t3 = self.active_events[i+1] + t3 = self.active_events[i + 1] active_period = t2 - t1 passive_period = t3 - t2 characteristics[i] = (active_period, passive_period) @@ -285,7 +292,7 @@ def calc_cycletocycle(self): # calculate characteristics until (count - 1) while i < (count - 1): t1 = self.active_events[i] - t2 = self.active_events[i+1] + t2 = self.active_events[i + 1] period = t2 - t1 periods.append(period) i += 1 diff --git a/src/sardana/pool/poolcontrollers/test/test_DummyCounterTimerController.py b/src/sardana/pool/poolcontrollers/test/test_DummyCounterTimerController.py index 69fef78ecc..1955ad1213 100644 --- a/src/sardana/pool/poolcontrollers/test/test_DummyCounterTimerController.py +++ b/src/sardana/pool/poolcontrollers/test/test_DummyCounterTimerController.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,6 +29,7 @@ from sardana.pool.test.test_acquisition import AcquisitionTestCase import logging + @insertTest(helper_name='hw_step_acquisition', repetitions=1, integ_time=0.4) class DummyCounterTimerControllerTestCase(AcquisitionTestCase, unittest.TestCase): diff --git a/src/sardana/pool/poolcontrollers/test/test_DummyTriggerGateController.py b/src/sardana/pool/poolcontrollers/test/test_DummyTriggerGateController.py index 1da20257ff..e8a82b96bc 100644 --- a/src/sardana/pool/poolcontrollers/test/test_DummyTriggerGateController.py +++ b/src/sardana/pool/poolcontrollers/test/test_DummyTriggerGateController.py @@ -6,7 +6,7 @@ from sardana.pool.test import (FakePool, createPoolController, createPoolTriggerGate, dummyPoolTGCtrlConf01, - dummyTriggerGateConf01, + dummyTriggerGateConf01, createPoolSynchronizationConfiguration) synchronization1 = [{SynchParam.Delay: {SynchDomain.Time: 0}, @@ -19,6 +19,7 @@ SynchParam.Total: {SynchDomain.Time: .02}, SynchParam.Repeats: 10}] + @insertTest(helper_name='generation', synchronization=synchronization1) @insertTest(helper_name='generation', synchronization=synchronization2) class PoolDummyTriggerGateTestCase(unittest.TestCase): @@ -43,7 +44,7 @@ def setUp(self): dummy_tg_ctrl.add_element(self.dummy_tg) self.cfg = createPoolSynchronizationConfiguration((dummy_tg_ctrl,), - ((self.dummy_tg,),)) + ((self.dummy_tg,),)) # marrying the element with the action self.tg_action = PoolSynchronization(self.dummy_tg) @@ -55,10 +56,10 @@ def generation(self, synchronization): args = () kwargs = {'config': self.cfg, 'synchronization': synchronization - } + } self.tg_action.start_action(*args, **kwargs) self.tg_action.action_loop() - # TODO: add asserts applicable to a dummy controller e.g. listen to + # TODO: add asserts applicable to a dummy controller e.g. listen to # state changes and verify if the change ON->MOVING-ON was emitted def tearDown(self): diff --git a/src/sardana/pool/poolcountertimer.py b/src/sardana/pool/poolcountertimer.py index 417f94f27d..8f1fa8a416 100644 --- a/src/sardana/pool/poolcountertimer.py +++ b/src/sardana/pool/poolcountertimer.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/pooldefs.py b/src/sardana/pool/pooldefs.py index d869e52617..740118d72a 100644 --- a/src/sardana/pool/pooldefs.py +++ b/src/sardana/pool/pooldefs.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -38,9 +38,11 @@ #: A constant defining the controller API version currently supported ControllerAPI = 1.1 -# synchronization domain: Time means that the configuration parameter will be +# synchronization domain: Time means that the configuration parameter will be # expressed in the time domain, Position means the motor position domain and -# Monitor means the count to monitor domain +# Monitor means the count to monitor domain + + class SynchEnum(IntEnum): @classmethod @@ -60,6 +62,7 @@ def fromStr(cls, string): else: raise ValueError('Can not convert %s to SynchDomain' % string) + class SynchDomain(SynchEnum): """Enumeration of synchronization domains. @@ -107,7 +110,7 @@ class SynchParam(SynchEnum): # TODO: convert to to python enums, but having in ming problems with # JSON serialization: https://bugs.python.org/issue18264 # class AcqSynchType(Enumeration): -# +# # Trigger = 0 # Gate = 1 @@ -133,8 +136,8 @@ def from_synch_type(self, software, synch_type): return AcqSynch.SoftwareTrigger else: return AcqSynch.HardwareTrigger - elif synch_type is AcqSynchType.Gate: - if software: + elif synch_type is AcqSynchType.Gate: + if software: return AcqSynch.SoftwareGate else: return AcqSynch.HardwareGate diff --git a/src/sardana/pool/poolelement.py b/src/sardana/pool/poolelement.py index 8f97a07752..8aff3b53e6 100644 --- a/src/sardana/pool/poolelement.py +++ b/src/sardana/pool/poolelement.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/poolexception.py b/src/sardana/pool/poolexception.py index 60abd893ba..53746739df 100644 --- a/src/sardana/pool/poolexception.py +++ b/src/sardana/pool/poolexception.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/poolextension.py b/src/sardana/pool/poolextension.py index 31d0b670bc..a9e78ed9eb 100644 --- a/src/sardana/pool/poolextension.py +++ b/src/sardana/pool/poolextension.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -64,14 +64,14 @@ class ControllerStateTranslator(BaseControllerTranslator): def register_controller_value_translator(klass, *args, **kwargs): if not issubclass(klass, ControllerValueTranslator): - raise Exception("Cannot register controller value translator. " \ + raise Exception("Cannot register controller value translator. " "Class must inherit from ControllerValueTranslator") __CTRL_VALUE_TRANSLATORS[klass] = klass(*args, **kwargs) def register_controller_state_translator(klass, *args, **kwargs): if not issubclass(klass, ControllerStateTranslator): - raise Exception("Cannot register controller value translator. " \ + raise Exception("Cannot register controller value translator. " "Class must inherit from ControllerStateTranslator") __CTRL_STATE_TRANSLATORS[klass] = klass(*args, **kwargs) diff --git a/src/sardana/pool/poolexternal.py b/src/sardana/pool/poolexternal.py index a144b9d072..45556c4a7a 100644 --- a/src/sardana/pool/poolexternal.py +++ b/src/sardana/pool/poolexternal.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -114,12 +114,11 @@ def get_config(self): attribute_name = property(get_attribute_name) -_SCHEME_CLASS = { 'tango' : PoolTangoObject, - None : PoolTangoObject} +_SCHEME_CLASS = {'tango': PoolTangoObject, + None: PoolTangoObject} def PoolExternalObject(**kwargs): scheme = kwargs.get('scheme', 'tango') klass = _SCHEME_CLASS[scheme] return klass(**kwargs) - diff --git a/src/sardana/pool/poolgroupelement.py b/src/sardana/pool/poolgroupelement.py index ec35eb12a0..cb76b84533 100644 --- a/src/sardana/pool/poolgroupelement.py +++ b/src/sardana/pool/poolgroupelement.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/poolinstrument.py b/src/sardana/pool/poolinstrument.py index 039e5e80d7..6741e59fe6 100644 --- a/src/sardana/pool/poolinstrument.py +++ b/src/sardana/pool/poolinstrument.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -93,7 +93,7 @@ def remove_element(self, element): del self._elements[element.id] def get_elements(self): - return [ e() for e in self._elements.values() ] + return [e() for e in self._elements.values()] def has_instruments(self): return len(self._child_instruments) > 0 diff --git a/src/sardana/pool/poolioregister.py b/src/sardana/pool/poolioregister.py index d08955bb01..d1b54e856d 100644 --- a/src/sardana/pool/poolioregister.py +++ b/src/sardana/pool/poolioregister.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/poolmeasurementgroup.py b/src/sardana/pool/poolmeasurementgroup.py index efa99db191..d002505e96 100644 --- a/src/sardana/pool/poolmeasurementgroup.py +++ b/src/sardana/pool/poolmeasurementgroup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -36,14 +36,14 @@ from taurus.core.taurusvalidator import AttributeNameValidator as\ TangoAttributeNameValidator except ImportError: - #TODO: For Taurus 4 compatibility + # TODO: For Taurus 4 compatibility from taurus.core.tango.tangovalidator import TangoAttributeNameValidator from sardana import State, ElementType, \ TYPE_EXP_CHANNEL_ELEMENTS, TYPE_TIMERABLE_ELEMENTS from sardana.sardanaevent import EventType from sardana.pool.pooldefs import (AcqMode, AcqSynchType, SynchParam, AcqSynch, - SynchDomain) + SynchDomain) from sardana.pool.poolgroupelement import PoolGroupElement from sardana.pool.poolacquisition import PoolAcquisition from sardana.pool.poolexternal import PoolExternalObject @@ -103,6 +103,7 @@ """ + class PoolMeasurementGroup(PoolGroupElement): DFT_DESC = 'General purpose measurement group' @@ -169,13 +170,13 @@ def get_pool_controller_by_name(self, name): for ctrl in self.get_pool_controllers(): if ctrl.name.lower() == name or ctrl.full_name.lower() == name: return ctrl - + def add_user_element(self, element, index=None): '''Override the base behavior, so the TriggerGate elements are silently skipped if used multiple times in the group''' user_elements = self._user_elements if element in user_elements: - # skipping TriggerGate element if already present + # skipping TriggerGate element if already present if element.get_type() is ElementType.TriggerGate: return return PoolGroupElement.add_user_element(self, element, index) @@ -189,6 +190,7 @@ def _is_managed_element(self, element): element_type is ElementType.TriggerGate) """Fills the channel default values for the given channel dictionary""" + def _build_channel_defaults(self, channel_data, channel): external_from_name = isinstance(channel, (str, unicode)) @@ -230,7 +232,8 @@ def _build_channel_defaults(self, channel_data, channel): channel_data['source'] = channel_data.get('source', source) channel_data['enabled'] = channel_data.get('enabled', True) channel_data['label'] = channel_data.get('label', channel_data['name']) - channel_data['instrument'] = channel_data.get('instrument', getattr(instrument, 'name', None)) + channel_data['instrument'] = channel_data.get( + 'instrument', getattr(instrument, 'name', None)) channel_data['ndim'] = ndim # Probably should be initialized by measurement group channel_data['output'] = channel_data.get('output', True) @@ -239,7 +242,8 @@ def _build_channel_defaults(self, channel_data, channel): channel_data['plot_type'] = channel_data.get('plot_type', PlotType.No) channel_data['plot_axes'] = channel_data.get('plot_axes', []) channel_data['conditioning'] = channel_data.get('conditioning', '') - channel_data['normalization'] = channel_data.get('normalization', Normalization.No) + channel_data['normalization'] = channel_data.get( + 'normalization', Normalization.No) return channel_data @@ -290,7 +294,8 @@ def _build_configuration(self): ctrl_data['synchronization'] = AcqSynchType.Trigger ctrl_data['synchronizer'] = 'software' self._ctrl_to_acq_synch[ctrl] = AcqSynch.SoftwareTrigger - self._channel_to_acq_synch[element] = AcqSynch.SoftwareTrigger + self._channel_to_acq_synch[ + element] = AcqSynch.SoftwareTrigger else: channels = ctrl_data['channels'] channels[element] = channel_data = {} @@ -305,7 +310,8 @@ def _build_configuration(self): for index, element in external_user_elements: channels[element] = channel_data = {} channel_data['index'] = index - channel_data = self._build_channel_defaults(channel_data, element) + channel_data = self._build_channel_defaults( + channel_data, element) return config def set_configuration(self, config=None, propagate=1): @@ -325,15 +331,18 @@ def set_configuration(self, config=None, propagate=1): acq_synch = None ctrl_enabled = False if not external and c.is_timerable(): - acq_synch = AcqSynch.from_synch_type(software, acq_synch_type) + acq_synch = AcqSynch.from_synch_type( + software, acq_synch_type) for channel_data in c_data['channels'].values(): if external: element = _id = channel_data['full_name'] channel_data['source'] = _id else: - element = pool.get_element_by_full_name(channel_data['full_name']) + element = pool.get_element_by_full_name( + channel_data['full_name']) _id = element.id - channel_data = self._build_channel_defaults(channel_data, element) + channel_data = self._build_channel_defaults( + channel_data, element) if channel_data["enabled"]: if acq_synch is not None: ctrl_enabled = True @@ -345,7 +354,7 @@ def set_configuration(self, config=None, propagate=1): self._ctrl_to_acq_synch[c] = acq_synch # sorted ids may not be consecutive (if a channel is disabled) indexes = sorted(user_elem_ids.keys()) - user_elem_ids_list = [ user_elem_ids[idx] for idx in indexes ] + user_elem_ids_list = [user_elem_ids[idx] for idx in indexes] user_elem_ids_list.extend(tg_elem_ids) self.set_user_element_ids(user_elem_ids_list) @@ -430,8 +439,8 @@ def set_configuration_from_user(self, cfg, propagate=1): # backwards compatibility for configurations before SEP6 synchronization = c_data['trigger_type'] msg = ("trigger_type configuration parameter is deprecated" - " in favor of synchronization. Re-apply configuration" - " in order to upgrade.") + " in favor of synchronization. Re-apply configuration" + " in order to upgrade.") self.warning(msg) ctrl_data['synchronization'] = synchronization ctrl_data['channels'] = channels = {} @@ -502,14 +511,15 @@ def load_configuration(self, force=False): continue ctrl.operator = self if ctrl.is_timerable(): - #if ctrl == g_timer.controller: + # if ctrl == g_timer.controller: # ctrl.set_ctrl_par('timer', g_timer.axis) - #if ctrl == g_monitor.controller: + # if ctrl == g_monitor.controller: # ctrl.set_ctrl_par('monitor', g_monitor.axis) ctrl.set_ctrl_par('timer', ctrl_data['timer'].axis) ctrl.set_ctrl_par('monitor', ctrl_data['monitor'].axis) synchronization = self._ctrl_to_acq_synch.get(ctrl) - self.debug('load_configuration: setting trigger_type: %s to ctrl: %s' % (synchronization, ctrl)) + self.debug('load_configuration: setting trigger_type: %s to ctrl: %s' % ( + synchronization, ctrl)) ctrl.set_ctrl_par('synchronization', synchronization) self._config_dirty = False @@ -518,7 +528,7 @@ def get_timer(self): return self.get_configuration()['timer'] timer = property(get_timer) - + # -------------------------------------------------------------------------- # repetitions # -------------------------------------------------------------------------- @@ -534,7 +544,7 @@ def set_repetitions(self, repetitions, propagate=1): repetitions) repetitions = property(get_repetitions, set_repetitions, - doc="repetitions used in synchronized acquisition") + doc="repetitions used in synchronized acquisition") # -------------------------------------------------------------------------- # integration time @@ -591,7 +601,7 @@ def get_acquisition_mode(self): def set_acquisition_mode(self, acquisition_mode, propagate=1): self._acquisition_mode = acquisition_mode - self._config_dirty = True #acquisition mode goes to configuration + self._config_dirty = True # acquisition mode goes to configuration if not propagate: return self.fire_event(EventType("acquisition_mode", priority=propagate), @@ -609,15 +619,15 @@ def get_synchronization(self): def set_synchronization(self, synchronization, propagate=1): self._synchronization = synchronization - self._config_dirty = True #acquisition mode goes to configuration + self._config_dirty = True # acquisition mode goes to configuration if not propagate: return self.fire_event(EventType("synchronization", priority=propagate), synchronization) synchronization = property(get_synchronization, set_synchronization, - doc="the current acquisition mode") - + doc="the current acquisition mode") + # -------------------------------------------------------------------------- # moveable # -------------------------------------------------------------------------- @@ -633,7 +643,7 @@ def set_moveable(self, moveable, propagate=1): moveable) moveable = property(get_moveable, set_moveable, - doc="moveable source used in synchronization") + doc="moveable source used in synchronization") # -------------------------------------------------------------------------- # latency time @@ -651,7 +661,7 @@ def get_latency_time(self): return latency_time latency_time = property(get_latency_time, - doc="latency time between two consecutive acquisitions") + doc="latency time between two consecutive acquisitions") # -------------------------------------------------------------------------- # acquisition diff --git a/src/sardana/pool/poolmetacontroller.py b/src/sardana/pool/poolmetacontroller.py index 5e670a67c3..24e60e1adc 100644 --- a/src/sardana/pool/poolmetacontroller.py +++ b/src/sardana/pool/poolmetacontroller.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -75,14 +75,14 @@ #: mapping element type enumeration with the corresponding controller pool class #: (:class:`~sardana.pool.poolcontroller.PoolController` or sub-class of it). CTRL_TYPE_MAP = { - ET.Motor : PoolController, - ET.CTExpChannel : PoolController, - ET.OneDExpChannel : PoolController, - ET.TwoDExpChannel : PoolController, - ET.TriggerGate : PoolController, - ET.PseudoMotor : PoolPseudoMotorController, - ET.PseudoCounter : PoolPseudoCounterController, - ET.IORegister : PoolController, + ET.Motor: PoolController, + ET.CTExpChannel: PoolController, + ET.OneDExpChannel: PoolController, + ET.TwoDExpChannel: PoolController, + ET.TriggerGate: PoolController, + ET.PseudoMotor: PoolPseudoMotorController, + ET.PseudoCounter: PoolPseudoCounterController, + ET.IORegister: PoolController, } #: dictionary dict<:data:`~sardana.ElementType`, :class:`tuple`> @@ -94,21 +94,22 @@ #: #. automatic full name #: #. controller class TYPE_MAP = { - ET.Controller : ("Controller", "Controller", CTRL_TYPE_MAP, "controller/{klass}/{name}", Controller), - ET.Instrument : ("Instrument", "Instrument", PoolInstrument, "{full_name}", None), - ET.Motor : ("Motor", "Motor", PoolMotor, "motor/{ctrl_name}/{axis}", MotorController), - ET.CTExpChannel : ("CTExpChannel", "ExpChannel", PoolCounterTimer, "expchan/{ctrl_name}/{axis}", CounterTimerController), - ET.TriggerGate : ("TriggerGate", "TriggerGate", PoolTriggerGate, "triggergate/{ctrl_name}/{axis}", TriggerGateController), - ET.ZeroDExpChannel : ("ZeroDExpChannel", "ExpChannel", Pool0DExpChannel, "expchan/{ctrl_name}/{axis}", ZeroDController), - ET.OneDExpChannel : ("OneDExpChannel", "ExpChannel", Pool1DExpChannel, "expchan/{ctrl_name}/{axis}", OneDController), - ET.TwoDExpChannel : ("TwoDExpChannel", "ExpChannel", Pool2DExpChannel, "expchan/{ctrl_name}/{axis}", TwoDController), - ET.PseudoMotor : ("PseudoMotor", "Motor", PoolPseudoMotor, "pm/{ctrl_name}/{axis}", PseudoMotorController), - ET.PseudoCounter : ("PseudoCounter", "ExpChannel", PoolPseudoCounter, "pc/{ctrl_name}/{axis}", PseudoCounterController), - ET.MotorGroup : ("MotorGroup", "MotorGroup", PoolMotorGroup, "mg/{pool_name}/{name}", None), - ET.MeasurementGroup : ("MeasurementGroup", "MeasurementGroup", PoolMeasurementGroup, "mntgrp/{pool_name}/{name}", None), - ET.IORegister : ("IORegister", "IORegister" , PoolIORegister, "ioregister/{ctrl_name}/{axis}", IORegisterController), + ET.Controller: ("Controller", "Controller", CTRL_TYPE_MAP, "controller/{klass}/{name}", Controller), + ET.Instrument: ("Instrument", "Instrument", PoolInstrument, "{full_name}", None), + ET.Motor: ("Motor", "Motor", PoolMotor, "motor/{ctrl_name}/{axis}", MotorController), + ET.CTExpChannel: ("CTExpChannel", "ExpChannel", PoolCounterTimer, "expchan/{ctrl_name}/{axis}", CounterTimerController), + ET.TriggerGate: ("TriggerGate", "TriggerGate", PoolTriggerGate, "triggergate/{ctrl_name}/{axis}", TriggerGateController), + ET.ZeroDExpChannel: ("ZeroDExpChannel", "ExpChannel", Pool0DExpChannel, "expchan/{ctrl_name}/{axis}", ZeroDController), + ET.OneDExpChannel: ("OneDExpChannel", "ExpChannel", Pool1DExpChannel, "expchan/{ctrl_name}/{axis}", OneDController), + ET.TwoDExpChannel: ("TwoDExpChannel", "ExpChannel", Pool2DExpChannel, "expchan/{ctrl_name}/{axis}", TwoDController), + ET.PseudoMotor: ("PseudoMotor", "Motor", PoolPseudoMotor, "pm/{ctrl_name}/{axis}", PseudoMotorController), + ET.PseudoCounter: ("PseudoCounter", "ExpChannel", PoolPseudoCounter, "pc/{ctrl_name}/{axis}", PseudoCounterController), + ET.MotorGroup: ("MotorGroup", "MotorGroup", PoolMotorGroup, "mg/{pool_name}/{name}", None), + ET.MeasurementGroup: ("MeasurementGroup", "MeasurementGroup", PoolMeasurementGroup, "mntgrp/{pool_name}/{name}", None), + ET.IORegister: ("IORegister", "IORegister", PoolIORegister, "ioregister/{ctrl_name}/{axis}", IORegisterController), } + class TypeData(object): """Information for a specific Element type""" @@ -119,7 +120,7 @@ def __init__(self, **kwargs): #: dict<:data:`~sardana.ElementType`, :class:`~sardana.pool.poolmetacontroller.TypeData`> TYPE_MAP_OBJ = {} for t, d in TYPE_MAP.items(): - o = TypeData(type=t, name=d[0], family=d[1], klass=d[2] , + o = TypeData(type=t, name=d[0], family=d[1], klass=d[2], auto_full_name=d[3], ctrl_klass=d[4]) TYPE_MAP_OBJ[t] = o @@ -213,13 +214,13 @@ def toDataInfo(klass, name, info): maxdimsize=maxdimsize) def toDict(self): - return { 'name' : self.name, 'type' : DataType.whatis(self.dtype), - 'format' : DataFormat.whatis(self.dformat), - 'access' : DataAccess.whatis(self.access), - 'description' : self.description, - 'default_value' : self.default_value, - 'memorized' : self.memorized, - 'maxdimsize' : self.maxdimsize } + return {'name': self.name, 'type': DataType.whatis(self.dtype), + 'format': DataFormat.whatis(self.dformat), + 'access': DataAccess.whatis(self.access), + 'description': self.description, + 'default_value': self.default_value, + 'memorized': self.memorized, + 'maxdimsize': self.maxdimsize} def serialize(self, *args, **kwargs): kwargs.update(self.toDict()) @@ -230,15 +231,15 @@ def __repr__(self): self.__class__.__name__, self.name, DataType[self.dtype], DataFormat[self.dformat], DataAccess[self.access]) -#class PropertyInfo(DataInfo): +# class PropertyInfo(DataInfo): # def __init__(self, name, dtype, dformat=DataFormat.Scalar, # description="", default_value=None): # DataInfo.__init__(self, name, dtype, dformat, access=DataAcces.ReadWrite, -# description=description, default_value=default_value) +# description=description, default_value=default_value) -#class AttributeInfo(DataInfo): +# class AttributeInfo(DataInfo): # def __init__(self, name, dtype, dformat=DataFormat.Scalar, # access=DataAccess.ReadWrite, description=""): @@ -350,5 +351,3 @@ def model(self): @property def organization(self): return self.klass.organization - - diff --git a/src/sardana/pool/poolmonitor.py b/src/sardana/pool/poolmonitor.py index 92bf956880..6549fa03ea 100644 --- a/src/sardana/pool/poolmonitor.py +++ b/src/sardana/pool/poolmonitor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/poolmotion.py b/src/sardana/pool/poolmotion.py index 210675bde4..a34ff2ffe7 100644 --- a/src/sardana/pool/poolmotion.py +++ b/src/sardana/pool/poolmotion.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -39,10 +39,10 @@ from sardana.pool.poolaction import ActionContext, PoolActionItem, PoolAction #: enumeration representing possible motion states -MotionState = Enumeration("MotionSate", (\ +MotionState = Enumeration("MotionSate", ( "Stopped", -# "StoppedOnError", -# "StoppedOnAbort", + # "StoppedOnError", + # "StoppedOnAbort", "Moving", "MovingBacklash", "MovingInstability", @@ -50,9 +50,9 @@ MS = MotionState MovingStates = MS.Moving, MS.MovingBacklash, MS.MovingInstability -StoppedStates = MS.Stopped, #MS.StoppedOnError, MS.StoppedOnAbort +StoppedStates = MS.Stopped, # MS.StoppedOnError, MS.StoppedOnAbort -#MotionAction = Enumeration("MotionAction", ( \ +# MotionAction = Enumeration("MotionAction", ( \ # "StartMotion", # "Finish", # "Abort", @@ -62,11 +62,11 @@ #MA = MotionAction MotionMap = { - #MS.Stopped : State.On, - MS.Moving : State.Moving, - MS.MovingBacklash : State.Moving, - MS.MovingInstability : State.Moving, - MS.Invalid : State.Invalid, + # MS.Stopped : State.On, + MS.Moving: State.Moving, + MS.MovingBacklash: State.Moving, + MS.MovingInstability: State.Moving, + MS.Invalid: State.Invalid, } @@ -165,6 +165,7 @@ def on_state_switch(self, state_info, timestamp=None): _NON_ERROR_STATES = State.On, State.Moving, State.Running + class PoolMotion(PoolAction): """This class manages motion actions""" @@ -206,7 +207,7 @@ def pre_start_one(self, moveables, items): if not ret: try: msg = "%s.PreStartOne(%s(%d), %f) returns False" \ - % (pool_ctrl.name, moveable.name, axis, dial) + % (pool_ctrl.name, moveable.name, axis, dial) raise Exception(msg) except: self._recover_start_error(pool_ctrl, "PreStartOne") @@ -300,7 +301,7 @@ def action_loop(self): emergency_stop = set() # read positions to send a first event when starting to move - #with ActionContext(self) as context: + # with ActionContext(self) as context: # positions = self.raw_read_dial_position() # position_error_occured = self._position_error_occured(positions) # if position_error_occured: @@ -382,14 +383,14 @@ def action_loop(self): # try to read a last position to force an event moveable.get_position(cache=False, propagate=2) - ## free the motor from the OperationContext so we can send - ## a state event. Otherwise we may be asked to move the - ## motor again which would result in an exception saying - ## that the motor is already involved in an operation - ## ... but before protect the motor so that the monitor - ## doesn't come in between the two instructions below and - ## send a state event on it's own - #with moveable: + # free the motor from the OperationContext so we can send + # a state event. Otherwise we may be asked to move the + # motor again which would result in an exception saying + # that the motor is already involved in an operation + # ... but before protect the motor so that the monitor + # doesn't come in between the two instructions below and + # send a state event on it's own + # with moveable: # moveable.clear_operation() moveable.set_state_info(real_state_info, propagate=2) @@ -407,12 +408,14 @@ def action_loop(self): # send positions self.read_dial_position(ret=positions) - position_error_occured = self._position_error_occured(positions) + position_error_occured = self._position_error_occured( + positions) if position_error_occured: self.error("Loop final read position error. " "Retrying...") self.read_dial_position(ret=positions) - position_error_occured = self._position_error_occured(positions) + position_error_occured = self._position_error_occured( + positions) if position_error_occured: self.error("Loop final read position error 2. " "Cannot send final position event!!!") @@ -437,7 +440,8 @@ def action_loop(self): # send position for moveable, position_value in positions.items(): if position_value.error: - self.error("Loop read position error for %s" % moveable.name) + self.error("Loop read position error for %s" % + moveable.name) moveable.put_dial_position(position_value) i += 1 time.sleep(nap) diff --git a/src/sardana/pool/poolmotor.py b/src/sardana/pool/poolmotor.py index a99aa90f6a..676e930f61 100644 --- a/src/sardana/pool/poolmotor.py +++ b/src/sardana/pool/poolmotor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -99,12 +99,12 @@ def calc_position(self, dial=None): """Returns the computed position from last the dial position from the given parameter or (if None), the last dial position obtained from hardware read. - + :param dial: the new dial position [default: None, meaning use the current dial position. :return: the computed user position :rtype: obj - + :raises: :exc:`Exception` if dial_position is None and no read value has been set yet""" @@ -122,7 +122,7 @@ def calc_position(self, dial=None): def calc_dial_position(self, position=None): """Returns the dial position for the given position. If position is not given (or is None) it uses this object's *write* value. - + :param position: the position to be converted to dial [default: None meaning use the this attribute's *write* value @@ -274,6 +274,7 @@ def _set_state_info(self, state_info, propagate=1): # -------------------------------------------------------------------------- _STD_STATUS = "{name} is {state}{limit_switches}{ctrl_status}" + def calculate_state_info(self, state_info=None): if state_info is None: state = self._state @@ -392,7 +393,8 @@ def get_backlash(self, cache=True): def set_backlash(self, backlash, propagate=1): self._backlash = backlash if propagate > 0: - self.fire_event(EventType("backlash", priority=propagate), backlash) + self.fire_event( + EventType("backlash", priority=propagate), backlash) backlash = property(get_backlash, set_backlash, doc="motor backlash") @@ -424,7 +426,8 @@ def get_sign(self, cache=True): def set_sign(self, sign, propagate=1): old_sign = self._sign.value self._sign.set_value(sign, propagate=propagate) - # invert lower with upper limit switches and send event in case of change + # invert lower with upper limit switches and send event in case of + # change ls = self._limit_switches if old_sign != sign and ls.has_value(): value = ls.value @@ -452,12 +455,14 @@ def set_step_per_unit(self, step_per_unit, propagate=1): def _set_step_per_unit(self, step_per_unit, propagate=1): self._step_per_unit = step_per_unit if propagate: - self.fire_event(EventType("step_per_unit", priority=propagate), step_per_unit) + self.fire_event(EventType("step_per_unit", + priority=propagate), step_per_unit) # force ask controller for new position to send priority event self.get_position(cache=False, propagate=2) def read_step_per_unit(self): - step_per_unit = self.controller.get_axis_par(self.axis, "step_per_unit") + step_per_unit = self.controller.get_axis_par( + self.axis, "step_per_unit") assert_type(float, step_per_unit) return step_per_unit @@ -482,7 +487,8 @@ def _set_acceleration(self, acceleration, propagate=1): self._acceleration = acceleration if not propagate: return - self.fire_event(EventType("acceleration", priority=propagate), acceleration) + self.fire_event( + EventType("acceleration", priority=propagate), acceleration) def read_acceleration(self): acceleration = self.controller.get_axis_par(self.axis, "acceleration") @@ -510,7 +516,8 @@ def _set_deceleration(self, deceleration, propagate=1): self._deceleration = deceleration if not propagate: return - self.fire_event(EventType("deceleration", priority=propagate), deceleration) + self.fire_event( + EventType("deceleration", priority=propagate), deceleration) def read_deceleration(self): deceleration = self.controller.get_axis_par(self.axis, "deceleration") @@ -587,7 +594,7 @@ def define_position(self, position): def get_position_attribute(self): """Returns the position attribute object for this motor - + :return: the position attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._position @@ -662,7 +669,7 @@ def put_dial_position(self, dial_position_value, propagate=1): def get_dial_position_attribute(self): """Returns the dial position attribute object for this motor - + :return: the dial position attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._dial_position @@ -777,7 +784,8 @@ def _start_move(self, new_position): timestamp = time.time() # update the write position - self.set_write_position(items[self][0], timestamp=timestamp, propagate=0) + self.set_write_position( + items[self][0], timestamp=timestamp, propagate=0) # move! self.motion.run(items=items) diff --git a/src/sardana/pool/poolmotorgroup.py b/src/sardana/pool/poolmotorgroup.py index d845d986fc..b7e1f003d4 100644 --- a/src/sardana/pool/poolmotorgroup.py +++ b/src/sardana/pool/poolmotorgroup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -71,16 +71,17 @@ def _get_exc_info(self): return position_attr.get_exc_info() def _get_timestamp(self): - return max([ pos_attr.timestamp for pos_attr in self.obj.get_physical_position_attribute_iterator() ]) + return max([pos_attr.timestamp for pos_attr in self.obj.get_physical_position_attribute_iterator()]) def _set_value(self, value, exc_info=None, timestamp=None, propagate=1): - raise Exception("Cannot set position value for motor group %s" % self.obj.name) + raise Exception( + "Cannot set position value for motor group %s" % self.obj.name) def _get_value(self): - return [ position.value for position in self.obj.get_physical_position_attribute_iterator() ] + return [position.value for position in self.obj.get_physical_position_attribute_iterator()] def _get_write_value(self): - return [ position.w_value for position in self.obj.get_physical_position_attribute_iterator() ] + return [position.w_value for position in self.obj.get_physical_position_attribute_iterator()] def _set_write_value(self, w_value, timestamp=None, propagate=1): assert len(w_value) == self.get_element_nb() @@ -107,9 +108,11 @@ def update(self, cache=True, propagate=1): cache = False break if not cache: - dial_position_values = self.obj.motion.read_dial_position(serial=True) + dial_position_values = self.obj.motion.read_dial_position( + serial=True) for motion_obj, position_value in dial_position_values.items(): - motion_obj.put_dial_position(position_value, propagate=propagate) + motion_obj.put_dial_position( + position_value, propagate=propagate) class PoolMotorGroup(PoolGroupElement): @@ -150,7 +153,7 @@ def add_user_element(self, element, index=None): if elem_type == ElementType.Motor: pass elif elem_type == ElementType.PseudoMotor: - #TODO: make this happen + # TODO: make this happen pass else: raise Exception("element %s is not a motor" % element.name) @@ -218,7 +221,8 @@ def set_write_position(self, w_position, timestamp=None, propagate=1): self._position.set_write_value(w_position, timestamp=timestamp, propagate=propagate) - position = property(get_position, set_position, doc="motor group positions") + position = property(get_position, set_position, + doc="motor group positions") # -------------------------------------------------------------------------- # default acquisition channel diff --git a/src/sardana/pool/poolmoveable.py b/src/sardana/pool/poolmoveable.py index a05bce6f96..5de2efc98e 100644 --- a/src/sardana/pool/poolmoveable.py +++ b/src/sardana/pool/poolmoveable.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/poolobject.py b/src/sardana/pool/poolobject.py index 3e4c8e2f9f..8b6affacd7 100644 --- a/src/sardana/pool/poolobject.py +++ b/src/sardana/pool/poolobject.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/poolonedexpchannel.py b/src/sardana/pool/poolonedexpchannel.py index 63d93c7213..b40c53e625 100644 --- a/src/sardana/pool/poolonedexpchannel.py +++ b/src/sardana/pool/poolonedexpchannel.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/poolpseudocounter.py b/src/sardana/pool/poolpseudocounter.py index 7c8aad4d7a..394bb52cb0 100644 --- a/src/sardana/pool/poolpseudocounter.py +++ b/src/sardana/pool/poolpseudocounter.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -85,7 +85,8 @@ def _get_exc_info(self): return exc_info def _get_timestamp(self): - timestamps = [ value_attr.timestamp for value_attr in self.obj.get_physical_value_attribute_iterator() ] + timestamps = [ + value_attr.timestamp for value_attr in self.obj.get_physical_value_attribute_iterator()] if not len(timestamps): timestamps = self._local_timestamp, return max(timestamps) @@ -129,7 +130,7 @@ def calc(self, physical_values=None): else: l_v, l_u = len(physical_values), len(obj.get_user_elements()) if l_v != l_u: - raise IndexError("CalcPseudo(%s): must give %d physical " \ + raise IndexError("CalcPseudo(%s): must give %d physical " "values (you gave %d)" % (obj.name, l_u, l_v)) ctrl, axis = obj.controller, obj.axis result = ctrl.calc(axis, physical_values) @@ -151,7 +152,7 @@ def calc_all(self, physical_values=None): else: l_v, l_u = len(physical_values), len(obj.get_user_elements()) if l_v != l_u: - raise IndexError("CalcAllPseudo(%s): must give %d physical " \ + raise IndexError("CalcAllPseudo(%s): must give %d physical " "values (you gave %d)" % (obj.name, l_u, l_v)) ctrl, axis = obj.controller, obj.axis result = ctrl.calc_all(axis, physical_values) @@ -197,7 +198,7 @@ def __init__(self, **kwargs): def serialize(self, *args, **kwargs): kwargs = PoolBaseChannel.serialize(self, *args, **kwargs) - elements = [ elem.name for elem in self.get_user_elements() ] + elements = [elem.name for elem in self.get_user_elements()] physical_elements = [] for elem_list in self.get_physical_elements().values(): for elem in elem_list: @@ -287,7 +288,7 @@ def get_physical_values(self, cache=True, propagate=1): def get_siblings_values(self, use=None): """Get the last values for all siblings. - + :param use: the already calculated values. If a sibling is in this dictionary, the value stored here is used instead :type use: dict @@ -306,7 +307,7 @@ def get_siblings_values(self, use=None): def get_value(self, cache=True, propagate=1): """Returns the pseudo counter value. - + :param cache: if ``True`` (default) return value in cache, otherwise read value from hardware @@ -334,6 +335,7 @@ def set_value(self, value, propagate=1): # -------------------------------------------------------------------------- _STD_STATUS = "{name} is {state}\n{ctrl_status}" + def calculate_state_info(self, status_info=None): if status_info is None: status_info = self._state, self._status @@ -361,4 +363,3 @@ def read_state_info(self, state_info=None): ret = self._calculate_states() return ret - diff --git a/src/sardana/pool/poolpseudomotor.py b/src/sardana/pool/poolpseudomotor.py index d22b5c4a1e..e6638875c2 100644 --- a/src/sardana/pool/poolpseudomotor.py +++ b/src/sardana/pool/poolpseudomotor.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -59,7 +59,8 @@ def __init__(self, *args, **kwargs): # The pool will not be able to start if we create a third slit with s3g,s3o = f(s1g, s2g) # self.obj.get_physical_position_attribute_iterator() raises a KeyError exception # so we will flag the Position object as no_listeners for later configuration - # We should still investigate the root of the problem when ordering the creation of elements + # We should still investigate the root of the problem when ordering the + # creation of elements self._listeners_configured = False try: for position_attr in self.obj.get_physical_position_attribute_iterator(): @@ -97,7 +98,8 @@ def _get_write_value(self): return self.calc_pseudo(physical_positions=w_positions).value def _set_write_value(self, w_value, timestamp=None, propagate=1): - raise Exception("Cannot set position write value for %s" % self.obj.name) + raise Exception("Cannot set position write value for %s" % + self.obj.name) def _get_exc_info(self): exc_info = self._exc_info @@ -108,7 +110,8 @@ def _get_exc_info(self): return exc_info def _get_timestamp(self): - timestamps = [ pos_attr.timestamp for pos_attr in self.obj.get_physical_position_attribute_iterator() ] + timestamps = [ + pos_attr.timestamp for pos_attr in self.obj.get_physical_position_attribute_iterator()] if not len(timestamps): timestamps = self._local_timestamp, return max(timestamps) @@ -149,11 +152,13 @@ def calc_pseudo(self, physical_positions=None): if physical_positions is None: physical_positions = self.get_physical_positions() else: - l_p, l_u = len(physical_positions), len(obj.get_user_elements()) + l_p, l_u = len(physical_positions), len( + obj.get_user_elements()) if l_p != l_u: - raise IndexError("CalcPseudo(%s): must give %d physical " \ + raise IndexError("CalcPseudo(%s): must give %d physical " "positions (you gave %d)" % (obj.name, l_u, l_p)) - result = obj.controller.calc_pseudo(obj.axis, physical_positions, None) + result = obj.controller.calc_pseudo( + obj.axis, physical_positions, None) except SardanaException as se: result = SardanaValue(exc_info=se.exc_info) except: @@ -166,9 +171,10 @@ def calc_all_pseudo(self, physical_positions=None): if physical_positions is None: physical_positions = self.get_physical_positions() else: - l_p, l_u = len(physical_positions), len(obj.get_user_elements()) + l_p, l_u = len(physical_positions), len( + obj.get_user_elements()) if l_p != l_u: - raise IndexError("CalcAllPseudo():: must give %d physical " \ + raise IndexError("CalcAllPseudo():: must give %d physical " "positions (you gave %d)" % (l_u, l_p)) result = obj.controller.calc_all_pseudo(physical_positions, None) except SardanaException as se: @@ -208,11 +214,13 @@ def update(self, cache=True, propagate=1): cache = False break if not cache: - dial_position_values = self.obj.motion.read_dial_position(serial=True) + dial_position_values = self.obj.motion.read_dial_position( + serial=True) if not len(dial_position_values): self._local_timestamp = time.time() for motion_obj, position_value in dial_position_values.items(): - motion_obj.put_dial_position(position_value, propagate=propagate) + motion_obj.put_dial_position( + position_value, propagate=propagate) class PoolPseudoMotor(PoolBaseGroup, PoolElement): @@ -239,7 +247,7 @@ def on_change(self, evt_src, evt_type, evt_value): def serialize(self, *args, **kwargs): kwargs = PoolElement.serialize(self, *args, **kwargs) - elements = [ elem.name for elem in self.get_user_elements() ] + elements = [elem.name for elem in self.get_user_elements()] physical_elements = [] for elem_list in self.get_physical_elements().values(): for elem in elem_list: @@ -304,7 +312,7 @@ def add_user_element(self, element, index=None): if elem_type == ElementType.Motor: pass elif elem_type == ElementType.PseudoMotor: - #TODO: make this happen + # TODO: make this happen pass else: raise Exception("element %s is not a motor" % element.name) @@ -363,7 +371,7 @@ def get_siblings_positions(self, use=None, write_pos=True): If write_pos is True and a sibling has already been moved before, it's last write position is used. Otherwise its read position is used instead. - + :param use: the already calculated positions. If a sibling is in this dictionary, the position stored here is used instead :type use: dict @@ -436,13 +444,15 @@ def set_write_position(self, w_position, timestamp=None, propagate=1): self._position.set_write_value(w_position, timestamp=timestamp, propagate=propagate) - position = property(get_position, set_position, doc="pseudo motor position") + position = property(get_position, set_position, + doc="pseudo motor position") # ------------------------------------------------------------------------ # state information # ------------------------------------------------------------------------ _STD_STATUS = "{name} is {state}\n{ctrl_status}" + def calculate_state_info(self, status_info=None): # Refer to Position.__init__ method for an explanation on this 'hack' @@ -534,7 +544,7 @@ def calculate_motion(self, new_position, items=None, calculated=None): for new_position, element in zip(physical_positions.value, user_elements): if new_position is None: raise PoolException("Cannot calculate motion: %s reports " - "position to be None" % element.name) + "position to be None" % element.name) element.calculate_motion(new_position, items=items, calculated=calculated) return items @@ -562,7 +572,7 @@ def _start_move(self, new_position): # ------------------------------------------------------------------------ def stop(self): - #surpass the PoolElement.stop because it doesn't do what we want + # surpass the PoolElement.stop because it doesn't do what we want PoolBaseElement.stop(self) PoolBaseGroup.stop(self) @@ -571,7 +581,7 @@ def stop(self): # ------------------------------------------------------------------------ def abort(self): - #surpass the PoolElement.abort because it doesn't do what we want + # surpass the PoolElement.abort because it doesn't do what we want PoolBaseElement.abort(self) PoolBaseGroup.abort(self) diff --git a/src/sardana/pool/poolsynchronization.py b/src/sardana/pool/poolsynchronization.py index 0ce3a4cc49..84d36bbee8 100644 --- a/src/sardana/pool/poolsynchronization.py +++ b/src/sardana/pool/poolsynchronization.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -38,6 +38,8 @@ from sardana.util.funcgenerator import FunctionGenerator # The purpose of this class was inspired on the CTAcquisition concept + + class TGChannel(PoolActionItem): """An item involved in the trigger/gate generation. Maps directly to a trigger object @@ -61,6 +63,7 @@ def __getattr__(self, name): class PoolSynchronization(PoolAction): '''Action class responsible for trigger/gate generation ''' + def __init__(self, main_element, name="Synchronization"): PoolAction.__init__(self, main_element, name) self._synch_soft = FunctionGenerator() @@ -121,9 +124,10 @@ def start_action(self, *args, **kwargs): remove_acq_listener = partial(self._synch_soft.remove_listener, self._listener) self.add_finish_hook(remove_acq_listener, False) - self._synch_soft.add_listener(self.main_element.on_element_changed) + self._synch_soft.add_listener( + self.main_element.on_element_changed) remove_mg_listener = partial(self._synch_soft.remove_listener, - self.main_element) + self.main_element) self.add_finish_hook(remove_mg_listener, False) # subscribing to the position change events to generate events # in position domain @@ -148,7 +152,7 @@ def start_action(self, *args, **kwargs): channel = channels[element] ret = ctrl.PreStartOne(axis) if not ret: - raise Exception("%s.PreStartOne(%d) returns False" \ + raise Exception("%s.PreStartOne(%d) returns False" % (pool_ctrl.name, axis)) ctrl.StartOne(axis) @@ -206,10 +210,9 @@ def action_loop(self): state_info = triggerelement._from_ctrl_state_info(state_info) triggerelement.set_state_info(state_info, propagate=2) - # wait for software synchronizer to finish + # wait for software synchronizer to finish if self._listener is not None: while True: if not self._synch_soft.is_started(): break time.sleep(0.01) - diff --git a/src/sardana/pool/pooltriggergate.py b/src/sardana/pool/pooltriggergate.py index 81650e6f18..9e0b81aa98 100644 --- a/src/sardana/pool/pooltriggergate.py +++ b/src/sardana/pool/pooltriggergate.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -36,6 +36,7 @@ from sardana.sardanaattribute import SardanaAttribute from sardana.pool.poolsynchronization import PoolSynchronization + class Index(SardanaAttribute): """ Index of the trigger/gate event being currently generated. @@ -49,6 +50,7 @@ class Index(SardanaAttribute): def __init__(self, *args, **kwargs): super(Index, self).__init__(*args, **kwargs) + class PoolTriggerGate(PoolElement): def __init__(self, **kwargs): diff --git a/src/sardana/pool/pooltwodexpchannel.py b/src/sardana/pool/pooltwodexpchannel.py index 59e6d39072..416f20f593 100644 --- a/src/sardana/pool/pooltwodexpchannel.py +++ b/src/sardana/pool/pooltwodexpchannel.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -57,10 +57,12 @@ def _set_data_source(self, data_source, propagate=1): self._data_source = data_source if not propagate: return - self.fire_event(EventType("data_source", priority=propagate), data_source) + self.fire_event( + EventType("data_source", priority=propagate), data_source) def read_data_source(self): data_source = self.controller.get_axis_par(self.axis, "data_source") return data_source - data_source = property(get_data_source, doc="source identifier for the 2D data") + data_source = property( + get_data_source, doc="source identifier for the 2D data") diff --git a/src/sardana/pool/poolutil.py b/src/sardana/pool/poolutil.py index 3415116740..9064388d06 100644 --- a/src/sardana/pool/poolutil.py +++ b/src/sardana/pool/poolutil.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/poolzerodexpchannel.py b/src/sardana/pool/poolzerodexpchannel.py index e0f5eb9fea..943aaca100 100644 --- a/src/sardana/pool/poolzerodexpchannel.py +++ b/src/sardana/pool/poolzerodexpchannel.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -141,7 +141,8 @@ class Value(SardanaAttribute): DefaultAccumulationType = "Average" def __init__(self, *args, **kwargs): - accumulation_type = kwargs.pop('accumulation_type', self.DefaultAccumulationType) + accumulation_type = kwargs.pop( + 'accumulation_type', self.DefaultAccumulationType) super(Value, self).__init__(*args, **kwargs) self.set_accumulation_type(accumulation_type) # member to store the acquisition index @@ -162,7 +163,7 @@ def get_accumulation(self): return self._accumulation accumulation = property(get_accumulation) - + def _get_value(self): value = self._accumulation.value if value is None: @@ -175,9 +176,10 @@ def _get_value_obj(self): the present values. ''' value = self._accumulation.value - # use timestamp of the last acquired sample as timestamp of accumulation + # use timestamp of the last acquired sample as timestamp of + # accumulation timestamp = self._accumulation.get_time_buffer()[-1] - idx = self._index + idx = self._index value_obj = SardanaValue(value=value, idx=idx, timestamp=timestamp) return value_obj @@ -219,7 +221,8 @@ def propagate(self, priority=1): def update(self, cache=True, propagate=1): # it is the Pool0DAcquisition action which is allowed to update raise Exception("0D Value can not be updated from outside" - " of acquisition") + " of acquisition") + class Pool0DExpChannel(PoolBaseChannel): @@ -252,14 +255,14 @@ def set_accumulation_type(self, ctype): def get_accumulated_value_attribute(self): """Returns the accumulated value attribute object for this 0D. - + :return: the accumulated value attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self.get_value_attribute() def get_current_value_attribute(self): """Returns the current value attribute object for this 0D. - + :return: the current value attribute :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute`""" return self._current_value @@ -272,7 +275,7 @@ def get_accumulated_value(self): value :rtype: :class:`~sardana.sardanaattribute.SardanaAttribute` - + :raises: Exception if no acquisition has been done yet on this 0D""" return self.get_accumulated_value_attribute() @@ -332,7 +335,8 @@ def append_value(self, value, timestamp=None, propagate=1): cumulation.append_value(value, timestamp) if not propagate: return - self.fire_event(EventType("value", priority=propagate), cumulation.value) + self.fire_event(EventType("value", priority=propagate), + cumulation.value) def propagate_value(self, priority=2): '''Propagate value attribute to its listeners. @@ -365,6 +369,7 @@ def start_acquisition(self, value=None): self._aborted = False self.clear_buffer() if value is None: - raise Exception("Invalid integration_time '%s'. Hint set a new value for 'value' first" % value) + raise Exception( + "Invalid integration_time '%s'. Hint set a new value for 'value' first" % value) if not self._simulation_mode: acq = self.acquisition.run() diff --git a/src/sardana/pool/test/__init__.py b/src/sardana/pool/test/__init__.py index ef857a5d39..e6455c68c2 100644 --- a/src/sardana/pool/test/__init__.py +++ b/src/sardana/pool/test/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/pool/test/base.py b/src/sardana/pool/test/base.py index 9d54a6feec..1ba5ecbd75 100644 --- a/src/sardana/pool/test/base.py +++ b/src/sardana/pool/test/base.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,6 +29,7 @@ createPoolZeroDExpChannel) import logging + class BasePoolTestCase(object): """Base pool test for setting the environment.""" POOLPATH = [] @@ -90,8 +91,8 @@ def setUp(self): for ctrl in range(1, self.nctctrls + 1): name = '_test_ct_ctrl_%s' % ctrl ctrl_obj = self.createController(name, - 'DummyCounterTimerController', - 'DummyCounterTimerController.py') + 'DummyCounterTimerController', + 'DummyCounterTimerController.py') # Create nelems CT elements for each ctrl for axis in range(1, self.nctelems + 1): name = '_test_ct_%s_%s' % (ctrl, axis) @@ -100,8 +101,8 @@ def setUp(self): for ctrl in range(1, self.nzerodctrls + 1): name = '_test_0d_ctrl_%s' % ctrl ctrl_obj = self.createController(name, - 'DummyZeroDController', - 'DummyZeroDController.py') + 'DummyZeroDController', + 'DummyZeroDController.py') # Create nelems ZeroD elements for each ctrl for axis in range(1, self.nzerodelems + 1): name = '_test_0d_%s_%s' % (ctrl, axis) @@ -110,8 +111,8 @@ def setUp(self): for ctrl in range(1, self.ntgctrls + 1): name = '_test_tg_ctrl_%s' % ctrl ctrl_obj = self.createController(name, - 'DummyTriggerGateController', - 'DummyTriggerGateController.py') + 'DummyTriggerGateController', + 'DummyTriggerGateController.py') # Create nelems CT elements for each ctrl for axis in range(1, self.ntgelems + 1): name = '_test_tg_%s_%s' % (ctrl, axis) @@ -120,8 +121,8 @@ def setUp(self): for ctrl in range(1, self.nctctrls + 1): name = '_test_mot_ctrl_%s' % ctrl ctrl_obj = self.createController(name, - 'DummyMotorController', - 'DummyMotorController.py') + 'DummyMotorController', + 'DummyMotorController.py') # Create nelems CT elements for each ctrl for axis in range(1, self.nctelems + 1): name = '_test_mot_%s_%s' % (ctrl, axis) diff --git a/src/sardana/pool/test/dummyconfs.py b/src/sardana/pool/test/dummyconfs.py index c9652c6489..bccea9d5fd 100644 --- a/src/sardana/pool/test/dummyconfs.py +++ b/src/sardana/pool/test/dummyconfs.py @@ -2,32 +2,32 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## __all__ = ['dummyMeasurementGroupConf01', - 'dummyPoolCTCtrlConf01', 'dummyPoolCTCtrlConf02', + 'dummyPoolCTCtrlConf01', 'dummyPoolCTCtrlConf02', 'TangoAttributeCTCtrlConf01', 'TangoAttributeCTCtrlConf02', 'dummyPoolTGCtrlConf01', 'dummyPoolTGCtrlConf02', - 'dummyCounterTimerConf01', 'dummyCounterTimerConf02', + 'dummyCounterTimerConf01', 'dummyCounterTimerConf02', 'dummyCounterTimerConf03', 'dummyCounterTimerConf04', 'dummyTriggerGateConf01', 'dummyTriggerGateConf02', 'dummyTriggerGateConf03', 'dummyTriggerGateConf04', @@ -36,172 +36,171 @@ # Pool Measuremeng Group '''Minimum configuration to create a Pool MeasurementGroup''' -dummyMeasurementGroupConf01 = { 'full_name': '', - 'id': None, - 'name': '', - 'pool': None, - 'user_elements': [2] } +dummyMeasurementGroupConf01 = {'full_name': '', + 'id': None, + 'name': '', + 'pool': None, + 'user_elements': [2]} # Pool Ctrls '''Minimum configuration to create a Pool CounterTimer controller''' -dummyPoolCTCtrlConf01 = { 'class_info': None, - 'full_name': '', - 'id': 1, - 'klass': 'DummyCounterTimerController', - 'lib_info': None, - 'library': 'DummyCounterTimerController.py', - 'name': '', - 'pool': None, - 'properties': {}, - 'role_ids': '', - 'type': 'CTExpChannel'} +dummyPoolCTCtrlConf01 = {'class_info': None, + 'full_name': '', + 'id': 1, + 'klass': 'DummyCounterTimerController', + 'lib_info': None, + 'library': 'DummyCounterTimerController.py', + 'name': '', + 'pool': None, + 'properties': {}, + 'role_ids': '', + 'type': 'CTExpChannel'} '''Second minimum configuration to create a Pool CounterTimer controller''' -dummyPoolCTCtrlConf02 = { 'class_info': None, - 'full_name': '', - 'id': 2, - 'klass': 'DummyCounterTimerController', - 'lib_info': None, - 'library': 'DummyCounterTimerController.py', - 'name': '', - 'pool': None, - 'properties': {}, - 'role_ids': '', - 'type': 'CTExpChannel'} +dummyPoolCTCtrlConf02 = {'class_info': None, + 'full_name': '', + 'id': 2, + 'klass': 'DummyCounterTimerController', + 'lib_info': None, + 'library': 'DummyCounterTimerController.py', + 'name': '', + 'pool': None, + 'properties': {}, + 'role_ids': '', + 'type': 'CTExpChannel'} '''Minimum configuration to create a TangoAttributeCTcontroller''' TangoAttributeCTCtrlConf01 = {'class_info': None, - 'ctrl_info': '', - 'full_name': '', - 'id': 1, - 'klass': 'TangoAttrCTController', - 'lib_info': None, - #'library': 'TangoAttrCTCtrl.py', - 'library': 'TangoAttrCounterTimerController.py', - 'name': '', - 'pool': None, - 'properties': {}, - 'role_ids': '', - 'type': 'CTExpChannel' } + 'ctrl_info': '', + 'full_name': '', + 'id': 1, + 'klass': 'TangoAttrCTController', + 'lib_info': None, + #'library': 'TangoAttrCTCtrl.py', + 'library': 'TangoAttrCounterTimerController.py', + 'name': '', + 'pool': None, + 'properties': {}, + 'role_ids': '', + 'type': 'CTExpChannel'} '''Second minimum configuration to create a TangoAttributeCTcontroller''' TangoAttributeCTCtrlConf02 = {'class_info': None, - 'ctrl_info': '', - 'full_name': '', - 'id': 2, - 'klass': 'TangoAttrCTController', - 'lib_info': None, - #'library': 'TangoAttrCTCtrl.py', - 'library': 'TangoAttrCounterTimerController.py', - 'name': '', - 'pool': None, - 'properties': {}, - 'role_ids': '', - 'type': 'CTExpChannel' } + 'ctrl_info': '', + 'full_name': '', + 'id': 2, + 'klass': 'TangoAttrCTController', + 'lib_info': None, + #'library': 'TangoAttrCTCtrl.py', + 'library': 'TangoAttrCounterTimerController.py', + 'name': '', + 'pool': None, + 'properties': {}, + 'role_ids': '', + 'type': 'CTExpChannel'} '''Minimum configuration to create a Pool TriggerGate controller''' -dummyPoolTGCtrlConf01 = { 'class_info': None, - 'full_name': '', - 'id': 1, - 'klass': 'DummyTriggerGateController', - 'lib_info': None, - 'library': 'DummyTriggerGateController.py', - 'name': '', - 'pool': None, - 'properties': {}, - 'role_ids': '', - 'type': 'TGChannel' } +dummyPoolTGCtrlConf01 = {'class_info': None, + 'full_name': '', + 'id': 1, + 'klass': 'DummyTriggerGateController', + 'lib_info': None, + 'library': 'DummyTriggerGateController.py', + 'name': '', + 'pool': None, + 'properties': {}, + 'role_ids': '', + 'type': 'TGChannel'} '''Minimum configuration to create a Pool Software TriggerGate controller''' -softwarePoolTGCtrlConf01 = { 'class_info': None, - 'full_name': '', - 'id': 1, - 'klass': 'SoftwareTriggerGateController', - 'lib_info': None, - 'library': 'SoftwareTriggerGateController.py', - 'name': '', - 'pool': None, - 'properties': {}, - 'role_ids': '', - 'type': 'TGChannel' } +softwarePoolTGCtrlConf01 = {'class_info': None, + 'full_name': '', + 'id': 1, + 'klass': 'SoftwareTriggerGateController', + 'lib_info': None, + 'library': 'SoftwareTriggerGateController.py', + 'name': '', + 'pool': None, + 'properties': {}, + 'role_ids': '', + 'type': 'TGChannel'} '''Minimum configuration to create a Pool TriggerGate controller''' -dummyPoolTGCtrlConf02 = { 'class_info': None, - 'full_name': '', - 'id': 2, - 'klass': 'DummyTriggerGateController', - 'lib_info': None, - 'library': 'DummyTriggerGateController.py', - 'name': '', - 'pool': None, - 'properties': {}, - 'role_ids': '', - 'type': 'TGChannel' } +dummyPoolTGCtrlConf02 = {'class_info': None, + 'full_name': '', + 'id': 2, + 'klass': 'DummyTriggerGateController', + 'lib_info': None, + 'library': 'DummyTriggerGateController.py', + 'name': '', + 'pool': None, + 'properties': {}, + 'role_ids': '', + 'type': 'TGChannel'} # Pool Elements '''Minimum configuration to create a Pool CounterTimer''' -dummyCounterTimerConf01 = { 'axis': 1, - 'ctrl': None, - 'full_name': '', - 'id': 2, - 'name': '', - 'pool': None } +dummyCounterTimerConf01 = {'axis': 1, + 'ctrl': None, + 'full_name': '', + 'id': 2, + 'name': '', + 'pool': None} '''Second minimum configuration to create a Pool CounterTimer''' -dummyCounterTimerConf02 = { 'axis': 2, - 'ctrl': None, - 'full_name': '', - 'id': 3, - 'name': '', - 'pool': None } +dummyCounterTimerConf02 = {'axis': 2, + 'ctrl': None, + 'full_name': '', + 'id': 3, + 'name': '', + 'pool': None} '''Third minimum configuration to create a Pool CounterTimer''' -dummyCounterTimerConf03 = { 'axis': 1, - 'ctrl': None, - 'full_name': '', - 'id': 2, - 'name': '', - 'pool': None } +dummyCounterTimerConf03 = {'axis': 1, + 'ctrl': None, + 'full_name': '', + 'id': 2, + 'name': '', + 'pool': None} '''Fourth minimum configuration to create a Pool CounterTimer''' -dummyCounterTimerConf04 = { 'axis': 2, - 'ctrl': None, - 'full_name': '', - 'id': 3, - 'name': '', - 'pool': None } +dummyCounterTimerConf04 = {'axis': 2, + 'ctrl': None, + 'full_name': '', + 'id': 3, + 'name': '', + 'pool': None} '''Minimum configuration to create a Pool TriggerGate''' -dummyTriggerGateConf01 = { 'axis': 1, - 'ctrl': None, - 'full_name': '', - 'id': 2, - 'name': '', - 'pool': None } +dummyTriggerGateConf01 = {'axis': 1, + 'ctrl': None, + 'full_name': '', + 'id': 2, + 'name': '', + 'pool': None} '''Second minimum configuration to create a Pool TriggerGate''' -dummyTriggerGateConf02 = { 'axis': 2, - 'ctrl': None, - 'full_name': '', - 'id': 3, - 'name': '', - 'pool': None } +dummyTriggerGateConf02 = {'axis': 2, + 'ctrl': None, + 'full_name': '', + 'id': 3, + 'name': '', + 'pool': None} '''Third minimum configuration to create a Pool TriggerGate''' -dummyTriggerGateConf03 = { 'axis': 3, - 'ctrl': None, - 'full_name': '', - 'id': 4, - 'name': '', - 'pool': None } +dummyTriggerGateConf03 = {'axis': 3, + 'ctrl': None, + 'full_name': '', + 'id': 4, + 'name': '', + 'pool': None} '''Fourth minimum configuration to create a Pool TriggerGate''' -dummyTriggerGateConf04 = { 'axis': 4, - 'ctrl': None, - 'full_name': '', - 'id': 5, - 'name': '', - 'pool': None } - +dummyTriggerGateConf04 = {'axis': 4, + 'ctrl': None, + 'full_name': '', + 'id': 5, + 'name': '', + 'pool': None} diff --git a/src/sardana/pool/test/fake.py b/src/sardana/pool/test/fake.py index 73be8058f9..8f0e49c481 100755 --- a/src/sardana/pool/test/fake.py +++ b/src/sardana/pool/test/fake.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -27,6 +27,7 @@ from sardana.pool.poolcontrollermanager import ControllerManager + class FakePool(object): ''' Fake class to simulate the behavior of the Pool class ''' @@ -51,7 +52,7 @@ def add_element(self, element): def get_element(self, id): return self.elements[id] - + def get_element_by_full_name(self, full_name): return self.elements_by_full_name[full_name] @@ -67,10 +68,10 @@ def get_free_name(self, base_name): num = 1 while True: try: - self.get_element_by_full_name(base_name+"%s" % num) + self.get_element_by_full_name(base_name + "%s" % num) num += 1 except KeyError: - return base_name+"%s" % num + return base_name + "%s" % num def get_manager(self): return self.ctrl_manager @@ -82,8 +83,11 @@ def cleanup(self): self.elements_by_full_name = {} # TODO: this should be a mock + + class FakeElement(object): '''Fake pool element''' + def __init__(self, pool): self.pool = pool diff --git a/src/sardana/pool/test/helper.py b/src/sardana/pool/test/helper.py index 5301c0b1a4..b86ec3257c 100644 --- a/src/sardana/pool/test/helper.py +++ b/src/sardana/pool/test/helper.py @@ -2,33 +2,33 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## __all__ = ['createPoolController', 'createPoolCounterTimer', 'createPoolZeroDExpChannel', 'createPoolTriggerGate', - 'createPoolMotor', 'createPoolMeasurementGroup', + 'createPoolMotor', 'createPoolMeasurementGroup', 'createPoolSynchronizationConfiguration', 'createCTAcquisitionConfiguration', 'createMGConfiguration', - 'createElemConf', 'createCtrlConf', 'createConfbyCtrlKlass', + 'createElemConf', 'createCtrlConf', 'createConfbyCtrlKlass', 'createMGUserConfiguration'] import copy from sardana.sardanadefs import ElementType @@ -39,6 +39,7 @@ from sardana.pool.poolmotor import PoolMotor from sardana.pool.poolmeasurementgroup import PoolMeasurementGroup + def createPoolController(pool, conf): '''Method to create a PoolController using a configuration dictionary ''' @@ -70,6 +71,7 @@ def createPoolController(pool, conf): kwargs['class_info'] = ctrl_class_info return PoolController(**kwargs) + def createPoolCounterTimer(pool, poolcontroller, conf): '''Method to create a PoolCounterTimer using a configuration dictionary ''' @@ -78,6 +80,7 @@ def createPoolCounterTimer(pool, poolcontroller, conf): kwargs['ctrl'] = poolcontroller return PoolCounterTimer(**kwargs) + def createPoolZeroDExpChannel(pool, poolcontroller, conf): '''Method to create a ZeroDExpChannel using a configuration dictionary ''' @@ -86,6 +89,7 @@ def createPoolZeroDExpChannel(pool, poolcontroller, conf): kwargs['ctrl'] = poolcontroller return Pool0DExpChannel(**kwargs) + def createPoolTriggerGate(pool, poolcontroller, conf): '''Method to create a PoolTriggerGate using a configuration dictionary ''' @@ -94,6 +98,7 @@ def createPoolTriggerGate(pool, poolcontroller, conf): kwargs['ctrl'] = poolcontroller return PoolTriggerGate(**kwargs) + def createPoolMotor(pool, poolcontroller, conf): '''Method to create a PoolMotor using a configuration dictionary ''' @@ -102,6 +107,7 @@ def createPoolMotor(pool, poolcontroller, conf): kwargs['ctrl'] = poolcontroller return PoolMotor(**kwargs) + def createPoolMeasurementGroup(pool, conf): '''Method to create a PoolMeasurementGroup using a configuration dictionary ''' @@ -112,11 +118,12 @@ def createPoolMeasurementGroup(pool, conf): kwargs['pool'] = pool return PoolMeasurementGroup(**kwargs) + def createPoolSynchronizationConfiguration(ctrls, ctrl_channels): '''Method to create PoolSynchronization configuration. Order of the sequences is important. For all sequences, the element of a given position refers the same controller. - + :param ctrls: sequence of the controllers used by the action :type ctrls: seq :param ctrl_channels: sequence of the sequences of the channels @@ -135,14 +142,14 @@ def createPoolSynchronizationConfiguration(ctrls, ctrl_channels): ctrl_data['channels'][channel] = channel_conf ctrls_configuration[ctrl] = ctrl_data configuration = {'controllers': ctrls_configuration} - return configuration + return configuration def createCTAcquisitionConfiguration(ctrls, ctrl_channels): '''Method to create CTAcquisition configuration. Order of the sequences is important. For all sequences, the element of a given position refers the same controller. - + :param ctrls: sequence of the controllers used by the action :type ctrls: seq :param ctrl_channels: sequence of the sequences of the channels @@ -167,7 +174,7 @@ def createCTAcquisitionConfiguration(ctrls, ctrl_channels): ctrl_data['timer'] = channels[master_idx] ctrls_configuration[ctrl] = ctrl_data configuration['controllers'] = ctrls_configuration - return configuration + return configuration def createMGUserConfiguration(pool, channels): @@ -194,7 +201,7 @@ def createMGUserConfiguration(pool, channels): MG_configuration['monitor'] = main_master_channel.full_name all_ctrls_d = {} - index = 0 # index represents the order of the channels + index = 0 # index represents the order of the channels for i in range(len(channels)): channels_in_ctrl = channels[i] master_channel_str = channels[i][0][0] @@ -203,7 +210,7 @@ def createMGUserConfiguration(pool, channels): ctrl_full_name = ctrl.full_name ctrl_d = {} - ctrl_d.update({ctrl_full_name:{}}) + ctrl_d.update({ctrl_full_name: {}}) ctrl_data = {} ctrl_data['monitor'] = master_channel_str @@ -221,21 +228,21 @@ def createMGUserConfiguration(pool, channels): one_channel_d.update({'plot_axes': ['']}) one_channel_d.update({'data_type': 'float64'}) one_channel_d.update({'index': index}) - one_channel_d.update({'enabled':True}) + one_channel_d.update({'enabled': True}) one_channel_d.update({'nexus_path': ''}) one_channel_d.update({'shape': []}) ctrl_from_channel = channel_element.get_controller() ctrl_name = ctrl_from_channel.full_name - one_channel_d.update({'_controller_name':ctrl_name}) + one_channel_d.update({'_controller_name': ctrl_name}) one_channel_d.update({'conditioning': ''}) - one_channel_d.update({'full_name':channel_name_str}) - one_channel_d.update({'id':channel_element.id}) + one_channel_d.update({'full_name': channel_name_str}) + one_channel_d.update({'id': channel_element.id}) one_channel_d.update({'normalization': 0}) one_channel_d.update({'output': True}) - one_channel_d.update({'label':channel_element.name}) + one_channel_d.update({'label': channel_element.name}) one_channel_d.update({'data_units': 'No unit'}) - one_channel_d.update({'name':channel_element.name}) - channels_d.update({channel_name_str:one_channel_d}) + one_channel_d.update({'name': channel_element.name}) + channels_d.update({channel_name_str: one_channel_d}) index += 1 ctrl_data['channels'] = {} @@ -246,12 +253,13 @@ def createMGUserConfiguration(pool, channels): MG_configuration.update({'controllers': all_ctrls_d}) return (MG_configuration, channel_ids, channel_names) + def createMGConfiguration(ctrls, ctrls_conf, ctrl_channels, ctrl_channels_conf, ctrl_trigger_elements, synchronizations): '''Method to create general MeasurementGroup (and CT) configuration. Order of the sequences is important. For all sequences, the element of a given position refers the same controller. - + :param ctrls: sequence of the controllers used by the action :type ctrls: seq :param ctrls_conf: sequence of the controllers configuration dictionaries @@ -278,12 +286,12 @@ def createMGConfiguration(ctrls, ctrls_conf, ctrl_channels, ctrl_channels_conf, MG_configuration['timer'] = ctrl_channels[master_ctrl_idx][master_idx] MG_configuration['monitor'] = ctrl_channels[master_ctrl_idx][master_idx] for ctrl, ctrl_data, channels, channels_conf, trigger_elements, \ - trigger_types in zip(ctrls, ctrls_conf, ctrl_channels, - ctrl_channels_conf, ctrl_trigger_elements, synchronizations): + trigger_types in zip(ctrls, ctrls_conf, ctrl_channels, + ctrl_channels_conf, ctrl_trigger_elements, synchronizations): ctrl_data['channels'] = {} index = 0 for channel, channel_conf, synchronizer, synchronization in \ - zip(channels, channels_conf, trigger_elements, trigger_types): + zip(channels, channels_conf, trigger_elements, trigger_types): ctrl_data['channels'][channel] = channel_conf # this way we are forcing the synchronization of the last channel ctrl_data['synchronization'] = synchronization @@ -298,76 +306,78 @@ def createMGConfiguration(ctrls, ctrls_conf, ctrl_channels, ctrl_channels_conf, ctrl_data['timer'] = channels[master_idx] ctrl_data['monitor'] = channels[master_idx] ctrls_configuration[ctrl] = ctrl_data - MG_configuration['controllers'] = ctrls_configuration + MG_configuration['controllers'] = ctrls_configuration return MG_configuration + def createConfbyCtrlKlass(pool, ctrl_klass, ctrl_name): pool_mng = pool.get_manager() klass = ctrl_klass meta = pool_mng.getControllerMetaClass(klass) _lib = meta.lib - #TODO check is is a valid name + # TODO check is is a valid name # raise Exception("The %s ctrl exists." % ctrl_name) name = full_name = ctrl_name - ctrl_id = pool.get_free_id() + ctrl_id = pool.get_free_id() lib_name = _lib.full_name ctrl_type = ElementType[meta.get_type()] - cfg = dict({ 'class_info': None, - 'full_name': full_name, - 'id': ctrl_id, - 'klass': klass, - 'lib_info': None, - 'library': lib_name, - 'name': name, - 'pool': None, - 'properties': {}, - 'role_ids': '', - 'type': ctrl_type}) + cfg = dict({'class_info': None, + 'full_name': full_name, + 'id': ctrl_id, + 'klass': klass, + 'lib_info': None, + 'library': lib_name, + 'name': name, + 'pool': None, + 'properties': {}, + 'role_ids': '', + 'type': ctrl_type}) return cfg + def createCtrlConf(pool, name, klass, lib, props={}): - cfg = dict({ 'class_info': None, - 'full_name': None, - 'id': None, - 'klass': None, - 'lib_info': None, - 'library': lib, - 'name': name, - 'pool': None, - 'properties': props, - 'role_ids': '', - 'type': 'ControllerClass'}) + cfg = dict({'class_info': None, + 'full_name': None, + 'id': None, + 'klass': None, + 'lib_info': None, + 'library': lib, + 'name': name, + 'pool': None, + 'properties': props, + 'role_ids': '', + 'type': 'ControllerClass'}) cfg['id'] = pool.get_free_id() cfg['name'] = cfg['full_name'] = name cfg['klass'] = klass cfg['library'] = lib return cfg + def createElemConf(pool, axis, name): - cfg = dict({ 'axis': None, - 'ctrl': None, - 'full_name': '', - 'id': None, - 'name': '', - 'pool': None }) + cfg = dict({'axis': None, + 'ctrl': None, + 'full_name': '', + 'id': None, + 'name': '', + 'pool': None}) cfg['id'] = pool.get_free_id() cfg['axis'] = axis cfg['name'] = cfg['full_name'] = name return cfg + def createConfFromObj(obj): cfg = dict({ - 'name': obj.name, - 'full_name': obj.full_name, - 'id': obj.id - }) + 'name': obj.name, + 'full_name': obj.full_name, + 'id': obj.id + }) # TODO: # enabling the channel - normally done when applying the MG conf. # see poolmeasurementgroup.PoolMeasurementGroup._build_channel_defaults if ElementType[obj.get_type()] == 'CTExpChannel': cfg['enabled'] = True return cfg - - diff --git a/src/sardana/pool/test/test_acquisition.py b/src/sardana/pool/test/test_acquisition.py index b09de1c442..cebca06e2c 100644 --- a/src/sardana/pool/test/test_acquisition.py +++ b/src/sardana/pool/test/test_acquisition.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## import time @@ -42,6 +42,7 @@ createCTAcquisitionConfiguration, BasePoolTestCase, FakeElement) + class AttributeListener(object): def __init__(self): @@ -57,14 +58,16 @@ def event_received(self, *args, **kwargs): # obtaining sardana element e.g. exp. channel (the attribute owner) obj = s.get_obj() obj_name = obj.name - # obtaining the SardanaValue(s) either from the value_chunk (in case - # of buffered attributes) or from the value in case of normal attributes + # obtaining the SardanaValue(s) either from the value_chunk (in case + # of buffered attributes) or from the value in case of normal + # attributes try: value_obj = v.value_chunk except AttributeError: value_obj = v.value_obj if is_non_str_seq(value_obj): - value = []; idx = [] + value = [] + idx = [] for sardana_value in value_obj: value.append(sardana_value.value) idx.append(sardana_value.idx) @@ -76,8 +79,8 @@ def event_received(self, *args, **kwargs): with self.data_lock: channel_data = self.data.get(obj_name, []) expected_idx = len(channel_data) - pad = [None] * (idx[0]-expected_idx) - channel_data.extend(pad+value) + pad = [None] * (idx[0] - expected_idx) + channel_data.extend(pad + value) self.data[obj_name] = channel_data def get_table(self): @@ -89,13 +92,15 @@ def get_table(self): table = [] for k in sorted(self.data.keys()): v = self.data[k] - v.extend([None]*(max_len-len(v))) + v.extend([None] * (max_len - len(v))) table.append(v) dtype_spec.append((k, 'float64')) a = numpy.array(zip(*table), dtype=dtype_spec) return a + class AcquisitionTestCase(BasePoolTestCase): + def setUp(self): """Create a Controller, TriggerGate and PoolSynchronization objects from dummy configurations. @@ -122,7 +127,7 @@ def hw_continuous_acquisition(self, offset, active_interval, tg_ctrl = tg.get_controller() # crating configuration for TGGeneration tg_cfg = createPoolSynchronizationConfiguration((tg_ctrl,), - ((tg,),)) + ((tg,),)) # creating PoolSynchronization action self.createPoolSynchronization([tg]) @@ -132,7 +137,6 @@ def hw_continuous_acquisition(self, offset, active_interval, ct_ctrl = self.ctrls[self.chn_ctrl_name] - # add_listeners self.addListeners(channels) # creating acquisition configurations @@ -154,7 +158,7 @@ def hw_continuous_acquisition(self, offset, active_interval, 'repetitions': repetitions, 'config': self.hw_acq_cfg, } - self.hw_acq.run(hw_acq_args, **hw_acq_kwargs) + self.hw_acq.run(hw_acq_args, **hw_acq_kwargs) tg_args = () tg_kwargs = { 'offset': offset, @@ -164,8 +168,8 @@ def hw_continuous_acquisition(self, offset, active_interval, 'config': tg_cfg } self.tggeneration.run(*tg_args, **tg_kwargs) - # waiting for acquisition and tggeneration to finish - while self.hw_acq.is_running() or self.tggeneration.is_running(): + # waiting for acquisition and tggeneration to finish + while self.hw_acq.is_running() or self.tggeneration.is_running(): time.sleep(1) self.do_asserts(self.channel_names, repetitions, jobs_before) @@ -200,7 +204,7 @@ def hw_step_acquisition(self, repetitions, integ_time): 'config': self.acq_cfg, } self.ct_acq.run(ct_acq_args, **ct_acq_kwargs) - # waiting for acquisition + # waiting for acquisition while self.ct_acq.is_running(): time.sleep(0.02) @@ -209,10 +213,9 @@ def hw_step_acquisition(self, repetitions, integ_time): value = channel.value.value print 'channel: %s = %s' % (name, value) msg = ('Value for channel %s is of type %s, should be ' % - (name, type(value))) + (name, type(value))) self.assertIsInstance(value, float, msg) - def addListeners(self, chn_list): for chn in chn_list: chn._value.add_listener(self.l) @@ -233,12 +236,12 @@ def do_asserts(self, channel_names, repetitions, jobs_before): for ch_name in header: ch_data_len = len(table[ch_name]) msg = 'length of data for channel %s is %d and should be %d' %\ - (ch_name, ch_data_len, repetitions) + (ch_name, ch_data_len, repetitions) self.assertEqual(ch_data_len, repetitions, msg) # checking if there are no pending jobs jobs_after = get_thread_pool().qsize msg = ('there are %d jobs pending to be done after the acquisition ' + - '(before: %d)') %(jobs_after, jobs_before) + '(before: %d)') % (jobs_after, jobs_before) self.assertEqual(jobs_before, jobs_after, msg) def tearDown(self): @@ -246,6 +249,7 @@ def tearDown(self): self.l = None self.channel_names = None + @insertTest(helper_name='continuous_acquisition', offset=0, active_interval=0.1, passive_interval=0.2, repetitions=10, integ_time=0.2) @insertTest(helper_name='continuous_acquisition', offset=0, @@ -264,6 +268,7 @@ class DummyAcquisitionTestCase(AcquisitionTestCase, unittest.TestCase): elements to corresponding sub-actions) and the PoolMeasurementGroup (it configures the elements and controllers). """ + def setUp(self): """Create a Controller, TriggerGate and PoolSynchronization objects from dummy configurations. @@ -297,22 +302,22 @@ def continuous_acquisition(self, offset, active_interval, passive_interval, # obtaining elements created in the BasePoolTestCase.setUp tg_2_1 = self.tgs['_test_tg_1_1'] tg_ctrl_2 = tg_2_1.get_controller() - ct_1_1 = self.cts['_test_ct_1_1'] # hw synchronized - ct_2_1 = self.cts['_test_ct_2_1'] # sw synchronized + ct_1_1 = self.cts['_test_ct_1_1'] # hw synchronized + ct_2_1 = self.cts['_test_ct_2_1'] # sw synchronized ct_ctrl_1 = ct_1_1.get_controller() ct_ctrl_2 = ct_2_1.get_controller() self.channel_names.append('_test_ct_1_1') self.channel_names.append('_test_ct_2_1') # crating configuration for TGGeneration tg_cfg = createPoolSynchronizationConfiguration((tg_ctrl_2,), - ((tg_2_1,),)) + ((tg_2_1,),)) # creating TGGeneration action self.createPoolSynchronization([tg_2_1]) # add_listeners self.addListeners([ct_1_1, ct_2_1]) # creating acquisition configurations self.hw_acq_cfg = createCTAcquisitionConfiguration((ct_ctrl_1,), - ((ct_1_1,),)) + ((ct_1_1,),)) self.sw_acq_cfg = createCTAcquisitionConfiguration((ct_ctrl_2,), ((ct_2_1,),)) # creating acquisition actions @@ -363,12 +368,11 @@ def continuous_acquisition(self, offset, active_interval, passive_interval, self.tggeneration.run(*tg_args, **tg_kwargs) # waiting for acquisition and tggeneration to finish while (self.hw_acq.is_running() or - self.sw_acq.is_running() or - self.tggeneration.is_running()): + self.sw_acq.is_running() or + self.tggeneration.is_running()): time.sleep(1) self.do_asserts(self.channel_names, repetitions, jobs_before) def tearDown(self): AcquisitionTestCase.tearDown(self) unittest.TestCase.tearDown(self) - diff --git a/src/sardana/pool/test/test_ctacquisition.py b/src/sardana/pool/test/test_ctacquisition.py index 2ac7c4e111..1f8295f046 100644 --- a/src/sardana/pool/test/test_ctacquisition.py +++ b/src/sardana/pool/test/test_ctacquisition.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -32,6 +32,7 @@ dummyPoolCTCtrlConf01, dummyMeasurementGroupConf01) + class PoolMeasurementGroupTestCase(unittest.TestCase): """Class used for an acquisition done by a Measurement Group with a dummyCounterTimer channel. The Measurement Group runs with a freshly created @@ -53,9 +54,10 @@ def setUp(self): pool.add_element(pc) pool.add_element(pct) - self.pmg = createPoolMeasurementGroup(pool, dummyMeasurementGroupConf01) + self.pmg = createPoolMeasurementGroup( + pool, dummyMeasurementGroupConf01) pool.add_element(self.pmg) - self._pct = pct # keep a reference to use it in test_acquisition + self._pct = pct # keep a reference to use it in test_acquisition def test_init(self): """check that the PoolMeasurementGroup is correctly instantiated""" diff --git a/src/sardana/pool/test/test_measurementgroup.py b/src/sardana/pool/test/test_measurementgroup.py index e7fd939e26..9c3f1d4709 100644 --- a/src/sardana/pool/test/test_measurementgroup.py +++ b/src/sardana/pool/test/test_measurementgroup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## import time @@ -35,9 +35,10 @@ from sardana.pool.test import (BasePoolTestCase, createPoolMeasurementGroup, dummyMeasurementGroupConf01, createMGUserConfiguration) -#TODO Import AttributeListener from the right location. +# TODO Import AttributeListener from the right location. from sardana.pool.test.test_acquisition import AttributeListener + class BaseAcquisition(object): def setUp(self, pool): @@ -53,7 +54,7 @@ def prepare_meas(self, config): pool = self.pool # creating mg user configuration and obtaining channel ids mg_conf, channel_ids, channel_names = \ - createMGUserConfiguration(pool, config) + createMGUserConfiguration(pool, config) conf = copy.deepcopy(dummyMeasurementGroupConf01) conf["name"] = 'mg1' conf["full_name"] = 'mg1' @@ -64,47 +65,47 @@ def prepare_meas(self, config): return channel_names def prepare_attribute_listener(self): - self.attr_listener = AttributeListener() - ## Add listeners - attributes = self.pmg.get_user_elements_attribute_sequence() + self.attr_listener = AttributeListener() + # Add listeners + attributes = self.pmg.get_user_elements_attribute_sequence() for attr in attributes: attr.add_listener(self.attr_listener) def remove_attribute_listener(self): - ## Remove listeners - attributes = self.pmg.get_user_elements_attribute_sequence() + # Remove listeners + attributes = self.pmg.get_user_elements_attribute_sequence() for attr in attributes: attr.remove_listener(self.attr_listener) def acquire(self): """ Run acquisition """ - self.pmg.start_acquisition() + self.pmg.start_acquisition() acq = self.pmg.acquisition - # waiting for acquisition - while acq.is_running(): - time.sleep(1) + # waiting for acquisition + while acq.is_running(): + time.sleep(1) def acq_asserts(self, channel_names, repetitions): # printing acquisition records table = self.attr_listener.get_table() header = table.dtype.names - print header + print header n_rows = table.shape[0] for row in xrange(n_rows): - print row, table[row] - # checking if any of data was acquired - self.assertTrue(self.attr_listener.data, 'no data were acquired') - # checking if all channels produced data + print row, table[row] + # checking if any of data was acquired + self.assertTrue(self.attr_listener.data, 'no data were acquired') + # checking if all channels produced data for channel in channel_names: msg = 'data from channel %s were not acquired' % channel self.assertIn(channel, header, msg) - + # checking if all the data were acquired for ch_name in header: ch_data_len = len(table[ch_name]) msg = 'length of data for channel %s is %d and should be %d' %\ - (ch_name, ch_data_len, repetitions) + (ch_name, ch_data_len, repetitions) self.assertEqual(ch_data_len, repetitions, msg) def meas_double_acquisition(self, config, synchronization, moveable=None): @@ -152,7 +153,8 @@ def meas_double_acquisition_samemode(self, config, synchronization, def consecutive_acquisitions(self, pool, config, synchronization): # creating mg user configuration and obtaining channel ids - mg_conf, channel_ids, channel_names = createMGUserConfiguration(pool, config) + mg_conf, channel_ids, channel_names = createMGUserConfiguration( + pool, config) # setting mg configuration - this cleans the action cache! self.pmg.set_configuration_from_user(mg_conf) @@ -180,13 +182,14 @@ def meas_cont_acquisition(self, config, synchronization, moveable=None, self.acq_asserts(channel_names, repetitions) if second_config is not None: - self.consecutive_acquisitions(self.pool, second_config, synchronization) + self.consecutive_acquisitions( + self.pool, second_config, synchronization) # checking if there are no pending jobs jobs_after = get_thread_pool().qsize msg = ('there are %d jobs pending to be done after the acquisition ' + - '(before: %d)') % (jobs_after, jobs_before) - self.assertEqual(jobs_before, jobs_after, msg) + '(before: %d)') % (jobs_after, jobs_before) + self.assertEqual(jobs_before, jobs_after, msg) def stopAcquisition(self): """Method used to abort a running acquisition""" @@ -196,32 +199,32 @@ def meas_cont_stop_acquisition(self, config, synchronization, moveable=None): """Executes measurement using the measurement group and tests that the acquisition can be stopped. - """ + """ self.prepare_meas(config) self.pmg.synchronization = synchronization self.pmg.moveable = moveable self.prepare_attribute_listener() - + self.pmg.start_acquisition() - # retrieving the acquisition since it was cleaned when applying mg conf + # retrieving the acquisition since it was cleaned when applying mg conf acq = self.pmg.acquisition - + # starting timer (0.05 s) which will stop the acquisiton - threading.Timer(0.2, self.stopAcquisition).start() - # waiting for acquisition and tggeneration to be stoped by thread + threading.Timer(0.2, self.stopAcquisition).start() + # waiting for acquisition and tggeneration to be stoped by thread while acq.is_running(): time.sleep(0.05) msg = "acquisition shall NOT be running after stopping it" - self.assertEqual(acq.is_running(), False, msg) + self.assertEqual(acq.is_running(), False, msg) tp = get_thread_pool() - numBW= tp.getNumOfBusyWorkers() + numBW = tp.getNumOfBusyWorkers() msg = "The number of busy workers is not zero; numBW = %s" % (numBW) self.assertEqual(numBW, 0, msg) # print the acquisition records for i, record in enumerate(zip(*self.attr_listener.data.values())): print i, record - + def meas_contpos_acquisition(self, config, synchronization, moveable, second_config=None): # TODO: this code is ready only for one group configuration @@ -243,10 +246,10 @@ def meas_contpos_acquisition(self, config, synchronization, moveable, self.pmg.start_acquisition() mot.set_position(position) acq = self.pmg.acquisition - # waiting for acquisition + # waiting for acquisition while acq.is_running(): time.sleep(0.1) - #time.sleep(3) + # time.sleep(3) self.acq_asserts(channel_names, repetitions) def tearDown(self): @@ -267,7 +270,7 @@ def tearDown(self): synchronization3 = [{SynchParam.Delay: {SynchDomain.Time: .1}, SynchParam.Initial: {SynchDomain.Position: 0}, SynchParam.Active: {SynchDomain.Position: .1, - SynchDomain.Time: .01,}, + SynchDomain.Time: .01, }, SynchParam.Total: {SynchDomain.Position: .2, SynchDomain.Time: .1}, SynchParam.Repeats: 10}] @@ -275,7 +278,7 @@ def tearDown(self): synchronization4 = [{SynchParam.Delay: {SynchDomain.Time: 0.1}, SynchParam.Initial: {SynchDomain.Position: 0}, SynchParam.Active: {SynchDomain.Position: -.1, - SynchDomain.Time: .01,}, + SynchDomain.Time: .01, }, SynchParam.Total: {SynchDomain.Position: -.2, SynchDomain.Time: .1}, SynchParam.Repeats: 10}] @@ -284,14 +287,14 @@ def tearDown(self): ' using the same trigger' config_1 = ( (('_test_ct_1_1', '_test_tg_1_1', AcqSynchType.Trigger), - ('_test_ct_1_2', '_test_tg_1_1', AcqSynchType.Trigger)), + ('_test_ct_1_2', '_test_tg_1_1', AcqSynchType.Trigger)), ) doc_2 = 'Synchronized acquisition with two channels from different controllers'\ ' using two different triggers' config_2 = ( (('_test_ct_1_1', '_test_tg_1_1', AcqSynchType.Trigger),), - (('_test_ct_2_1', '_test_tg_2_1', AcqSynchType.Trigger),) + (('_test_ct_2_1', '_test_tg_2_1', AcqSynchType.Trigger),) ) doc_3 = 'Use the same trigger in 2 channels of different controllers' @@ -319,15 +322,15 @@ def tearDown(self): doc_11 = 'Acquisition using 2 controllers, with 2 channels in each controller.' config_11 = [[('_test_ct_1_1', '_test_tg_1_1', AcqSynchType.Trigger), - ('_test_ct_1_2', '_test_tg_1_1', AcqSynchType.Trigger)], - [('_test_ct_2_1', 'software', AcqSynchType.Trigger), - ('_test_ct_2_2', 'software', AcqSynchType.Trigger)]] + ('_test_ct_1_2', '_test_tg_1_1', AcqSynchType.Trigger)], + [('_test_ct_2_1', 'software', AcqSynchType.Trigger), + ('_test_ct_2_2', 'software', AcqSynchType.Trigger)]] doc_9 = 'Test two consecutive synchronous acquisitions with different'\ ' configuration.' doc_10 = 'Test synchronous acquisition followed by asynchronous'\ - ' acquisition using the same configuration.' + ' acquisition using the same configuration.' doc_12 = 'Acquisition using 2 controllers, with 2 channels in each controller.' config_12 = [[('_test_ct_1_1', 'software', AcqSynchType.Trigger), @@ -336,9 +339,9 @@ def tearDown(self): ('_test_ct_2_2', 'software', AcqSynchType.Trigger)]] doc_13 = 'Test acquisition of zerod using software gate.' -config_13 = [[('_test_ct_1_1', '_test_tg_1_1', AcqSynchType.Trigger),], - [('_test_ct_2_1', 'software', AcqSynchType.Trigger),], - [('_test_0d_1_1', 'software', AcqSynchType.Gate),]] +config_13 = [[('_test_ct_1_1', '_test_tg_1_1', AcqSynchType.Trigger), ], + [('_test_ct_2_1', 'software', AcqSynchType.Trigger), ], + [('_test_0d_1_1', 'software', AcqSynchType.Gate), ]] @insertTest(helper_name='meas_contpos_acquisition', test_method_doc=doc_12, @@ -359,9 +362,9 @@ def tearDown(self): config=config_5, synchronization=synchronization1) # TODO: implement dedicated asserts/test for only software synchronized # acquisition. -# Until this TODO gets implemented we comment the test since it may +# Until this TODO gets implemented we comment the test since it may # fail (last acquisitions may not be executed - the previous one could -# still be in progress, so the shape of data will not correspond to the +# still be in progress, so the shape of data will not correspond to the # number of repetitions # @insertTest(helper_name='meas_cont_acquisition', test_method_doc=doc_6, # params=params_1, config=config_6) diff --git a/src/sardana/pool/test/test_poolcontroller.py b/src/sardana/pool/test/test_poolcontroller.py index 39fb1ff125..fea20f15fb 100644 --- a/src/sardana/pool/test/test_poolcontroller.py +++ b/src/sardana/pool/test/test_poolcontroller.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -28,6 +28,7 @@ dummyPoolCTCtrlConf01) from sardana.pool.poolcontroller import PoolController + class PoolControllerTestCase(unittest.TestCase): """Unittest of PoolController Class""" diff --git a/src/sardana/pool/test/test_poolcontrollermanager.py b/src/sardana/pool/test/test_poolcontrollermanager.py index ae416a25b8..2fee8cf8ec 100644 --- a/src/sardana/pool/test/test_poolcontrollermanager.py +++ b/src/sardana/pool/test/test_poolcontrollermanager.py @@ -2,30 +2,31 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## from taurus.external import unittest from sardana.pool.poolcontrollermanager import ControllerManager + class ControllerManagerTestCase(unittest.TestCase): """Unittest of ControllerManager Class""" @@ -42,4 +43,4 @@ def test_init(self): def tearDown(self): unittest.TestCase.tearDown(self) - self.cm = None \ No newline at end of file + self.cm = None diff --git a/src/sardana/pool/test/test_poolcountertimer.py b/src/sardana/pool/test/test_poolcountertimer.py index 410dae226a..14017643e8 100644 --- a/src/sardana/pool/test/test_poolcountertimer.py +++ b/src/sardana/pool/test/test_poolcountertimer.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,6 +29,7 @@ createPoolCounterTimer, dummyCounterTimerConf01, dummyPoolCTCtrlConf01) + class PoolCounterTimerTestCase(unittest.TestCase): """Unittest of PoolCounterTimer Class""" @@ -48,4 +49,4 @@ def test_init(self): def tearDown(self): unittest.TestCase.tearDown(self) - self.pct = None \ No newline at end of file + self.pct = None diff --git a/src/sardana/pool/test/test_poolsynchronization.py b/src/sardana/pool/test/test_poolsynchronization.py index 9f502074e3..9e4fcb0014 100644 --- a/src/sardana/pool/test/test_poolsynchronization.py +++ b/src/sardana/pool/test/test_poolsynchronization.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## import threading @@ -30,9 +30,10 @@ from sardana.sardanadefs import State from sardana.pool.test import (FakePool, createPoolController, createPoolTriggerGate, dummyPoolTGCtrlConf01, - dummyTriggerGateConf01, + dummyTriggerGateConf01, createPoolSynchronizationConfiguration) + class PoolTriggerGateTestCase(unittest.TestCase): """Unittest of PoolSynchronization class""" @@ -47,13 +48,13 @@ def setUp(self): self.skipTest("mock module is not available") pool = FakePool() dummy_tg_ctrl = createPoolController(pool, dummyPoolTGCtrlConf01) - self.dummy_tg = createPoolTriggerGate(pool, dummy_tg_ctrl, - dummyTriggerGateConf01) + self.dummy_tg = createPoolTriggerGate(pool, dummy_tg_ctrl, + dummyTriggerGateConf01) dummy_tg_ctrl.add_element(self.dummy_tg) pool.add_element(dummy_tg_ctrl) pool.add_element(self.dummy_tg) self.cfg = createPoolSynchronizationConfiguration((dummy_tg_ctrl,), - ((self.dummy_tg,),),) + ((self.dummy_tg,),),) # Create mock and define its functions ctrl_methods = ['PreStartAll', 'StartAll', 'PreStartOne', 'StartOne', 'PreStateAll', 'StateAll', 'PreStateOne', 'StateOne', @@ -78,13 +79,13 @@ def test_tggeneration(self): self.tgaction.start_action(*args, **kwargs) # verifying that the action correctly started the involved controller self.mock_tg_ctrl.assert_has_calls([call.PreStartAll(), - (call.PreStartOne(1,)), - (call.StartOne(1,)), - (call.StartAll())]) + (call.PreStartOne(1,)), + (call.StartOne(1,)), + (call.StartAll())]) # verifying that the elements involved in action changed its state element_state = self.dummy_tg.get_state() - msg = ("State after start_action is '%s'. (Expected: '%s')" % - (State.get(element_state), "Moving")) + msg = ("State after start_action is '%s'. (Expected: '%s')" % + (State.get(element_state), "Moving")) self.assertEqual(element_state, State.Moving, msg) # starting timer (1 s) which will change the controller state threading.Timer(1, self.stopGeneration).start() @@ -93,7 +94,7 @@ def test_tggeneration(self): # verifying that the action checked the controller states self.mock_tg_ctrl.assert_has_calls([call.PreStateAll(), call.PreStateOne(1,), - call.StateAll(), + call.StateAll(), call.StateOne(1,)]) # verifying that the elements involved in action changed its state element_state = self.dummy_tg.get_state() diff --git a/src/sardana/pool/test/test_synchronization.py b/src/sardana/pool/test/test_synchronization.py index bbfa2f4950..730da0f8b4 100644 --- a/src/sardana/pool/test/test_synchronization.py +++ b/src/sardana/pool/test/test_synchronization.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -40,6 +40,7 @@ createPoolController, createPoolTriggerGate, createPoolSynchronizationConfiguration) + class SynchronizationTestCase(object): """Base class for integration tests of PoolSynchronization class and any PoolTriggerGateController. Test is parameterized using trigger parameters. @@ -53,14 +54,14 @@ def createElements(self, ctrl_klass, ctrl_lib, ctrl_props): elem_conf = createElemConf(self.pool, 1, 'tg01') self.tg_ctrl = createPoolController(self.pool, ctrl_conf) self.tg_elem = createPoolTriggerGate(self.pool, self.tg_ctrl, - elem_conf) + elem_conf) # add controller and elements to containers self.tg_ctrl.add_element(self.tg_elem) self.pool.add_element(self.tg_ctrl) self.pool.add_element(self.tg_elem) # create Synchronization action and its configuration self.tg_cfg = createPoolSynchronizationConfiguration((self.tg_ctrl,), - ((self.tg_elem,),),) + ((self.tg_elem,),),) self.tgaction = PoolSynchronization(self.tg_elem) self.tgaction.add_element(self.tg_elem) @@ -91,17 +92,17 @@ def tggeneration(self, ctrl_lib, ctrl_klass, ctrl_props, # create controller and trigger element self.createElements(ctrl_klass, ctrl_lib, ctrl_props) - #create start_action arguments + # create start_action arguments args = () kwargs = {'config': self.tg_cfg, 'synchronization': synchronization - } + } # starting action self.tgaction.start_action(*args, **kwargs) # verifying that the elements involved in action changed its state element_state = self.tg_elem.get_state() - msg = ("State after start_action is '%s'. (Expected: '%s')" % - (State.get(element_state), "Moving")) + msg = ("State after start_action is '%s'. (Expected: '%s')" % + (State.get(element_state), "Moving")) self.assertEqual(element_state, State.Moving, msg) # entering action loop self.tgaction.action_loop() @@ -142,13 +143,13 @@ def abort_tggeneration(self, ctrl_lib, ctrl_klass, ctrl_props, args = () kwargs = {'config': self.tg_cfg, 'synchronization': synchronization - } + } # starting action self.tgaction.start_action(*args, **kwargs) # verifying that the elements involved in action changed its state element_state = self.tg_elem.get_state() - msg = ("State after start_action is '%s'. (Expected: '%s')" % - (State.get(element_state), "Moving")) + msg = ("State after start_action is '%s'. (Expected: '%s')" % + (State.get(element_state), "Moving")) self.assertEqual(element_state, State.Moving, msg) # starting timer (abort_time) stop the trigger generation @@ -178,17 +179,18 @@ def tearDown(self): SynchParam.Total: {SynchDomain.Time: .02}, SynchParam.Repeats: 100}] + @insertTest(helper_name='tggeneration', - ctrl_lib = 'DummyTriggerGateController', - ctrl_klass = 'DummyTriggerGateController', - ctrl_props = {}, - synchronization = synchronization1 + ctrl_lib='DummyTriggerGateController', + ctrl_klass='DummyTriggerGateController', + ctrl_props={}, + synchronization=synchronization1 ) @insertTest(helper_name='abort_tggeneration', - ctrl_lib = 'DummyTriggerGateController', - ctrl_klass = 'DummyTriggerGateController', - ctrl_props = {}, - synchronization = synchronization2, + ctrl_lib='DummyTriggerGateController', + ctrl_klass='DummyTriggerGateController', + ctrl_props={}, + synchronization=synchronization2, abort_time=0.5 ) class DummySynchronizationTestCase(SynchronizationTestCase, unittest.TestCase): diff --git a/src/sardana/release.py b/src/sardana/release.py index 55d13a795a..993834b5f4 100644 --- a/src/sardana/release.py +++ b/src/sardana/release.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -57,17 +57,17 @@ _v = tuple([int(n) for n in _v.split('.')]) version_info = _v + (_rel, 0) # deprecated, do not use -revision = str(version_info[4]) # deprecated, do not use +revision = str(version_info[4]) # deprecated, do not use description = "instrument control and data acquisition system" long_description = \ -'''Sardana is a Supervision, Control And Data Acquisition (SCADA) system for + '''Sardana is a Supervision, Control And Data Acquisition (SCADA) system for scientific installations. It is written in Python and based on the TANGO library. The hardware control and data acquisition routines can be accessed via an IPython console and a generic graphical user interface (both of which are easily extensible by the user).''' - + license = 'LGPL' authors = {'Tiago_et_al': ('Tiago Coutinho et al.', ''), @@ -79,6 +79,6 @@ download_url = 'http://pypi.python.org/packages/source/s/sardana' -platforms = ['Linux','Windows XP/2000/NT','Windows 95/98/ME'] +platforms = ['Linux', 'Windows XP/2000/NT', 'Windows 95/98/ME'] keywords = ['Sardana', 'Tango', 'Python', 'Control System'] diff --git a/src/sardana/requirements.py b/src/sardana/requirements.py index 09db0e38c6..24f296ccde 100644 --- a/src/sardana/requirements.py +++ b/src/sardana/requirements.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -34,12 +34,13 @@ import sys __requires__ = { -# module minimum - "Python" : (2, 6, 0), - "PyTango" : (7, 2, 3), - "taurus.core" : (3, 6, 0), + # module minimum + "Python": (2, 6, 0), + "PyTango": (7, 2, 3), + "taurus.core": (3, 6, 0), } + def check_requirements(exec_name=None): if exec_name is None: @@ -78,7 +79,8 @@ def check_requirements(exec_name=None): sys.exit(-1) # TODO: add itango as runtime dependency of spock - # now it is not possible because itango does not provide info about its version + # now it is not possible because itango does not provide info about its + # version taurusver = None try: diff --git a/src/sardana/sardanaattribute.py b/src/sardana/sardanaattribute.py index 27d46f02fa..88cc625090 100644 --- a/src/sardana/sardanaattribute.py +++ b/src/sardana/sardanaattribute.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -128,7 +128,8 @@ def _set_value(self, value, exc_info=None, timestamp=None, propagate=1): if isinstance(value, SardanaValue): rvalue = value else: - rvalue = SardanaValue(value=value, exc_info=exc_info, timestamp=timestamp) + rvalue = SardanaValue( + value=value, exc_info=exc_info, timestamp=timestamp) self._r_value = rvalue self.fire_read_event(propagate=propagate) @@ -282,7 +283,8 @@ def fire_read_event(self, propagate=1): obj = property(get_obj, "container object for this attribute") value_obj = property(get_value_obj) write_value_obj = property(get_write_value_obj) - value = property(get_value, set_value, "current read value for this attribute") + value = property(get_value, set_value, + "current read value for this attribute") w_value = property(get_write_value, set_write_value, "current write value for this attribute") timestamp = property(get_timestamp, doc="the read timestamp") @@ -300,11 +302,13 @@ def __repr__(self): def __str__(self): if self.has_value(): - value = "{0} at {1}".format(self.value, datetime.datetime.fromtimestamp(self.timestamp)) + value = "{0} at {1}".format( + self.value, datetime.datetime.fromtimestamp(self.timestamp)) else: value = "-----" if self.has_write_value(): - w_value = "{0} at {1}".format(self.w_value, datetime.datetime.fromtimestamp(self.w_timestamp)) + w_value = "{0} at {1}".format( + self.w_value, datetime.datetime.fromtimestamp(self.w_timestamp)) else: w_value = "-----" @@ -364,6 +368,7 @@ class BufferedAttribute(SardanaAttribute): (up to and including removal of the module) may occur if deemed necessary by the core developers. """ + def __init__(self, *args, **kwargs): SardanaAttribute.__init__(self, *args, **kwargs) self._r_value_chunk = [] @@ -436,4 +441,3 @@ def __init__(self): self.range = self.NoRange self.alarm = self.NoRange self.warning = self.NoRange - diff --git a/src/sardana/sardanabase.py b/src/sardana/sardanabase.py index 2cae07c7ff..005ee506e9 100644 --- a/src/sardana/sardanabase.py +++ b/src/sardana/sardanabase.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -42,7 +42,7 @@ class SardanaBaseObject(EventGenerator, EventReceiver, Logger): """The Sardana most abstract object. It contains only two members: - + - _manager : a weak reference to the manager (pool or ms) where it belongs - _name : the name @@ -63,50 +63,49 @@ def __init__(self, **kwargs): def get_manager(self): """Return the :class:`sardana.Manager` which *owns* this sardana object. - + :return: the manager which *owns* this pool object. :rtype: :class:`sardana.Manager`""" return self._manager() def get_name(self): """Returns this sardana object name - + :return: this sardana object name :rtype: str""" return self._name - + def set_name(self, name): """Sets sardana object name - + :param: sardana object name :type: str""" self._name = name - def get_full_name(self): """Returns this sardana object full name - + :return: this sardana object full name :rtype: str""" return self._full_name def get_type(self): """Returns this sardana object type. - + :return: this sardana object type :rtype: :obj:`~sardana.sardanadefs.ElementType`""" return self._type def get_parent(self): """Returns this pool object parent. - + :return: this objects parent :rtype: :class:`~sardana.sardanabase.SardanaBaseObject`""" return self._parent() def get_parent_name(self): """Returns this sardana object parent's name. - + :return: this objects parent :rtype: str""" parent = self.get_parent() @@ -116,7 +115,7 @@ def get_parent_name(self): def get_frontend(self): """Returns this sardana frontend object or None if no frontend is registered - + :return: this objects frontend :rtype: :obj:`object`""" f = self._frontend @@ -130,7 +129,8 @@ def fire_event(self, event_type, event_value, listeners=None, protected=True): return EventGenerator.fire_event(self, event_type, event_value, listeners=listeners) except: - self.warning("Error firing event <%r, %r>", event_type, event_value) + self.warning("Error firing event <%r, %r>", + event_type, event_value) self.debug("Details", exc_info=1) else: return EventGenerator.fire_event(self, event_type, event_value, @@ -138,7 +138,7 @@ def fire_event(self, event_type, event_value, listeners=None, protected=True): def get_interfaces(self): """Returns the set of interfaces this object implements. - + :return: The set of interfaces this object implements. :rtype: @@ -147,7 +147,7 @@ def get_interfaces(self): def get_interface(self): """Returns the interface this object implements. - + :return: The interface this object implements. :rtype: @@ -156,7 +156,7 @@ def get_interface(self): def get_interface_names(self): """Returns a sequence of interface names this object implements. - + :return: The sequence of interfaces this object implements. :rtype: @@ -199,7 +199,7 @@ def __init__(self, id=InvalidId): def get_id(self): """Returns this sardana object ID - + :return: this sardana object ID :rtype: int""" return self._id diff --git a/src/sardana/sardanacontainer.py b/src/sardana/sardanacontainer.py index 58edbeb830..16b188c0f4 100644 --- a/src/sardana/sardanacontainer.py +++ b/src/sardana/sardanacontainer.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -65,7 +65,7 @@ def __init__(self): def add_element(self, e): """Adds a new :class:`pool.PoolObject` to this container - + :param e: the pool element to be added :type e: :class:`pool.PoolObject` """ @@ -82,10 +82,10 @@ def add_element(self, e): def remove_element(self, e): """Removes the :class:`pool.PoolObject` from this container - + :param e: the pool object to be removed :type e: :class:`pool.PoolObject` - + :throw: KeyError """ name, full_name, id = e.get_name(), e.get_full_name(), e.get_id() @@ -98,7 +98,7 @@ def remove_element(self, e): def get_element_id_map(self): """Returns a reference to the internal pool object ID map - + :return: the internal pool object ID map :rtype: dict """ @@ -106,7 +106,7 @@ def get_element_id_map(self): def get_element_name_map(self): """Returns a reference to the internal pool object name map - + :return: the internal pool object name map :rtype: dict """ @@ -114,7 +114,7 @@ def get_element_name_map(self): def get_element_type_map(self): """Returns a reference to the internal pool object type map - + :return: the internal pool object type map :rtype: dict> """ @@ -122,14 +122,14 @@ def get_element_type_map(self): def get_element(self, **kwargs): """Returns a reference to the requested pool object - + :param kwargs: if key 'id' given: search by ID else if key 'full_name' given: search by full name else if key 'name' given: search by name - + :return: the pool object :rtype: pool.PoolObject - + :throw: KeyError """ if kwargs.has_key("id"): @@ -145,13 +145,13 @@ def get_element(self, **kwargs): def get_element_by_name(self, name, **kwargs): """Returns a reference to the requested pool object - + :param name: pool object name :type name: str - + :return: the pool object :rtype: pool.PoolObject - + :throw: KeyError """ ret = self._element_names.get(name) @@ -161,29 +161,30 @@ def get_element_by_name(self, name, **kwargs): def get_element_by_full_name(self, full_name, **kwargs): """Returns a reference to the requested pool object - + :param name: pool object full name :type name: str - + :return: the pool object :rtype: pool.PoolObject - + :throw: KeyError """ ret = self._element_full_names.get(full_name) if ret is None: - raise KeyError("There is no element with full name '%s'" % full_name) + raise KeyError( + "There is no element with full name '%s'" % full_name) return ret def get_element_by_id(self, id, **kwargs): """Returns a reference to the requested pool object - + :param id: pool object ID :type id: int - + :return: the pool object :rtype: pool.PoolObject - + :throw: KeyError """ ret = self._element_ids.get(id) @@ -193,32 +194,32 @@ def get_element_by_id(self, id, **kwargs): def get_elements_by_type(self, t): """Returns a list of all pool objects of the given type - + :param t: element type :type t: pool.ElementType - + :return: list of pool objects :rtype: seq """ elem_types_dict = self._element_types.get(t) if elem_types_dict is None: - return [] + return [] return elem_types_dict.values() def get_element_names_by_type(self, t): """Returns a list of all pool object names of the given type - + :param t: element type :type t: pool.ElementType - + :return: list of pool object names :rtype: seq """ - return [ elem.get_name() for elem in self.get_elements_by_type(t) ] + return [elem.get_name() for elem in self.get_elements_by_type(t)] def rename_element(self, old_name, new_name): """Rename an object - + :param old_name: old object name :type old_name: str :param new_name: new object name diff --git a/src/sardana/sardanacustomsettings.py b/src/sardana/sardanacustomsettings.py index 6017b75044..28a21454d6 100644 --- a/src/sardana/sardanacustomsettings.py +++ b/src/sardana/sardanacustomsettings.py @@ -2,24 +2,24 @@ ############################################################################# ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Taurus is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Taurus is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Taurus. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Taurus is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Taurus is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Taurus. If not, see . ## ############################################################################# @@ -30,7 +30,7 @@ """ #:UnitTest door name: the door to be used by unit tests. -#:UNITTEST_DOOR_NAME Must be defined for running sardana unittests. +#:UNITTEST_DOOR_NAME Must be defined for running sardana unittests. UNITTEST_DOOR_NAME = "door/demo1/1" #:UnitTests Pool DS name: Pool DS to use in unit tests. UNITTEST_POOL_DS_NAME = "unittest1" @@ -38,7 +38,7 @@ UNITTEST_POOL_NAME = "pool/demo1/1" #:Size and number of rotating backups of the log files. -#:The Pool and MacroServer Device servers will use these values for their logs. +#:The Pool and MacroServer Device servers will use these values for their logs. LOG_FILES_SIZE = 1e7 LOG_BCK_COUNT = 5 @@ -52,4 +52,4 @@ #: dict #: key - scan file extension #: value - recorder name -SCAN_RECORDER_MAP = None +SCAN_RECORDER_MAP = None diff --git a/src/sardana/sardanadefs.py b/src/sardana/sardanadefs.py index ab57e9f5bb..3b04521661 100644 --- a/src/sardana/sardanadefs.py +++ b/src/sardana/sardanadefs.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -49,7 +49,7 @@ EpsilonError = 1E-16 #: sardana element state enumeration -State = Enumeration("State", (\ +State = Enumeration("State", ( "On", "Off", "Close", @@ -93,12 +93,12 @@ def __repr__(self): #: server loop. Return immediately #: - **ASynchProcess** : separate process asynchronous: start a sub-process #: running the server loop. Return immediately -ServerRunMode = Enumeration("ServerRunMode", \ - ("SynchPure", "SynchThread", "SynchProcess", \ +ServerRunMode = Enumeration("ServerRunMode", + ("SynchPure", "SynchThread", "SynchProcess", "AsynchThread", "AsynchProcess")) #: sardana data types (used by device pool controllers) -DataType = Enumeration("DataType", (\ +DataType = Enumeration("DataType", ( "Integer", "Double", "String", @@ -107,84 +107,85 @@ def __repr__(self): "Invalid")) #: sardana data format enumeration (used by device pool controllers) -DataFormat = Enumeration("DataFormat", (\ +DataFormat = Enumeration("DataFormat", ( "Scalar", "OneD", "TwoD", "Invalid")) #: sardana data access (used by device pool controllers) -DataAccess = Enumeration("DataAccess", (\ +DataAccess = Enumeration("DataAccess", ( "ReadOnly", "ReadWrite", "Invalid")) #: dictionary dict DTYPE_MAP = { - 'int' : DataType.Integer, - 'integer' : DataType.Integer, - int : DataType.Integer, - long : DataType.Integer, - 'long' : DataType.Integer, - DataType.Integer : DataType.Integer, - 'float' : DataType.Double, - 'double' : DataType.Double, - float : DataType.Double, - DataType.Double : DataType.Double, - 'str' : DataType.String, - 'string' : DataType.String, - str : DataType.String, - DataType.String : DataType.String, - 'bool' : DataType.Boolean, - 'boolean' : DataType.Boolean, - bool : DataType.Boolean, - DataType.Boolean : DataType.Boolean, + 'int': DataType.Integer, + 'integer': DataType.Integer, + int: DataType.Integer, + long: DataType.Integer, + 'long': DataType.Integer, + DataType.Integer: DataType.Integer, + 'float': DataType.Double, + 'double': DataType.Double, + float: DataType.Double, + DataType.Double: DataType.Double, + 'str': DataType.String, + 'string': DataType.String, + str: DataType.String, + DataType.String: DataType.String, + 'bool': DataType.Boolean, + 'boolean': DataType.Boolean, + bool: DataType.Boolean, + DataType.Boolean: DataType.Boolean, } #: dictionary dict R_DTYPE_MAP = { - 'int' : int, - 'integer' : int, - int : int, - long : int, - 'long' : int, - DataType.Integer : int, - 'float' : float, - 'double' : float, - float : float, - DataType.Double : float, - 'str' : str, - 'string' : str, - str : str, - DataType.String : str, - 'bool' : bool, - 'boolean' : bool, - bool : bool, - DataType.Boolean : bool, + 'int': int, + 'integer': int, + int: int, + long: int, + 'long': int, + DataType.Integer: int, + 'float': float, + 'double': float, + float: float, + DataType.Double: float, + 'str': str, + 'string': str, + str: str, + DataType.String: str, + 'bool': bool, + 'boolean': bool, + bool: bool, + DataType.Boolean: bool, } -#DTYPE_MAP.setdefault(DataType.Invalid) +# DTYPE_MAP.setdefault(DataType.Invalid) #: dictionary dict DACCESS_MAP = { - 'read' : DataAccess.ReadOnly, - DataAccess.ReadOnly : DataAccess.ReadOnly, - 'readwrite' : DataAccess.ReadWrite, - 'read_write' : DataAccess.ReadWrite, - DataAccess.ReadWrite : DataAccess.ReadWrite, + 'read': DataAccess.ReadOnly, + DataAccess.ReadOnly: DataAccess.ReadOnly, + 'readwrite': DataAccess.ReadWrite, + 'read_write': DataAccess.ReadWrite, + DataAccess.ReadWrite: DataAccess.ReadWrite, } -#DACCESS_MAP.setdefault(DataAccess.Invalid) +# DACCESS_MAP.setdefault(DataAccess.Invalid) + def from_dtype_str(dtype): """Transforms the given dtype parameter (string/:obj:`DataType` or None) into a tuple of two elements (str, :obj:`DataFormat`) where the first element is a string with a simplified data type. - + - If None is given, it returns ('float', :obj:`DataFormat.Scalar`) - If :obj:`DataType` is given, it returns (:obj:`DataType`, :obj:`DataFormat.Scalar`) - + :param dtype: the data type to be transformed :type dtype: str or None or :obj:`DataType` :return: a tuple for the given dtype @@ -205,10 +206,11 @@ def from_dtype_str(dtype): dformat = DataFormat.OneD return dtype, dformat + def from_access_str(access): """Transforms the given access parameter (string or :obj:`DataAccess`) into a simplified data access string. - + :param dtype: the access to be transformed :type dtype: str :return: a simple string for the given access @@ -219,11 +221,12 @@ def from_access_str(access): access = access[len("pytango."):] return access + def to_dtype_dformat(data): """Transforms the given data parameter (string/ or sequence of string or sequence of sequence of string/:obj:`DataType`) into a tuple of two elements (:obj:`DataType`, :obj:`DataFormat`). - + :param data: the data information to be transformed :type data: str or seq or seq> :return: a tuple <:obj:`DataType`, :obj:`DataFormat`> for the given data @@ -248,18 +251,20 @@ def to_dtype_dformat(data): dtype = DTYPE_MAP.get(dtype, DataType.Invalid) return dtype, dformat + def to_daccess(daccess): """Transforms the given access parameter (string or None) into a :obj:`DataAccess`. If None is given returns :obj:`DataAccess.ReadWrite` - + :param dtype: the access to be transformed :type dtype: str :return: a :obj:`DataAccess` for the given access :rtype: :obj:`DataAccess`""" if daccess is None: daccess = DataAccess.ReadWrite - elif isinstance(daccess , (str, unicode)): - daccess = DACCESS_MAP.get(from_access_str(daccess), DataAccess.ReadWrite) + elif isinstance(daccess, (str, unicode)): + daccess = DACCESS_MAP.get( + from_access_str(daccess), DataAccess.ReadWrite) return daccess #: A constant representing an invalid ID @@ -269,7 +274,7 @@ def to_daccess(daccess): InvalidAxis = 0 #: An enumeration describing the all possible element types in sardana -ElementType = Enumeration("ElementType", (\ +ElementType = Enumeration("ElementType", ( "Pool", "Controller", "Motor", @@ -304,10 +309,10 @@ def to_daccess(daccess): #: a set containning all "controllable" element types. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` -TYPE_ELEMENTS = set((ET.Motor, ET.CTExpChannel, ET.ZeroDExpChannel, \ - ET.OneDExpChannel, ET.TwoDExpChannel, ET.TriggerGate, \ - ET.ComChannel, ET.IORegister, ET.PseudoMotor, \ - ET.PseudoCounter, ET.Constraint)) +TYPE_ELEMENTS = set((ET.Motor, ET.CTExpChannel, ET.ZeroDExpChannel, + ET.OneDExpChannel, ET.TwoDExpChannel, ET.TriggerGate, + ET.ComChannel, ET.IORegister, ET.PseudoMotor, + ET.PseudoCounter, ET.Constraint)) #: a set containing all group element types. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` @@ -319,33 +324,33 @@ def to_daccess(daccess): #: a set containing the possible types of physical elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` -TYPE_PHYSICAL_ELEMENTS = set((ET.Motor, ET.CTExpChannel, ET.ZeroDExpChannel, \ - ET.OneDExpChannel, ET.TwoDExpChannel, ET.TriggerGate,\ - ET.ComChannel, ET.IORegister)) +TYPE_PHYSICAL_ELEMENTS = set((ET.Motor, ET.CTExpChannel, ET.ZeroDExpChannel, + ET.OneDExpChannel, ET.TwoDExpChannel, ET.TriggerGate, + ET.ComChannel, ET.IORegister)) #: a set containing the possible types of acquirable elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` -TYPE_ACQUIRABLE_ELEMENTS = set((ET.Motor, ET.CTExpChannel, ET.ZeroDExpChannel, \ - ET.OneDExpChannel, ET.TwoDExpChannel, \ - ET.ComChannel, ET.IORegister, ET.PseudoMotor, \ - ET.PseudoCounter)) +TYPE_ACQUIRABLE_ELEMENTS = set((ET.Motor, ET.CTExpChannel, ET.ZeroDExpChannel, + ET.OneDExpChannel, ET.TwoDExpChannel, + ET.ComChannel, ET.IORegister, ET.PseudoMotor, + ET.PseudoCounter)) #: a set containing the possible types of experimental channel elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` -TYPE_EXP_CHANNEL_ELEMENTS = set((ET.CTExpChannel, ET.ZeroDExpChannel, \ - ET.OneDExpChannel, ET.TwoDExpChannel, ET.PseudoCounter)) +TYPE_EXP_CHANNEL_ELEMENTS = set((ET.CTExpChannel, ET.ZeroDExpChannel, + ET.OneDExpChannel, ET.TwoDExpChannel, ET.PseudoCounter)) #: a set containing the possible timer-able elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_TIMERABLE_ELEMENTS = set((ET.CTExpChannel, ET.OneDExpChannel, - ET.TwoDExpChannel)) + ET.TwoDExpChannel)) #: a set containing the possible types of pseudo elements. #: Constant values belong to :class:`~sardana.sardanadefs.ElementType` TYPE_PSEUDO_ELEMENTS = set((ET.PseudoMotor, ET.PseudoCounter)) -##: An enumeration describing the all possible sardana interfaces -#SardanaInterface = Enumeration("SardanaInterface", ( \ +# : An enumeration describing the all possible sardana interfaces +# SardanaInterface = Enumeration("SardanaInterface", ( \ # ("Object", 0b0000000000000001), # ("Element", 0b0000000000000011), # ("Class", 0b0000000000000101), @@ -384,54 +389,55 @@ def to_daccess(daccess): #: a dictionary containing the direct interfaces supported by each type #: (:obj:`dict`\<:obj:`str`\, :obj:`tuple`\<:obj:`set`\<:obj:`str`\, :obj:`str`\>>>) INTERFACES = { - "Meta" : (set(), "A generic sardana meta object"), - "Object" : (set(), "A generic sardana object"), - "Element" : (set(("Object",)), "A generic sardana element"), - "Class" : (set(("Object",)), "A generic sardana class"), - "Function" : (set(("Object",)), "A generic sardana function"), - "Library" : (set(("Object",)), "A generic sardana library"), - "PoolObject" : (set(("Object",)), "A Pool object"), - "PoolElement" : (set(("Element", "PoolObject")), "A Pool element"), - "Pool" : (set(("PoolElement",)), "A Pool"), - "Controller" : (set(("PoolElement",)), "A controller"), - "Moveable" : (set(("PoolElement",)), "A moveable element"), - "Acquirable" : (set(("PoolElement",)), "An acquirable element"), - "Instrument" : (set(("PoolElement",)), "An instrument"), - "Motor" : (set(("Moveable", "Acquirable")), "a motor"), - "PseudoMotor" : (set(("Moveable", "Acquirable")), "A pseudo motor"), - "IORegister" : (set(("Acquirable",)), "An IO register"), - "ExpChannel" : (set(("Acquirable",)), "A generic experimental channel"), - "CTExpChannel" : (set(("ExpChannel",)), "A counter/timer experimental channel"), - "ZeroDExpChannel" : (set(("ExpChannel",)), "A 0D experimental channel"), - "OneDExpChannel" : (set(("ExpChannel",)), "A 1D experimental channel"), - "TwoDExpChannel" : (set(("ExpChannel",)), "A 2D experimental channel"), - "TriggerGate" : (set(("PoolElement",)), "A trigger/gate"), - "PseudoCounter" : (set(("ExpChannel",)), "A pseudo counter"), - "ComChannel" : (set(("PoolElement",)), "A communication channel"), - "MotorGroup" : (set(("PoolElement",),), "A motor group"), - "MeasurementGroup" : (set(("PoolElement",),), "A measurement group"), - "ControllerLibrary" : (set(("Library", "PoolObject")), "A controller library"), - "ControllerClass" : (set(("Class", "PoolObject")), "A controller class"), - "Constraint" : (set(("PoolObject",)), "A constraint"), - "External" : (set(("Object",)), "An external object"), - - "MacroServerObject" : (set(("Object",)), "A generic macro server object"), - "MacroServerElement" : (set(("Element", "MacroServerObject")), "A generic macro server element"), - "MacroServer" : (set(("MacroServerElement",)), "A MacroServer"), - "Door" : (set(("MacroServerElement",)), "A macro server door"), - "MacroLibrary" : (set(("Library", "MacroServerObject")), "A macro server library"), - "MacroCode" : (set(("MacroServerObject",)), "A macro server macro code"), - "MacroClass" : (set(("Class", "MacroCode")), "A macro server macro class"), - "MacroFunction" : (set(("Function", "MacroCode")), "A macro server macro function"), - "Macro" : (set(("MacroClass", "MacroFunction")), "A macro server macro"), - - "ParameterType" : (set(("Meta",)), "A generic macro server parameter type"), + "Meta": (set(), "A generic sardana meta object"), + "Object": (set(), "A generic sardana object"), + "Element": (set(("Object",)), "A generic sardana element"), + "Class": (set(("Object",)), "A generic sardana class"), + "Function": (set(("Object",)), "A generic sardana function"), + "Library": (set(("Object",)), "A generic sardana library"), + "PoolObject": (set(("Object",)), "A Pool object"), + "PoolElement": (set(("Element", "PoolObject")), "A Pool element"), + "Pool": (set(("PoolElement",)), "A Pool"), + "Controller": (set(("PoolElement",)), "A controller"), + "Moveable": (set(("PoolElement",)), "A moveable element"), + "Acquirable": (set(("PoolElement",)), "An acquirable element"), + "Instrument": (set(("PoolElement",)), "An instrument"), + "Motor": (set(("Moveable", "Acquirable")), "a motor"), + "PseudoMotor": (set(("Moveable", "Acquirable")), "A pseudo motor"), + "IORegister": (set(("Acquirable",)), "An IO register"), + "ExpChannel": (set(("Acquirable",)), "A generic experimental channel"), + "CTExpChannel": (set(("ExpChannel",)), "A counter/timer experimental channel"), + "ZeroDExpChannel": (set(("ExpChannel",)), "A 0D experimental channel"), + "OneDExpChannel": (set(("ExpChannel",)), "A 1D experimental channel"), + "TwoDExpChannel": (set(("ExpChannel",)), "A 2D experimental channel"), + "TriggerGate": (set(("PoolElement",)), "A trigger/gate"), + "PseudoCounter": (set(("ExpChannel",)), "A pseudo counter"), + "ComChannel": (set(("PoolElement",)), "A communication channel"), + "MotorGroup": (set(("PoolElement",),), "A motor group"), + "MeasurementGroup": (set(("PoolElement",),), "A measurement group"), + "ControllerLibrary": (set(("Library", "PoolObject")), "A controller library"), + "ControllerClass": (set(("Class", "PoolObject")), "A controller class"), + "Constraint": (set(("PoolObject",)), "A constraint"), + "External": (set(("Object",)), "An external object"), + + "MacroServerObject": (set(("Object",)), "A generic macro server object"), + "MacroServerElement": (set(("Element", "MacroServerObject")), "A generic macro server element"), + "MacroServer": (set(("MacroServerElement",)), "A MacroServer"), + "Door": (set(("MacroServerElement",)), "A macro server door"), + "MacroLibrary": (set(("Library", "MacroServerObject")), "A macro server library"), + "MacroCode": (set(("MacroServerObject",)), "A macro server macro code"), + "MacroClass": (set(("Class", "MacroCode")), "A macro server macro class"), + "MacroFunction": (set(("Function", "MacroCode")), "A macro server macro function"), + "Macro": (set(("MacroClass", "MacroFunction")), "A macro server macro"), + + "ParameterType": (set(("Meta",)), "A generic macro server parameter type"), } #: a dictionary containing the *all* interfaces supported by each type #: (:obj:`dict` <:obj:`str`, :obj:`set` < :obj:`str`> >) INTERFACES_EXPANDED = {} + def __expand(name): direct_expansion, _ = INTERFACES[name] if isinstance(direct_expansion, (str, unicode)): @@ -446,6 +452,7 @@ def __expand(name): exp.add(name) return exp + def __build_interfaces_expanded(): global INTERFACES_EXPANDED for i in INTERFACES: @@ -453,6 +460,7 @@ def __build_interfaces_expanded(): __build_interfaces_expanded() + def __expand_sardana_interface_data(si_map, name, curr_id): if name in si_map: return curr_id @@ -461,11 +469,13 @@ def __expand_sardana_interface_data(si_map, name, curr_id): i_expanded.remove(name) for interface in i_expanded: if interface not in si_map: - curr_id = __expand_sardana_interface_data(si_map, interface, curr_id) + curr_id = __expand_sardana_interface_data( + si_map, interface, curr_id) d |= si_map[interface] si_map[name] = long(d | curr_id) return 2 * curr_id + def __root_expand_sardana_interface_data(): curr_id = 1 si_map = {} @@ -477,6 +487,7 @@ def __root_expand_sardana_interface_data(): Interface = Enumeration("Interface", __root_expand_sardana_interface_data().items()) + def __create_sardana_interfaces(): interfaces, interfaces_expanded = {}, {} for i in INTERFACES: diff --git a/src/sardana/sardanaevent.py b/src/sardana/sardanaevent.py index 339f7a5de0..52bdc48ae5 100644 --- a/src/sardana/sardanaevent.py +++ b/src/sardana/sardanaevent.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -71,7 +71,7 @@ def _listener_died(self, weak_listener): def add_listener(self, listener): """Adds a new listener for this object. - + :param listener: a listener""" if self._listeners is None or listener is None: return False @@ -84,7 +84,7 @@ def add_listener(self, listener): def remove_listener(self, listener): """Removes an existing listener for this object. - + :param listener: the listener to be removed :return: True is succeeded or False otherwise""" if self._listeners is None: @@ -98,7 +98,7 @@ def remove_listener(self, listener): def has_listeners(self): """Returns True if anybody is listening to events from this object - + :return: True is at least one listener is listening or False otherwise """ if self._listeners is None: @@ -177,14 +177,14 @@ def __repr__(self): def get_name(self): """Returns this event name - + :return: this event name :rtype: str""" return self.name def get_priority(self): """Returns this event priority - + :return: this event priority :rtype: str""" return self.priority diff --git a/src/sardana/sardanaexception.py b/src/sardana/sardanaexception.py index ca28fba817..9bef60311c 100644 --- a/src/sardana/sardanaexception.py +++ b/src/sardana/sardanaexception.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -28,7 +28,7 @@ from __future__ import absolute_import -__all__ = [ "AbortException", "SardanaException", "SardanaExceptionList", +__all__ = ["AbortException", "SardanaException", "SardanaExceptionList", "UnknownCode", "UnknownLibrary", "LibraryError", "format_exception_only", "format_exception_only_str"] @@ -44,9 +44,11 @@ def format_exception_only(etype, value): msg[-1] = msg[-1][:-1] return msg + def format_exception_only_str(etype, value): return "".join(format_exception_only(etype, value)) + class AbortException(Exception): pass @@ -87,6 +89,7 @@ def __repr__(self): class SardanaExceptionList(SardanaException): + def __init__(self, *args): SardanaException.__init__(self, *args) self.exceptions = args[0] @@ -102,4 +105,3 @@ class UnknownLibrary(SardanaException): class LibraryError(SardanaException): pass - diff --git a/src/sardana/sardanalock.py b/src/sardana/sardanalock.py index 067491911e..02690129f9 100644 --- a/src/sardana/sardanalock.py +++ b/src/sardana/sardanalock.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/sardanamanager.py b/src/sardana/sardanamanager.py index 93164fad58..a4afd9b715 100644 --- a/src/sardana/sardanamanager.py +++ b/src/sardana/sardanamanager.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -39,59 +39,58 @@ class SardanaElementManager(object): """A class capable of manage elements""" - + SerializationProtocol = 'json' - + def get_serialization_protocol(self): return self.SerializationProtocol - + def set_serialization_protocol(self, protocol): self.SerializationProtocol = protocol - + serialization_protocol = property(get_serialization_protocol, set_serialization_protocol, doc="the serialization protocol") - + def serialize_element(self, element, *args, **kwargs): obj = element.serialize(*args, **kwargs) return self.serialize_object(obj) - + def serialize_object(self, obj, *args, **kwargs): return CodecFactory().encode(self.serialization_protocol, ('', obj), *args, **kwargs)[1] - + def str_element(self, element, *args, **kwargs): obj = element.serialize(*args, **kwargs) return self.str_object(obj) - + def str_object(self, obj, *args, **kwargs): # TODO: use the active codec instead of hardcoded json - return CodecFactory().encode('json', ('', obj), *args, **kwargs)[1] + return CodecFactory().encode('json', ('', obj), *args, **kwargs)[1] class SardanaIDManager(object): """A class capable of manage ids""" - + _last_id = InvalidId - + def get_new_id(self): """Returns a new ID. The ID becomes reserved at this moment. - + :return: a new ID :rtype: int""" self._last_id += 1 return self._last_id - + def rollback_id(self): """Free previously reserved ID""" self._last_id -= 1 - + def reserve_id(self, nid): """Marks the given ID as reserved - + :param id: the ID to be reserved :type id: int""" assert type(nid) == int if nid > self._last_id: self._last_id = nid - \ No newline at end of file diff --git a/src/sardana/sardanameta.py b/src/sardana/sardanameta.py index a458b9b3ab..bf3fe5c45c 100644 --- a/src/sardana/sardanameta.py +++ b/src/sardana/sardanameta.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -57,6 +57,7 @@ def findsource(obj): linecache.checkcache(filename) return inspect.findsource(obj) + def getsourcelines(object): """Return a list of source lines and starting line number for an object. @@ -67,8 +68,11 @@ def getsourcelines(object): raised if the source code cannot be retrieved.""" lines, lnum = findsource(object) - if inspect.ismodule(object): return lines, 0 - else: return inspect.getblock(lines[lnum:]), lnum + 1 + if inspect.ismodule(object): + return lines, 0 + else: + return inspect.getblock(lines[lnum:]), lnum + 1 + def getsource(object): """Return the text of the source code for an object. @@ -252,7 +256,7 @@ def has_meta(self, meta_name): library or False otherwise :rtype: bool""" return self.has_meta_class(meta_name) or \ - self.has_meta_function(meta_name) + self.has_meta_function(meta_name) def has_metas(self): """Returns True if any meta object exists in the library @@ -264,8 +268,8 @@ def has_metas(self): :rtype: bool """ has_metas_bool = False - if (len(self.get_meta_classes()) > 0 or - len(self.get_meta_functions()) > 0): + if (len(self.get_meta_classes()) > 0 or + len(self.get_meta_functions()) > 0): has_metas_bool = True return has_metas_bool @@ -375,13 +379,16 @@ def serialize(self, *args, **kwargs): kwargs['file_name'] = self.file_name kwargs['path'] = self.path kwargs['description'] = self.description - kwargs['elements'] = self.meta_classes.keys() + self.meta_functions.keys() + kwargs['elements'] = self.meta_classes.keys() + \ + self.meta_functions.keys() if self.exc_info is None: kwargs['exc_summary'] = None kwargs['exc_info'] = None else: - kwargs['exc_summary'] = "".join(traceback.format_exception_only(*self.exc_info[:2])) - kwargs['exc_info'] = "".join(traceback.format_exception(*self.exc_info)) + kwargs['exc_summary'] = "".join( + traceback.format_exception_only(*self.exc_info[:2])) + kwargs['exc_info'] = "".join( + traceback.format_exception(*self.exc_info)) return kwargs @@ -522,4 +529,3 @@ def __init__(self, **kwargs): @property def function(self): return self.code_object - diff --git a/src/sardana/sardanamodulemanager.py b/src/sardana/sardanamodulemanager.py index 923cf1325f..8ad2b7ffe6 100755 --- a/src/sardana/sardanamodulemanager.py +++ b/src/sardana/sardanamodulemanager.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -44,13 +44,13 @@ from .sardanamanager import SardanaIDManager _MINIMUM_EXCLUDE = [ -'sys', -'os.path', -'__builtin__', -'__main__', -'sardana', -'taurus', -'PyTango' + 'sys', + 'os.path', + '__builtin__', + '__main__', + 'sardana', + 'taurus', + 'PyTango' ] @@ -86,7 +86,7 @@ def _decode_path(path): def add_python_path(self, path): """Adds a new path to the python path. - + :param path: a sequence of strings each string may contain an absolute path or a list of ":" or "\n" separated absolute paths @@ -111,7 +111,7 @@ def add_python_path(self, path): def remove_python_path(self, path_id): """Removes the path given by the path_id - + :param path_id: a path id identifying specific changes that were made to sys.path :type path_id: int""" @@ -258,13 +258,13 @@ def deep_reload_module(self, module_name, path=None, exclude=None): def loadModule(self, module_name, path=None): """Loads the given module name. If the module has been already loaded into this python interpreter, nothing is done. - + :param module_name: the module to be loaded. :type module_name: str :param path: list of paths to look for modules [default: None] :type path: seq or None :return: python module - + :raises: ImportError""" if module_name in sys.modules: @@ -308,4 +308,3 @@ def getModuleNames(self): module_names = self._modules.keys() module_names.sort() return module_names - diff --git a/src/sardana/sardanathreadpool.py b/src/sardana/sardanathreadpool.py index 2efd1ddc50..66faf4e29e 100644 --- a/src/sardana/sardanathreadpool.py +++ b/src/sardana/sardanathreadpool.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -42,7 +42,7 @@ def get_thread_pool(): """Returns the global pool of threads for Sardana - + :return: the global pool of threads object :rtype: taurus.core.util.ThreadPool""" diff --git a/src/sardana/sardanautils.py b/src/sardana/sardanautils.py index ae3debe640..2ad45b4bc9 100644 --- a/src/sardana/sardanautils.py +++ b/src/sardana/sardanautils.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -72,36 +72,44 @@ __number_klasses = tuple(__number_klasses) __bool_klasses = tuple(__bool_klasses) + def is_pure_str(obj): - return isinstance(obj , __str_klasses) + return isinstance(obj, __str_klasses) + def is_non_str_seq(obj): return isinstance(obj, collections.Sequence) and not is_pure_str(obj) + def is_integer(obj): return isinstance(obj, __int_klasses) + def is_number(obj): return isinstance(obj, __number_klasses) + def is_bool(obj): return isinstance(obj, __bool_klasses) + def is_callable(obj): return hasattr(obj, "__call__") __METH_MAP = { - DataType.Integer : is_integer, - DataType.Double : is_number, - DataType.String : is_pure_str, - DataType.Boolean : is_bool, + DataType.Integer: is_integer, + DataType.Double: is_number, + DataType.String: is_pure_str, + DataType.Boolean: is_bool, } + def check_type(type_info, value): tinfo = __DTYPE_MAP.get(type_info, type_info) tmeth = __METH_MAP.get(tinfo, type_info) return tmeth(value) + def assert_type(type_info, value): ret = check_type(type_info, value) if not ret: @@ -119,31 +127,34 @@ def assert_type(type_info, value): return ret _DTYPE_FUNC = { - DataType.Integer : int, - DataType.Double : float, - DataType.String : str, - DataType.Boolean : bool, + DataType.Integer: int, + DataType.Double: float, + DataType.String: str, + DataType.Boolean: bool, } + def str_to_value(value, dtype=DataType.Double, dformat=DataFormat.Scalar): f = _DTYPE_FUNC[dtype] if dformat == DataFormat.Scalar: ret = f(value) elif dformat == DataFormat.OneD: - ret = [ f(v) for v in value ] + ret = [f(v) for v in value] elif dformat == DataFormat.TwoD: ret = [] for v1 in value: - ret.append([ f(v2) for v2 in v1 ]) + ret.append([f(v2) for v2 in v1]) return ret + def translate_version_str2int(version_str): """Translates a version string in format x[.y[.z[...]]] into a 000000 number. Each part of version number can have up to 99 possibilities.""" import math parts = version_str.split('.') i, v, l = 0, 0, len(parts) - if not l: return v + if not l: + return v while i < 3: try: v += int(parts[i]) * int(math.pow(10, (2 - i) * 2)) @@ -151,7 +162,8 @@ def translate_version_str2int(version_str): i += 1 except ValueError: return v - if not l: return v + if not l: + return v return v try: @@ -159,21 +171,25 @@ def translate_version_str2int(version_str): l -= 1 except ValueError: return v - if not l: return v + if not l: + return v try: v += 100 * int(parts[1]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v try: v += int(parts[0]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v + def translate_version_str2list(version_str, depth=2): """Translates a version string in format 'x[.y[.z[...]]]' into a list of @@ -189,4 +205,3 @@ def translate_version_str2list(version_str, depth=2): i = 0 ver.append(i) return ver - diff --git a/src/sardana/sardanavalue.py b/src/sardana/sardanavalue.py index 386ddea2d9..681ef7285a 100644 --- a/src/sardana/sardanavalue.py +++ b/src/sardana/sardanavalue.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/spock/__init__.py b/src/sardana/spock/__init__.py index 8845fd0331..496c5b59f5 100644 --- a/src/sardana/spock/__init__.py +++ b/src/sardana/spock/__init__.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,5 +29,6 @@ from genutils import load_ipython_extension, unload_ipython_extension, \ load_config, run + def main(): run() diff --git a/src/sardana/spock/colors.py b/src/sardana/spock/colors.py index dd68759d30..87cfcbc02b 100644 --- a/src/sardana/spock/colors.py +++ b/src/sardana/spock/colors.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -30,4 +30,4 @@ __docformat__ = 'restructuredtext' -from taurus.core.util.console import make_color_table, TermColors, HTMLColors \ No newline at end of file +from taurus.core.util.console import make_color_table, TermColors, HTMLColors diff --git a/src/sardana/spock/config.py b/src/sardana/spock/config.py index 2a3e221fd7..864262428e 100644 --- a/src/sardana/spock/config.py +++ b/src/sardana/spock/config.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -38,9 +38,10 @@ from IPython.config.configurable import Configurable from IPython.utils.traitlets import Unicode, Bool + class Spock(Configurable): macro_server_name = Unicode(config=True) door_name = Unicode(config=True) macro_server_alias = Unicode(config=True) door_alias = Unicode(config=True) - ready = Bool(default_value=False, config=True) \ No newline at end of file + ready = Bool(default_value=False, config=True) diff --git a/src/sardana/spock/exception.py b/src/sardana/spock/exception.py index 1ce89b0a17..f259689da6 100644 --- a/src/sardana/spock/exception.py +++ b/src/sardana/spock/exception.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -35,11 +35,14 @@ class SpockException(Exception): pass + class SpockBadInstallation(SpockException): pass + class SpockMissingRequirement(SpockException): pass + class SpockMissingRecommended(SpockException): pass diff --git a/src/sardana/spock/genutils.py b/src/sardana/spock/genutils.py index 563a267a02..9d21a3b2c3 100644 --- a/src/sardana/spock/genutils.py +++ b/src/sardana/spock/genutils.py @@ -3,29 +3,30 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """This package provides the spock generic utilities""" + def translate_version_str2list(version_str): """Translates a version string in format 'x[.y[.z[...]]]' into a list of numbers""" @@ -41,6 +42,7 @@ def translate_version_str2list(version_str): ver.append(i) return ver + def get_ipython_version(): """Returns the current IPython version""" import IPython @@ -57,6 +59,7 @@ def get_ipython_version(): pass return v + def get_ipython_version_list(): ipv_str = get_ipython_version() return translate_version_str2list(ipv_str) @@ -68,5 +71,3 @@ def get_ipython_version_list(): from ipython_00_11.genutils import * else: from ipython_01_00.genutils import * - - diff --git a/src/sardana/spock/inputhandler.py b/src/sardana/spock/inputhandler.py index 9e013d56d3..4174582541 100644 --- a/src/sardana/spock/inputhandler.py +++ b/src/sardana/spock/inputhandler.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -76,10 +76,10 @@ def __init__(self, conn, parent=None): self._conn = conn self._dialog = None self.connect(self, Qt.SIGNAL("messageArrived"), self.on_message) - + def handle_message(self, input_data): self.emit(Qt.SIGNAL("messageArrived"), input_data) - + def on_message(self, input_data): msg_type = input_data['type'] if msg_type == 'input': @@ -103,18 +103,18 @@ def on_message(self, input_data): class InputHandler(Singleton, BaseInputHandler): - + def __init__(self): # don't call super __init__ on purpose pass - + def init(self, *args, **kwargs): self._conn, child_conn = Pipe() self._proc = proc = Process(target=self.safe_run, - name="SpockInputHandler", args=(child_conn,)) + name="SpockInputHandler", args=(child_conn,)) proc.daemon = True proc.start() - + def input(self, input_data=None): # parent process data_type = input_data.get('data_type', 'String') @@ -122,7 +122,8 @@ def input(self, input_data=None): ms = genutils.get_macro_server() interfaces = ms.getInterfaces() if data_type in interfaces: - input_data['data_type'] = [ elem.name for elem in interfaces[data_type].values() ] + input_data['data_type'] = [ + elem.name for elem in interfaces[data_type].values()] self._conn.send(input_data) ret = self._conn.recv() return ret @@ -130,7 +131,7 @@ def input(self, input_data=None): def input_timeout(self, input_data): # parent process self._conn.send(input_data) - + def safe_run(self, conn): # child process try: @@ -139,7 +140,7 @@ def safe_run(self, conn): msgbox = TaurusMessageBox(*sys.exc_info()) conn.send((e, False)) msgbox.exec_() - + def run(self, conn): # child process self._conn = conn @@ -152,7 +153,7 @@ def run(self, conn): app.exec_() conn.close() print "Quit input handler" - + def run_forever(self): # child process message, conn = True, self._conn @@ -164,4 +165,3 @@ def run_forever(self): app = Qt.QApplication.instance() if app: app.quit() - diff --git a/src/sardana/spock/ipython_00_10/__init__.py b/src/sardana/spock/ipython_00_10/__init__.py index 120e183f51..7d0819f924 100644 --- a/src/sardana/spock/ipython_00_10/__init__.py +++ b/src/sardana/spock/ipython_00_10/__init__.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/spock/ipython_00_10/genutils.py b/src/sardana/spock/ipython_00_10/genutils.py index 61be5f7a3e..0d28a53c68 100644 --- a/src/sardana/spock/ipython_00_10/genutils.py +++ b/src/sardana/spock/ipython_00_10/genutils.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -32,7 +32,7 @@ 'translate_version_str2int', 'get_ipython_version', 'get_ipython_version_number', 'get_python_version', 'get_python_version_number', 'get_ipython_dir', - 'get_ipython_profiles', 'get_spock_profiles', + 'get_ipython_profiles', 'get_spock_profiles', 'get_non_spock_profiles', 'get_spock_user_profile_module', 'get_pytango_version', 'get_pytango_version_number', 'get_server_for_device', 'get_macroserver_for_door', @@ -46,8 +46,8 @@ 'init_console', 'init_magic', 'init_pre_spock', 'init_post_spock', 'init_spock', 'start', 'mainloop', 'run', 'load_ipython_extension', 'unload_ipython_extension', 'load_config', - 'MSG_FAILED','MSG_FAILED_WR', 'MSG_R', 'MSG_ERROR', - 'MSG_DONE', 'MSG_OK' ] + 'MSG_FAILED', 'MSG_FAILED_WR', 'MSG_R', 'MSG_ERROR', + 'MSG_DONE', 'MSG_OK'] __docformat__ = 'restructuredtext' @@ -79,15 +79,15 @@ requirements = { -# module minimum recommended - "IPython" : ("0.10.0", "0.10.0"), - "Python" : ("2.6.0", "2.6.0"), - "PyTango" : ("7.1.2", "7.2.0"), + # module minimum recommended + "IPython": ("0.10.0", "0.10.0"), + "Python": ("2.6.0", "2.6.0"), + "PyTango": ("7.1.2", "7.2.0"), # for the moment just for reference since itango does not provide version # when using PyTango < 9 the dependency is >= 0.0.1 and < 0.1.0 # when using PyTango >= 9 the dependency is >= 0.1.6 - "itango" : ("0.0.1", "0.0.1"), - "taurus.core" : ("2.0.0", "2.1.0") + "itango": ("0.0.1", "0.0.1"), + "taurus.core": ("2.0.0", "2.1.0") } ENV_NAME = "_E" @@ -96,6 +96,7 @@ # IPython utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def get_gui_mode(): if '-q4thread' in sys.argv: return 'qt' @@ -105,19 +106,24 @@ def get_gui_mode(): return 'wx' return '' + def get_pylab_mode(): return get_gui_mode() - + + def get_color_mode(): return get_ipapi().options.colors - + + def get_ipapi(): return IPython.ipapi.get() + def get_editor(): return get_ipapi().options.editor -def ask_yes_no(prompt,default=None): + +def ask_yes_no(prompt, default=None): """Asks a question and returns a boolean (y/n) answer. If default is given (one of 'y','n'), it is used if the user input is @@ -132,8 +138,10 @@ def ask_yes_no(prompt,default=None): prompt = '%s [%s]' % (prompt, default) return IPython.genutils.ask_yes_no(prompt, default) + def spock_input(prompt='', ps2='... '): - return IPython.genutils.raw_input_ext(prompt=prompt, ps2=ps2) + return IPython.genutils.raw_input_ext(prompt=prompt, ps2=ps2) + def translate_version_str2int(version_str): """Translates a version string in format x[.y[.z[...]]] into a 000000 number""" @@ -142,37 +150,43 @@ def translate_version_str2int(version_str): num_version_str = version_str.split('-')[0] parts = num_version_str.split('.') i, v, l = 0, 0, len(parts) - if not l: return v - while i<3: + if not l: + return v + while i < 3: try: - v += int(parts[i])*int(math.pow(10,(2-i)*2)) + v += int(parts[i]) * int(math.pow(10, (2 - i) * 2)) l -= 1 i += 1 except ValueError: return v - if not l: return v + if not l: + return v return v - + try: - v += 10000*int(parts[0]) + v += 10000 * int(parts[0]) l -= 1 except ValueError: return v - if not l: return v - + if not l: + return v + try: - v += 100*int(parts[1]) + v += 100 * int(parts[1]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v try: v += int(parts[0]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v + def get_ipython_version(): """Returns the current IPython version""" @@ -189,41 +203,47 @@ def get_ipython_version(): pass return v + def get_ipython_version_number(): """Returns the current IPython version number""" ipyver_str = get_ipython_version() - if ipyver_str is None: return None + if ipyver_str is None: + return None return translate_version_str2int(ipyver_str) + def get_python_version(): - return '.'.join(map(str,sys.version_info[:3])) + return '.'.join(map(str, sys.version_info[:3])) + def get_python_version_number(): pyver_str = get_python_version() return translate_version_str2int(pyver_str) + def get_ipython_dir(): """Find the ipython local directory. Usually is /.ipython""" if hasattr(itango, "get_ipython_dir"): return itango.get_ipython_dir() - + if hasattr(IPython.iplib, 'get_ipython_dir'): # Starting from ipython 0.9 they hadded this method return IPython.iplib.get_ipython_dir() - - # Try to find the profile in the current directory and then in the + + # Try to find the profile in the current directory and then in the # default IPython dir #userdir = os.path.realpath(os.path.curdir) home_dir = IPython.genutils.get_home_dir() - + if os.name == 'posix': ipdir = '.ipython' else: ipdir = '_ipython' ipdir = os.path.join(home_dir, ipdir) - ipythondir = os.path.abspath( os.environ.get('IPYTHONDIR', ipdir) ) + ipythondir = os.path.abspath(os.environ.get('IPYTHONDIR', ipdir)) return ipythondir + def get_ipython_profiles(): """Helper function to find all ipython profiles""" if hasattr(itango, "get_ipython_profiles"): @@ -239,6 +259,7 @@ def get_ipython_profiles(): ret.append(i[len("ipy_profile_"):i.rfind(".")]) return ret + def get_spock_profiles(ipython_profiles=None): """Helper function to find all spock ipython profiles""" ret = [] @@ -250,10 +271,12 @@ def get_spock_profiles(ipython_profiles=None): ret = [] for profile in ipython_profiles: profile_f = os.path.join(ipydir, "ipy_profile_%s.py" % profile) - if not os.path.isfile(profile_f): continue + if not os.path.isfile(profile_f): + continue try: for i, l in enumerate(file(profile_f)): - if i > 10: break + if i > 10: + break if l.find("spock_creation_version") >= 0: ret.append(profile) break @@ -261,6 +284,7 @@ def get_spock_profiles(ipython_profiles=None): pass return ret + def get_non_spock_profiles(ipython_profiles=None): """Helper function to find all non spock ipython profiles""" if ipython_profiles is None: @@ -269,13 +293,15 @@ def get_non_spock_profiles(ipython_profiles=None): spock_profiles = set(get_spock_profiles(ipython_profiles=ipython_profiles)) return ipython_profiles.difference(spock_profiles) + def get_spock_user_profile_module(profile_name): return 'ipy_profile_%s' % profile_name - + #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # PyTango utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def get_pytango_version(): try: import PyTango @@ -286,11 +312,14 @@ def get_pytango_version(): except: return '0.0.0' + def get_pytango_version_number(): tgver_str = get_pytango_version() - if tgver_str is None: return None + if tgver_str is None: + return None return translate_version_str2int(tgver_str) - + + def get_server_for_device(device_name): db = get_tango_db() device_name = device_name.lower() @@ -300,7 +329,8 @@ def get_server_for_device(device_name): if dev.lower() == device_name: return server return None - + + def get_macroserver_for_door(door_name): """Returns the MacroServer device name in the same DeviceServer as the given door device""" @@ -321,7 +351,8 @@ def get_macroserver_for_door(door_name): else: return None -def get_device_from_user(expected_class, dft = None): + +def get_device_from_user(expected_class, dft=None): """Gets a device of the given device class from user input""" dft = print_dev_from_class(expected_class, dft) prompt = "%s name from the list" % expected_class @@ -329,32 +360,33 @@ def get_device_from_user(expected_class, dft = None): prompt += "[%s]" % dft prompt += "? " from_user = raw_input(prompt).strip() or dft - + name = '' try: full_name, name, alias = from_name_to_tango(from_user) except: print "Warning: the given %s does not exist" % expected_class - return name - + return name + try: db = get_tango_db() cl_name = db.get_class_for_device(name) class_correct = cl_name == expected_class if not class_correct: - print "Warning: the given name is not a %s (it is a %s)"%(expected_class,cl_name) + print "Warning: the given name is not a %s (it is a %s)" % (expected_class, cl_name) except Exception as e: print "Warning: unable to confirm if '%s' is valid" % name print str(e) return full_name + def get_tango_db(): tg_host = PyTango.ApiUtil.get_env_var("TANGO_HOST") db = None if tg_host is None: - host,port = get_tango_host_from_user() - tg_host = "%s:%d" % (host,port) + host, port = get_tango_host_from_user() + tg_host = "%s:%d" % (host, port) os.environ["TANGO_HOST"] = tg_host db = PyTango.Database() else: @@ -362,19 +394,20 @@ def get_tango_db(): db = PyTango.Database() except: # tg host is not valid. Find a valid one - host,port = get_tango_host_from_user() - tg_host = "%s:%d" % (host,port) + host, port = get_tango_host_from_user() + tg_host = "%s:%d" % (host, port) os.environ["TANGO_HOST"] = tg_host - + db = PyTango.Database() return db + def get_tango_host_from_user(): - while True: + while True: prompt = "Please enter a valid tango host (:): " from_user = raw_input(prompt).strip() - + try: host, port = from_user.split(':') try: @@ -382,10 +415,10 @@ def get_tango_host_from_user(): try: socket.gethostbyname(host) try: - db = PyTango.Database(host,port) + db = PyTango.Database(host, port) return db.get_db_host(), db.get_db_port() except: - exp = "No tango database found at %s:%d" % (host,port) + exp = "No tango database found at %s:%d" % (host, port) except: exp = "Invalid host name %s" % host except: @@ -395,7 +428,8 @@ def get_tango_host_from_user(): exp = "Invalid tango host. %s " % exp print exp -def print_dev_from_class(classname, dft = None): + +def print_dev_from_class(classname, dft=None): db = get_tango_db() pytg_ver = get_pytango_version_number() @@ -408,39 +442,43 @@ def print_dev_from_class(classname, dft = None): else: server_wildcard = '%' exp_dev_list = [] - + res = None - dev_list = db.get_device_name(server_wildcard,classname) - tg_host = "%s:%s" % (db.get_db_host(),db.get_db_port()) - print "Available",classname,"devices from",tg_host,":" + dev_list = db.get_device_name(server_wildcard, classname) + tg_host = "%s:%s" % (db.get_db_host(), db.get_db_port()) + print "Available", classname, "devices from", tg_host, ":" for dev in dev_list: full_name, name, alias = from_name_to_tango(dev) out = alias or name - if alias: out += ' (a.k.a. %s)' % name - out = "%-25s" % out + if alias: + out += ' (a.k.a. %s)' % name + out = "%-25s" % out if dev in exp_dev_list: out += " (running)" print out if dft: - if dft.lower() == name.lower(): res = name - elif not alias is None and dft.lower() == alias.lower(): res = alias - + if dft.lower() == name.lower(): + res = name + elif not alias is None and dft.lower() == alias.lower(): + res = alias + return res - + + def from_name_to_tango(name): - + db = get_tango_db() - + alias = None - + c = name.count('/') # if the db prefix is there, remove it first if c == 3 or c == 1: - name = name[name.index("/")+1:] - + name = name[name.index("/") + 1:] + elems = name.split('/') l = len(elems) - + if l == 3: try: alias = db.get_alias(name) @@ -453,7 +491,7 @@ def from_name_to_tango(name): name = db.get_device_alias(alias) else: raise Exception("Invalid device name '%s'" % name) - + full_name = "%s:%s/%s" % (db.get_db_host(), db.get_db_port(), name) return full_name, name, alias @@ -461,60 +499,72 @@ def from_name_to_tango(name): # taurus utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def clean_up(): taurus.Manager().cleanUp() + def get_taurus_core_version(): try: import taurus return taurus.core.release.version except: return '0.0.0' - + + def get_taurus_core_version_number(): tgver_str = get_taurus_core_version() - if tgver_str is None: return None + if tgver_str is None: + return None return translate_version_str2int(tgver_str) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Requirements checking #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def check_requirements(): r = requirements minPyTango, recPyTango = map(translate_version_str2int, r["PyTango"]) minIPython, recIPython = map(translate_version_str2int, r["IPython"]) minPython, recPython = map(translate_version_str2int, r["Python"]) - minTaurusCore, recTaurusCore = map(translate_version_str2int, r["taurus.core"]) - + minTaurusCore, recTaurusCore = map( + translate_version_str2int, r["taurus.core"]) + currPython = get_python_version_number() currIPython = get_ipython_version_number() currPyTango = get_pytango_version_number() currTaurusCore = get_taurus_core_version_number() - + errMsg = "" warnMsg = "" - + errPython, errIPython, errPyTango, errTaurusCore = False, False, False, False if currPython is None: - errMsg += "Spock needs Python version >= %s. No python installation found\n" % requirements["Python"][0] + errMsg += "Spock needs Python version >= %s. No python installation found\n" % requirements[ + "Python"][0] errPython = True elif currPython < minPython: - errMsg += "Spock needs Python version >= %s. Current version is %s\n" % (requirements["Python"][0], get_python_version()) + errMsg += "Spock needs Python version >= %s. Current version is %s\n" % ( + requirements["Python"][0], get_python_version()) errPython = True if currIPython is None: - errMsg += "Spock needs IPython version >= %s. No IPython installation found\n" % requirements["IPython"][0] + errMsg += "Spock needs IPython version >= %s. No IPython installation found\n" % requirements[ + "IPython"][0] errIPython = True elif currIPython < minIPython: - errMsg += "Spock needs IPython version >= %s. Current version is %s\n" % (requirements["IPython"][0], get_ipython_version()) + errMsg += "Spock needs IPython version >= %s. Current version is %s\n" % ( + requirements["IPython"][0], get_ipython_version()) errIPython = True if currPyTango is None: - errMsg += "Spock needs PyTango version >= %s. No PyTango installation found\n" % requirements["IPython"][0] + errMsg += "Spock needs PyTango version >= %s. No PyTango installation found\n" % requirements[ + "IPython"][0] errPyTango = True elif currPyTango < minPyTango: - errMsg += "Spock needs PyTango version >= %s. " % requirements["PyTango"][0] + errMsg += "Spock needs PyTango version >= %s. " % requirements[ + "PyTango"][0] if currPyTango > 0: errMsg += "Current version is %s\n" % get_pytango_version() else: @@ -528,60 +578,70 @@ def check_requirements(): errMsg += "Spock needs itango version >= 0.0.1, < 0.1.0 (PyTango < 9) or version >= 0.1.6 (PyTanog >= 9). No itango installation found\n" if currTaurusCore is None: - errMsg += "Spock needs taurus.core version >= %s. No taurus.core installation found\n" % requirements["taurus.core"][0] + errMsg += "Spock needs taurus.core version >= %s. No taurus.core installation found\n" % requirements[ + "taurus.core"][0] errTaurusCore = True elif currTaurusCore < minTaurusCore: - errMsg += "Spock needs taurus.core version >= %s. " % requirements["taurus.core"][0] + errMsg += "Spock needs taurus.core version >= %s. " % requirements[ + "taurus.core"][0] if currTaurusCore > 0: errMsg += "Current version is %s\n" % get_taurus_core_version() else: errMsg += "Current version is unknown (most surely too old)\n" errTaurusCore = True - + # Warnings if not errPython and currPython < recPython: - warnMsg += "Spock recommends Python version >= %s. Current version is %s\n" % (requirements["Python"][1], get_python_version()) + warnMsg += "Spock recommends Python version >= %s. Current version is %s\n" % ( + requirements["Python"][1], get_python_version()) if not errIPython and currIPython < recIPython: - warnMsg += "Spock recommends IPython version >= %s. Current version is %s\n" % (requirements["IPython"][1], get_ipython_version()) + warnMsg += "Spock recommends IPython version >= %s. Current version is %s\n" % ( + requirements["IPython"][1], get_ipython_version()) if not errPyTango and currPyTango < recPyTango: - warnMsg += "Spock recommends PyTango version >= %s. Current version is %s\n" % (requirements["PyTango"][1], get_pytango_version()) - + warnMsg += "Spock recommends PyTango version >= %s. Current version is %s\n" % ( + requirements["PyTango"][1], get_pytango_version()) + if not errTaurusCore and currTaurusCore < recTaurusCore: - warnMsg += "Spock recommends taurus.core version >= %s. Current version is %s\n" % (requirements["taurus.core"][1], get_taurus_core_version()) + warnMsg += "Spock recommends taurus.core version >= %s. Current version is %s\n" % ( + requirements["taurus.core"][1], get_taurus_core_version()) if errMsg: errMsg += warnMsg raise exception.SpockMissingRequirement, errMsg - if warnMsg: + if warnMsg: raise exception.SpockMissingRecommended, warnMsg - + return True + def _get_dev(dev_type): ip = get_ipapi() ret = ip.user_ns.get("_" + dev_type) if ret is not None: return ret - + dev_obj_name = '%s_NAME' % dev_type # TODO: For Taurus 4 compatibility dev_name = "tango://%s" % ip.user_ns[dev_obj_name] factory = Factory() dev_obj = factory.getDevice(dev_name) - ip.user_ns[dev_type] = PyTango.DeviceProxy(dev_name) + ip.user_ns[dev_type] = PyTango.DeviceProxy(dev_name) ip.user_ns["_" + dev_type] = dev_obj setattr(ip, '_%s' % dev_type, dev_obj) return dev_obj + def get_door(): return _get_dev('DOOR') + def get_macro_server(): return _get_dev('MACRO_SERVER') + def _macro_completer(self, event): """Method called by the IPython autocompleter. It will determine possible values for macro arguments. @@ -589,14 +649,16 @@ def _macro_completer(self, event): ms = get_macro_server() macro_name = event.command.lstrip('%') - + # calculate parameter index param_idx = len(event.line.split()) - 1 - if not event.line.endswith(' '): param_idx -= 1 + if not event.line.endswith(' '): + param_idx -= 1 # get macro info info = ms.getMacroInfoObj(macro_name) # if macro doesn't have parameters return - if param_idx < 0 or not info.hasParams() : return + if param_idx < 0 or not info.hasParams(): + return # get the parameter info possible_params = info.getPossibleParams(param_idx) # return the existing elements for the given parameter type @@ -605,43 +667,49 @@ def _macro_completer(self, event): for param in possible_params: res.extend(ms.getElementNamesWithInterface(param['type'])) return res - + + def expose_magic(name, fn, completer_func=_macro_completer): ip = get_ipapi() ip.expose_magic(name, fn) - + if completer_func is None: return - + # enable macro param completion - ip.set_hook('complete_command', completer_func, str_key = name) + ip.set_hook('complete_command', completer_func, str_key=name) # register also when the command as is typed with the magic prefix '%' name = str('%') + name - ip.set_hook('complete_command', completer_func, str_key = name) - + ip.set_hook('complete_command', completer_func, str_key=name) + + def unexpose_magic(name): ip = get_ipapi() mg = 'magic_%s' % name delattr(ip.IP, mg) + def expose_variable(name, value): - get_ipapi().to_user_ns({ name : value }) + get_ipapi().to_user_ns({name: value}) + def unexpose_variable(name): user_ns = get_ipapi().user_ns del user_ns[name] - + + def expose_variables(d): get_ipapi().to_user_ns(d) -#def _expose_device(name): +# def _expose_device(name): # ip.to_user_ns({ name : PyTango.DeviceProxy(name) }) - -#def expose_device(name): + +# def expose_device(name): # ip = get_ipapi() # ip.magic("bg _expose_device(%s)" % name) + def create_spock_profile(userdir, dft_profile, profile, door_name=None): """Create a profile file from a profile template file """ @@ -664,7 +732,7 @@ def main(): main() """ - + # # Discover door name # @@ -673,25 +741,25 @@ def main(): else: full_door_name, door_name, door_alias = from_name_to_tango(door_name) door_name = full_door_name - + # # Discover macro server name # ms_name = get_macroserver_for_door(door_name) - + dest_data = src_data.format(version=release.version, macroserver_name=ms_name, door_name=door_name) - + f_name = '%s.py' % get_spock_user_profile_module(profile) - + dest_name = os.path.join(userdir, f_name) - + sys.stdout.write('Storing %s in %s... ' % (f_name, userdir)) sys.stdout.flush() res = MSG_FAILED try: - dest = open(dest_name,"w") + dest = open(dest_name, "w") dest.write(dest_data) dest.flush() dest.close() @@ -700,35 +768,37 @@ def main(): sys.stdout.write(res + '\n') sys.stdout.flush() + def check_for_upgrade(ipy_profile_file, ipythondir, session, profile): # Check if the current profile is up to date with the spock version spock_profile_ver_str = '0.0.0' door_name = None - + # search for version and door inside the ipy_profile file for i, line in enumerate(ipy_profile_file): - if i > 20 : break; # give up after 20 lines + if i > 20: + break # give up after 20 lines if line.startswith('# spock_creation_version = '): - spock_profile_ver_str = line[line.index('=')+1:].strip() + spock_profile_ver_str = line[line.index('=') + 1:].strip() if line.startswith('# door_name = '): - door_name = line[line.index('=')+1:].strip() - + door_name = line[line.index('=') + 1:].strip() + # convert version from string to numbers spock_lib_ver_str = release.version spocklib_ver = translate_version_str2int(spock_lib_ver_str) spock_profile_ver = translate_version_str2int(spock_profile_ver_str) - + alpha_in_spock_profile = "-alpha" in spock_profile_ver_str - alpha_in_spock_lib = "-alpha" in spock_lib_ver_str + alpha_in_spock_lib = "-alpha" in spock_lib_ver_str if spocklib_ver == spock_profile_ver and \ - alpha_in_spock_profile == alpha_in_spock_lib: + alpha_in_spock_profile == alpha_in_spock_lib: return if spocklib_ver < spock_profile_ver: print '%sYour spock profile (%s) is newer than your spock version ' \ '(%s)!' % (TermColors.Brown, spock_profile_ver_str, spock_lib_ver_str) print 'Please upgrade spock or delete the current profile %s' % TermColors.Normal sys.exit(1) - + # there was no version track of spock profiles since spock 0.2.0 so change # the message if spock_profile_ver_str == '0.0.0': @@ -743,16 +813,17 @@ def check_for_upgrade(ipy_profile_file, ipythondir, session, profile): create_spock_profile(ipythondir, session, profile, door_name) sys.exit(0) + def get_args(argv): - + script_name = argv[0] script_dir, session = os.path.split(script_name) script_name = os.path.realpath(script_name) #script_dir = os.path.dirname(script_name) - + macro_server = None door = None - + # Define the profile file profile = "spockdoor" try: @@ -763,12 +834,12 @@ def get_args(argv): pass profile_modulename = get_spock_user_profile_module(profile) - - # Try to find the profile in the current directory and then in the + + # Try to find the profile in the current directory and then in the # default IPython dir #userdir = os.path.realpath(os.path.curdir) ipythondir = get_ipython_dir() - + if not os.path.isdir(ipythondir): # Platform-dependent suffix. if os.name == 'posix': @@ -777,33 +848,34 @@ def get_args(argv): rc_suffix = '.ini' IPython.iplib.user_setup(ipythondir, rc_suffix, mode='install', interactive=False) - + try: f, name, t = imp.find_module(profile_modulename, [ipythondir]) check_for_upgrade(f, ipythondir, session, profile) except ImportError: # Create a new profile r = '' - while not r in ['y','n']: + while not r in ['y', 'n']: prompt = 'Profile \'%s\' does not exist. Do you want to create '\ 'one now ([y]/n)? ' % profile r = raw_input(prompt) or 'y' if r.lower() == 'y': create_spock_profile(ipythondir, session, profile) else: - sys.stdout.write('No spock door extension profile was created. Starting normal spock...\n') + sys.stdout.write( + 'No spock door extension profile was created. Starting normal spock...\n') sys.stdout.flush() profile = '' - + # inform the shell of the profile it should use if not '-p' in argv and profile: argv.append('-p') argv.append(profile) - - user_ns = { 'MACRO_SERVER_NAME' : macro_server, - 'DOOR_NAME' : door, - 'PROFILE' : profile } - + + user_ns = {'MACRO_SERVER_NAME': macro_server, + 'DOOR_NAME': door, + 'PROFILE': profile} + return user_ns #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @@ -814,14 +886,15 @@ def get_args(argv): MSG_R = '[%s%%s%s]' % (TermColors.Red, TermColors.Normal) MSG_FAILED = MSG_R % 'FAILED' MSG_FAILED_WR = MSG_R % 'FAILED: %s' -MSG_ERROR = MSG_R % 'ERROR' -MSG_DONE = MSG_G % 'DONE' -MSG_OK = MSG_G % 'OK' +MSG_ERROR = MSG_R % 'ERROR' +MSG_DONE = MSG_G % 'DONE' +MSG_OK = MSG_G % 'OK' #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # initialization methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def init_console(ip): # Handy tab-completers for %cd, %run, import etc. # Try commenting this out if you have completion problems/slowness @@ -832,17 +905,17 @@ def init_console(ip): ipyver = get_ipython_version() pytangover = get_pytango_version() tauruscorever = get_taurus_core_version() - + TermColors = IPython.ColorANSI.TermColors - - d = { "version" : spockver, - "pyver" : pyver, - "ipyver" : ipyver, - "pytangover" : pytangover, - "taurusver" : tauruscorever, - "profile" : ip.user_ns["PROFILE"], - "door" : ip.user_ns["DOOR_ALIAS"] } - + + d = {"version": spockver, + "pyver": pyver, + "ipyver": ipyver, + "pytangover": pytangover, + "taurusver": tauruscorever, + "profile": ip.user_ns["PROFILE"], + "door": ip.user_ns["DOOR_ALIAS"]} + d.update(TermColors.__dict__) # IPython options @@ -910,6 +983,7 @@ def init_console(ip): o.banner = banner + def init_magic(ip): import sardana.spock.magic magic = sardana.spock.magic @@ -924,6 +998,7 @@ def init_magic(ip): ip.set_hook('late_startup_hook', magic.spock_late_startup_hook) ip.set_hook('pre_prompt_hook', magic.spock_pre_prompt_hook) + def init_pre_spock(ip, macro_server, door): so = IPython.ipstruct.Struct() full_door_tg_name, door_tg_name, door_tg_alias = from_name_to_tango(door) @@ -935,14 +1010,14 @@ def init_pre_spock(ip, macro_server, door): ip.user_ns['DOOR_ALIAS'] = door_tg_alias or door_tg_name ip.user_ns['DOOR_STATE'] = "" ip.user_ns['spock_options'] = so - + if ip.IP.alias_table.has_key('mv'): del ip.IP.alias_table['mv'] - + v = release.version alias = ip.user_ns['DOOR_ALIAS'] profile = ip.user_ns['PROFILE'] - + so.spock_banner = """\ {Blue}Spock's sardana extension %s loaded with profile: %s (linked to door '%s'){Normal} """ % (v, profile, alias) @@ -951,23 +1026,23 @@ def init_pre_spock(ip, macro_server, door): # request for it in the first event at startup in different threads # therefore this small hack: make sure CodecFactory is initialized. CodecFactory() - + factory = Factory() import sardana.spock.spockms macroserver = sardana.spock.spockms factory.registerDeviceClass('MacroServer', macroserver.SpockMacroServer) - + mode = get_gui_mode() if mode == 'qt': factory.registerDeviceClass('Door', macroserver.QSpockDoor) else: factory.registerDeviceClass('Door', macroserver.SpockDoor) - + door = get_door() macro_server = get_macro_server() - + # Initialize the environment expose_variable(ENV_NAME, macro_server.getEnvironment()) @@ -975,7 +1050,8 @@ def init_pre_spock(ip, macro_server, door): def init_post_spock(ip): init_console(ip) init_magic(ip) - + + def init_spock(ip, macro_server, door): init_pre_spock(ip, macro_server, door) itango.init_ipython(ip) @@ -983,8 +1059,10 @@ def init_spock(ip, macro_server, door): def start(user_ns=None): - if '-pylab' not in sys.argv: sys.argv.insert(1, '-pylab') - if '-q4thread' not in sys.argv: sys.argv.insert(1, '-q4thread') + if '-pylab' not in sys.argv: + sys.argv.insert(1, '-pylab') + if '-q4thread' not in sys.argv: + sys.argv.insert(1, '-q4thread') # Make sure the log level is changed to warning from taurus.core.taurushelper import setLogLevel, Warning @@ -998,7 +1076,7 @@ def start(user_ns=None): sys.exit(-1) except exception.SpockMissingRecommended, recommended: print str(recommended) - + user_ns = user_ns or {} try: user_ns.update(get_args(sys.argv)) @@ -1011,14 +1089,16 @@ def start(user_ns=None): except Exception, e: print 'spock exited with an unmanaged exception: %s' % str(e) sys.exit(-2) - + return IPython.Shell.start(user_ns=user_ns) + def mainloop(shell=None, user_ns=None): if shell is None: shell = start(user_ns) shell.mainloop() + def run(user_ns=None): # initialize input handler as soon as possible import sardana.spock.inputhandler @@ -1034,12 +1114,15 @@ def run(user_ns=None): # for compatibility reasons with new IPython API (>=0.11) we add the following # empty methods - + + def load_ipython_extension(ipython): pass + def unload_ipython_extension(ipython): pass - + + def load_config(config): pass diff --git a/src/sardana/spock/ipython_00_11/__init__.py b/src/sardana/spock/ipython_00_11/__init__.py index a2538b79a5..75fadda7c9 100644 --- a/src/sardana/spock/ipython_00_11/__init__.py +++ b/src/sardana/spock/ipython_00_11/__init__.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/spock/ipython_00_11/genutils.py b/src/sardana/spock/ipython_00_11/genutils.py index a35bd8477f..c3bcb66e4e 100644 --- a/src/sardana/spock/ipython_00_11/genutils.py +++ b/src/sardana/spock/ipython_00_11/genutils.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -84,15 +84,15 @@ SpockTermColors = colors.TermColors requirements = { -# module minimum recommended - "IPython" : ("0.11.0", "0.12.0"), - "Python" : ("2.6.0", "2.6.0"), - "PyTango" : ("7.2.0", "7.2.3"), + # module minimum recommended + "IPython": ("0.11.0", "0.12.0"), + "Python": ("2.6.0", "2.6.0"), + "PyTango": ("7.2.0", "7.2.3"), # for the moment just for reference since itango does not provide version # when using PyTango < 9 the dependency is >= 0.0.1 and < 0.1.0 # when using PyTango >= 9 the dependency is >= 0.1.6 - "itango" : ("0.0.1", "0.0.1"), - "taurus.core" : ("3.0.0", "3.0.0") + "itango": ("0.0.1", "0.0.1"), + "taurus.core": ("3.0.0", "3.0.0") } ENV_NAME = "_E" @@ -101,34 +101,43 @@ # IPython utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def get_gui_mode(): return 'qt' + def get_pylab_mode(): return get_app().pylab + def get_color_mode(): return get_config().InteractiveShell.colors + def get_app(): - #return TerminalIPythonApp.instance() + # return TerminalIPythonApp.instance() return Application.instance() + def get_shell(): """Get the global InteractiveShell instance.""" return get_app().shell + def get_ipapi(): """Get the global InteractiveShell instance.""" return InteractiveShell.instance() + def get_config(): return get_app().config + def get_editor(): return get_ipapi().editor -def ask_yes_no(prompt,default=None): + +def ask_yes_no(prompt, default=None): """Asks a question and returns a boolean (y/n) answer. If default is given (one of 'y','n'), it is used if the user input is @@ -143,9 +152,11 @@ def ask_yes_no(prompt,default=None): prompt = '%s [%s]' % (prompt, default) return _ask_yes_no(prompt, default) + def spock_input(prompt='', ps2='... '): return _raw_input_ext(prompt=prompt, ps2=ps2) + def translate_version_str2int(version_str): """Translates a version string in format x[.y[.z[...]]] into a 000000 number""" import math @@ -153,37 +164,43 @@ def translate_version_str2int(version_str): num_version_str = version_str.split('-')[0] parts = num_version_str.split('.') i, v, l = 0, 0, len(parts) - if not l: return v - while i<3: + if not l: + return v + while i < 3: try: - v += int(parts[i])*int(math.pow(10,(2-i)*2)) + v += int(parts[i]) * int(math.pow(10, (2 - i) * 2)) l -= 1 i += 1 except ValueError: return v - if not l: return v + if not l: + return v return v try: - v += 10000*int(parts[0]) + v += 10000 * int(parts[0]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v try: - v += 100*int(parts[1]) + v += 100 * int(parts[1]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v try: v += int(parts[0]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v + def get_ipython_version(): """Returns the current IPython version""" @@ -200,19 +217,24 @@ def get_ipython_version(): print e3 return v + def get_ipython_version_number(): """Returns the current IPython version number""" ipyver_str = get_ipython_version() - if ipyver_str is None: return None + if ipyver_str is None: + return None return translate_version_str2int(ipyver_str) + def get_python_version(): - return '.'.join(map(str,sys.version_info[:3])) + return '.'.join(map(str, sys.version_info[:3])) + def get_python_version_number(): pyver_str = get_python_version() return translate_version_str2int(pyver_str) + def get_ipython_profiles(path=None): """list profiles in a given root directory""" if path is None: @@ -222,13 +244,14 @@ def get_ipython_profiles(path=None): for f in files: full_path = os.path.join(path, f) if os.path.isdir(full_path) and f.startswith('profile_'): - profiles.append(f.split('_',1)[-1]) + profiles.append(f.split('_', 1)[-1]) return profiles #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # PyTango utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def get_pytango_version(): try: import PyTango @@ -239,11 +262,14 @@ def get_pytango_version(): except: return None + def get_pytango_version_number(): tgver_str = get_pytango_version() - if tgver_str is None: return None + if tgver_str is None: + return None return translate_version_str2int(tgver_str) + def get_server_for_device(device_name): db = get_tango_db() device_name = device_name.lower() @@ -254,6 +280,7 @@ def get_server_for_device(device_name): return server return None + def get_macroserver_for_door(door_name): """Returns the MacroServer device name in the same DeviceServer as the given door device""" @@ -274,7 +301,8 @@ def get_macroserver_for_door(door_name): else: return None -def get_device_from_user(expected_class, dft = None): + +def get_device_from_user(expected_class, dft=None): """Gets a device of the given device class from user input""" dft = print_dev_from_class(expected_class, dft) prompt = "%s name from the list" % expected_class @@ -295,20 +323,21 @@ def get_device_from_user(expected_class, dft = None): cl_name = db.get_class_for_device(name) class_correct = cl_name == expected_class if not class_correct: - print "Warning: the given name is not a %s (it is a %s)"%(expected_class,cl_name) + print "Warning: the given name is not a %s (it is a %s)" % (expected_class, cl_name) except Exception as e: print "Warning: unable to confirm if '%s' is valid" % name print str(e) return full_name + def get_tango_db(): import PyTango tg_host = PyTango.ApiUtil.get_env_var("TANGO_HOST") db = None if tg_host is None: - host,port = get_tango_host_from_user() - tg_host = "%s:%d" % (host,port) + host, port = get_tango_host_from_user() + tg_host = "%s:%d" % (host, port) os.environ["TANGO_HOST"] = tg_host db = PyTango.Database() else: @@ -316,13 +345,14 @@ def get_tango_db(): db = PyTango.Database() except: # tg host is not valid. Find a valid one - host,port = get_tango_host_from_user() - tg_host = "%s:%d" % (host,port) + host, port = get_tango_host_from_user() + tg_host = "%s:%d" % (host, port) os.environ["TANGO_HOST"] = tg_host db = PyTango.Database() return db + def get_tango_host_from_user(): import PyTango while True: @@ -349,7 +379,8 @@ def get_tango_host_from_user(): exp = "Invalid tango host. %s " % exp print exp -def print_dev_from_class(classname, dft = None): + +def print_dev_from_class(classname, dft=None): db = get_tango_db() pytg_ver = get_pytango_version_number() @@ -364,23 +395,27 @@ def print_dev_from_class(classname, dft = None): exp_dev_list = [] res = None - dev_list = db.get_device_name(server_wildcard,classname) - tg_host = "%s:%s" % (db.get_db_host(),db.get_db_port()) - print "Available",classname,"devices from",tg_host,":" + dev_list = db.get_device_name(server_wildcard, classname) + tg_host = "%s:%s" % (db.get_db_host(), db.get_db_port()) + print "Available", classname, "devices from", tg_host, ":" for dev in dev_list: _, name, alias = from_name_to_tango(dev) out = alias or name - if alias: out += ' (a.k.a. %s)' % name + if alias: + out += ' (a.k.a. %s)' % name out = "%-25s" % out if dev in exp_dev_list: out += " (running)" print out if dft: - if dft.lower() == name.lower(): res = name - elif not alias is None and dft.lower() == alias.lower(): res = alias + if dft.lower() == name.lower(): + res = name + elif not alias is None and dft.lower() == alias.lower(): + res = alias return res + def from_name_to_tango(name): db = get_tango_db() @@ -390,7 +425,7 @@ def from_name_to_tango(name): c = name.count('/') # if the db prefix is there, remove it first if c == 3 or c == 1: - name = name[name.index("/")+1:] + name = name[name.index("/") + 1:] elems = name.split('/') l = len(elems) @@ -415,9 +450,11 @@ def from_name_to_tango(name): # taurus utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def clean_up(): Manager().cleanUp() + def get_taurus_core_version(): try: import taurus @@ -427,21 +464,25 @@ def get_taurus_core_version(): traceback.print_exc() return '0.0.0' + def get_taurus_core_version_number(): tgver_str = get_taurus_core_version() - if tgver_str is None: return None + if tgver_str is None: + return None return translate_version_str2int(tgver_str) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Requirements checking #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def check_requirements(): r = requirements minPyTango, recPyTango = map(translate_version_str2int, r["PyTango"]) minIPython, recIPython = map(translate_version_str2int, r["IPython"]) minPython, recPython = map(translate_version_str2int, r["Python"]) - minTaurusCore, recTaurusCore = map(translate_version_str2int, r["taurus.core"]) + minTaurusCore, recTaurusCore = map( + translate_version_str2int, r["taurus.core"]) currPython = get_python_version_number() currIPython = get_ipython_version_number() @@ -453,24 +494,30 @@ def check_requirements(): errPython, errIPython, errPyTango, errTaurusCore = False, False, False, False if currPython is None: - errMsg += "Spock needs Python version >= %s. No python installation found\n" % requirements["Python"][0] + errMsg += "Spock needs Python version >= %s. No python installation found\n" % requirements[ + "Python"][0] errPython = True elif currPython < minPython: - errMsg += "Spock needs Python version >= %s. Current version is %s\n" % (requirements["Python"][0], get_python_version()) + errMsg += "Spock needs Python version >= %s. Current version is %s\n" % ( + requirements["Python"][0], get_python_version()) errPython = True if currIPython is None: - errMsg += "Spock needs IPython version >= %s. No IPython installation found\n" % requirements["IPython"][0] + errMsg += "Spock needs IPython version >= %s. No IPython installation found\n" % requirements[ + "IPython"][0] errIPython = True elif currIPython < minIPython: - errMsg += "Spock needs IPython version >= %s. Current version is %s\n" % (requirements["IPython"][0], get_ipython_version()) + errMsg += "Spock needs IPython version >= %s. Current version is %s\n" % ( + requirements["IPython"][0], get_ipython_version()) errIPython = True if currPyTango is None: - errMsg += "Spock needs PyTango version >= %s. No PyTango installation found\n" % requirements["IPython"][0] + errMsg += "Spock needs PyTango version >= %s. No PyTango installation found\n" % requirements[ + "IPython"][0] errPyTango = True elif currPyTango < minPyTango: - errMsg += "Spock needs PyTango version >= %s. " % requirements["PyTango"][0] + errMsg += "Spock needs PyTango version >= %s. " % requirements[ + "PyTango"][0] if currPyTango > 0: errMsg += "Current version is %s\n" % get_pytango_version() else: @@ -484,10 +531,12 @@ def check_requirements(): errMsg += "Spock needs itango version >= 0.0.1, < 0.1.0 (PyTango < 9) or version >= 0.1.6 (PyTanog >= 9). No itango installation found\n" if currTaurusCore is None: - errMsg += "Spock needs taurus.core version >= %s. No taurus.core installation found\n" % requirements["taurus.core"][0] + errMsg += "Spock needs taurus.core version >= %s. No taurus.core installation found\n" % requirements[ + "taurus.core"][0] errTaurusCore = True elif currTaurusCore < minTaurusCore: - errMsg += "Spock needs taurus.core version >= %s. " % requirements["taurus.core"][0] + errMsg += "Spock needs taurus.core version >= %s. " % requirements[ + "taurus.core"][0] if currTaurusCore > 0: errMsg += "Current version is %s\n" % get_taurus_core_version() else: @@ -524,6 +573,7 @@ def check_requirements(): return True + def _get_dev(dev_type): spock_config = get_config().Spock taurus_dev = None @@ -545,12 +595,15 @@ def _get_dev(dev_type): shell.user_ns["_" + dev_type_upper] = taurus_dev return taurus_dev + def get_door(): return _get_dev('door') + def get_macro_server(): return _get_dev('macro_server') + def _macro_completer(self, event): """Method called by the IPython autocompleter. It will determine possible values for macro arguments. @@ -560,11 +613,13 @@ def _macro_completer(self, event): macro_name = event.command.lstrip('%') # calculate parameter index param_idx = len(event.line.split()) - 1 - if not event.line.endswith(' '): param_idx -= 1 + if not event.line.endswith(' '): + param_idx -= 1 # get macro info info = ms.getMacroInfoObj(macro_name) # if macro doesn't have parameters return - if param_idx < 0 or not info.hasParams() : return + if param_idx < 0 or not info.hasParams(): + return # get the parameter info possible_params = info.getPossibleParams(param_idx) # return the existing elements for the given parameter type @@ -574,6 +629,7 @@ def _macro_completer(self, event): res.extend(ms.getElementNamesWithInterface(param['type'])) return res + def expose_magic(name, fn, completer_func=_macro_completer): shell = get_shell() fn.old_magic = shell.define_magic(name, fn) @@ -584,28 +640,33 @@ def expose_magic(name, fn, completer_func=_macro_completer): # enable macro param completion if completer_func is not None: - shell.set_hook('complete_command', completer_func, str_key = name) - shell.set_hook('complete_command', completer_func, str_key = '%'+name) + shell.set_hook('complete_command', completer_func, str_key=name) + shell.set_hook('complete_command', completer_func, str_key='%' + name) + def unexpose_magic(name): shell = get_shell() mg_name = 'magic_' + name if hasattr(shell, mg_name): - magic_fn = getattr(shell, mg_name) + magic_fn = getattr(shell, mg_name) delattr(shell, mg_name) if hasattr(magic_fn, 'old_magic') and magic_fn.old_magic is not None: expose_magic(name, magic_fn.old_magic, magic_fn.old_completer) + def expose_variable(name, value): get_shell().user_ns[name] = value + def expose_variables(d): get_shell().user_ns.update(d) + def unexpose_variable(name): user_ns = get_shell().user_ns del user_ns[name] + def _create_config_file(location, door_name=None): config_file_name = BaseIPythonApplication.config_file_name.default_value abs_config_file_name = os.path.join(location, config_file_name) @@ -657,12 +718,12 @@ def _create_config_file(location, door_name=None): sys.stdout.write('Storing %s in %s... ' % (config_file_name, location)) sys.stdout.flush() - with file(abs_config_file_name, "w") as f: f.write(dest_data) f.close() sys.stdout.write(MSG_DONE + '\n') + def create_spock_profile(userdir, profile, door_name=None): """Create spock profile directory and configuration file from a template file @@ -679,6 +740,7 @@ def create_spock_profile(userdir, profile, door_name=None): _create_config_file(ipy_profile_dir) + def upgrade_spock_profile(ipy_profile_dir, door_name): """Upgrade spock profile by recreating configuration file from scratch @@ -687,6 +749,7 @@ def upgrade_spock_profile(ipy_profile_dir, door_name): """ _create_config_file(ipy_profile_dir, door_name) + def check_for_upgrade(ipy_profile_dir): """Check if the current profile is up to date with the spock version @@ -701,11 +764,12 @@ def check_for_upgrade(ipy_profile_dir): # search for version and door inside the ipy_profile file with file(abs_config_file_name, "r") as ipy_config_file: for i, line in enumerate(ipy_config_file): - if i > 20 : break; # give up after 20 lines + if i > 20: + break # give up after 20 lines if line.startswith('# spock_creation_version = '): - spock_profile_ver_str = line[line.index('=')+1:].strip() + spock_profile_ver_str = line[line.index('=') + 1:].strip() if line.startswith('# door_name = '): - door_name = line[line.index('=')+1:].strip() + door_name = line[line.index('=') + 1:].strip() # convert version from string to numbers spock_lib_ver_str = release.version @@ -713,13 +777,14 @@ def check_for_upgrade(ipy_profile_dir): spock_profile_ver = translate_version_str2int(spock_profile_ver_str) alpha_in_spock_profile = "-alpha" in spock_profile_ver_str - alpha_in_spock_lib = "-alpha" in spock_lib_ver_str + alpha_in_spock_lib = "-alpha" in spock_lib_ver_str if spocklib_ver == spock_profile_ver and \ alpha_in_spock_profile == alpha_in_spock_lib: return if spocklib_ver < spock_profile_ver: print '%sYour spock profile (%s) is newer than your spock version ' \ - '(%s)!' % (SpockTermColors.Brown, spock_profile_ver_str, spock_lib_ver_str) + '(%s)!' % (SpockTermColors.Brown, + spock_profile_ver_str, spock_lib_ver_str) print 'Please upgrade spock or delete the current profile %s' % SpockTermColors.Normal sys.exit(1) @@ -737,6 +802,7 @@ def check_for_upgrade(ipy_profile_dir): upgrade_spock_profile(ipy_profile_dir, door_name) sys.exit(0) + def get_args(argv): script_name = argv[0] @@ -751,7 +817,7 @@ def get_args(argv): try: for _, arg in enumerate(argv[1:]): if arg.startswith('--profile='): - profile=arg[10:] + profile = arg[10:] break else: argv.append("--profile=" + profile) @@ -763,14 +829,15 @@ def get_args(argv): ProfileDir.find_profile_dir_by_name(ipython_dir, profile) except ProfileDirError: r = '' - while not r in ('y','n'): + while not r in ('y', 'n'): prompt = 'Profile \'%s\' does not exist. Do you want to create '\ 'one now ([y]/n)? ' % profile r = raw_input(prompt) or 'y' if r.lower() == 'y': create_spock_profile(ipython_dir, profile) else: - sys.stdout.write('No spock door extension profile was created. Starting normal spock...\n') + sys.stdout.write( + 'No spock door extension profile was created. Starting normal spock...\n') sys.stdout.flush() profile = '' @@ -778,9 +845,9 @@ def get_args(argv): if not '--profile=' in argv and profile: argv.append('--profile=' + profile) - user_ns = { 'MACRO_SERVER_NAME' : macro_server, - 'DOOR_NAME' : door, - 'PROFILE' : profile } + user_ns = {'MACRO_SERVER_NAME': macro_server, + 'DOOR_NAME': door, + 'PROFILE': profile} return user_ns @@ -792,14 +859,15 @@ def get_args(argv): MSG_R = '[%s%%s%s]' % (SpockTermColors.Red, SpockTermColors.Normal) MSG_FAILED = MSG_R % 'FAILED' MSG_FAILED_WR = MSG_R % 'FAILED: %s' -MSG_ERROR = MSG_R % 'ERROR' -MSG_DONE = MSG_G % 'DONE' -MSG_OK = MSG_G % 'OK' +MSG_ERROR = MSG_R % 'ERROR' +MSG_DONE = MSG_G % 'DONE' +MSG_OK = MSG_G % 'OK' #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # initialization methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def init_taurus(): # the CodecFactory is not thread safe. There are two attributes who will # request for it in the first event at startup in different threads @@ -837,7 +905,7 @@ def load_ipython_extension(ipython): #shell.set_hook('late_startup_hook', magic.spock_late_startup_hook) ipython.set_hook('pre_prompt_hook', magic.spock_pre_prompt_hook) - #if ip.IP.alias_table.has_key('mv'): + # if ip.IP.alias_table.has_key('mv'): # del ip.IP.alias_table['mv'] door = get_door() @@ -845,9 +913,10 @@ def load_ipython_extension(ipython): # Initialize the environment expose_variable(ENV_NAME, macro_server.getEnvironment()) - - new_style_magics = hasattr(IPython.core.magic, 'Magics') and hasattr(IPython.core.magic, 'magics_class') - + + new_style_magics = hasattr(IPython.core.magic, 'Magics') and hasattr( + IPython.core.magic, 'magics_class') + if new_style_magics: @IPython.core.magic.magics_class class Sardana(IPython.core.magic.Magics): @@ -859,7 +928,7 @@ class Sardana(IPython.core.magic.Magics): edmac = IPython.core.magic.line_magic(magic.edmac) showscan = IPython.core.magic.line_magic(magic.showscan) expconf = IPython.core.magic.line_magic(magic.expconf) - + ipython.register_magics(Sardana) else: expose_magic('debug', magic.debug, magic.debug_completer) @@ -873,9 +942,11 @@ class Sardana(IPython.core.magic.Magics): door.setConsoleReady(True) + def unload_ipython_extension(ipython): pass + def load_config(config): spockver = release.version pyver = get_python_version() @@ -900,13 +971,13 @@ def load_config(config): config.Spock.macro_server_alias = ms_alias config.Spock.door_alias = door_alias - d = { "version" : spockver, - "pyver" : pyver, - "ipyver" : ipyver, - "pytangover" : pytangover, - "taurusver" : tauruscorever, - #"profile" : ip.user_ns["PROFILE"], - "door" : door_alias } + d = {"version": spockver, + "pyver": pyver, + "ipyver": ipyver, + "pytangover": pytangover, + "taurusver": tauruscorever, + #"profile" : ip.user_ns["PROFILE"], + "door": door_alias} d.update(TermColors.__dict__) @@ -990,7 +1061,7 @@ def load_config(config): term_app = config.TerminalIPythonApp term_app.display_banner = True term_app.gui = gui_mode - term_app.pylab='qt' + term_app.pylab = 'qt' #term_app.nosep = False #term_app.classic = True @@ -999,7 +1070,7 @@ def load_config(config): # ------------------------------------ #kernel_app = config.IPKernelApp ipython_widget = config.IPythonWidget - ipython_widget.in_prompt = ' Spock [%i]: ' + ipython_widget.in_prompt = ' Spock [%i]: ' ipython_widget.out_prompt = 'Result [%i]: ' ipython_widget.input_sep = '\n' ipython_widget.output_sep = '' @@ -1068,6 +1139,7 @@ def load_config(config): config.Spock.ready = True return config + def start(user_ns=None): # Make sure the log level is changed to warning CodecFactory() @@ -1099,11 +1171,13 @@ def start(user_ns=None): #config = get_config() return app + def mainloop(app=None, user_ns=None): if app is None: app = start(user_ns) app.start() + def prepare_input_handler(): # initialize input handler as soon as possible import sardana.spock.inputhandler @@ -1122,11 +1196,11 @@ def prepare_cmdline(argv=None): profile, append_profile = "spockdoor", True try: # in ipython the last option in the list takes precedence - # so reversing order for searching of the profile + # so reversing order for searching of the profile reversed_argv = reversed(argv[1:]) for _, arg in enumerate(reversed_argv): if arg.startswith('--profile='): - profile=arg[10:] + profile = arg[10:] append_profile = False break except: @@ -1153,7 +1227,7 @@ def prepare_cmdline(argv=None): argv.remove(arg) return else: - ipy_profile_dir = pd.location # directory with the spock profile + ipy_profile_dir = pd.location # directory with the spock profile check_for_upgrade(ipy_profile_dir) if append_profile: @@ -1165,7 +1239,7 @@ def run(): try: from IPython.utils.traitlets import Unicode from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget - + class SpockConsole(RichIPythonWidget): banner = Unicode(config=True) @@ -1188,9 +1262,8 @@ def _banner_default(self): sys.exit(-1) except exception.SpockMissingRecommended, recommended: print str(recommended) - + prepare_input_handler() prepare_cmdline() launch_new_instance() - diff --git a/src/sardana/spock/ipython_01_00/__init__.py b/src/sardana/spock/ipython_01_00/__init__.py index a2538b79a5..75fadda7c9 100644 --- a/src/sardana/spock/ipython_01_00/__init__.py +++ b/src/sardana/spock/ipython_01_00/__init__.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/spock/ipython_01_00/genutils.py b/src/sardana/spock/ipython_01_00/genutils.py index a11c156465..fb14ba75fc 100644 --- a/src/sardana/spock/ipython_01_00/genutils.py +++ b/src/sardana/spock/ipython_01_00/genutils.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -71,8 +71,8 @@ from IPython.paths import get_ipython_dir except: # IPython <4.x - from IPython.config.application import Application - from IPython.utils.path import get_ipython_dir + from IPython.config.application import Application + from IPython.utils.path import get_ipython_dir import taurus @@ -91,15 +91,15 @@ SpockTermColors = colors.TermColors requirements = { -# module minimum recommended - "IPython" : ("0.11.0", "0.12.0"), - "Python" : ("2.6.0", "2.6.0"), - "PyTango" : ("7.2.0", "7.2.3"), + # module minimum recommended + "IPython": ("0.11.0", "0.12.0"), + "Python": ("2.6.0", "2.6.0"), + "PyTango": ("7.2.0", "7.2.3"), # for the moment just for reference since itango does not provide version # when using PyTango < 9 the dependency is >= 0.0.1 and < 0.1.0 # when using PyTango >= 9 the dependency is >= 0.1.6 - "itango" : ("0.0.1", "0.0.1"), - "taurus.core" : ("3.0.0", "3.0.0") + "itango": ("0.0.1", "0.0.1"), + "taurus.core": ("3.0.0", "3.0.0") } ENV_NAME = "_E" @@ -108,34 +108,43 @@ # IPython utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def get_gui_mode(): return 'qt' + def get_pylab_mode(): return get_app().pylab + def get_color_mode(): return get_config().InteractiveShell.colors + def get_app(): - #return TerminalIPythonApp.instance() + # return TerminalIPythonApp.instance() return Application.instance() + def get_shell(): """Get the global InteractiveShell instance.""" return get_app().shell + def get_ipapi(): """Get the global InteractiveShell instance.""" return InteractiveShell.instance() + def get_config(): return get_app().config + def get_editor(): return get_ipapi().editor -def ask_yes_no(prompt,default=None): + +def ask_yes_no(prompt, default=None): """Asks a question and returns a boolean (y/n) answer. If default is given (one of 'y','n'), it is used if the user input is @@ -150,9 +159,11 @@ def ask_yes_no(prompt,default=None): prompt = '%s [%s]' % (prompt, default) return _ask_yes_no(prompt, default) + def spock_input(prompt='', ps2='... '): return raw_input(prompt) + def translate_version_str2int(version_str): """Translates a version string in format x[.y[.z[...]]] into a 000000 number""" import math @@ -160,37 +171,43 @@ def translate_version_str2int(version_str): num_version_str = version_str.split('-')[0] parts = num_version_str.split('.') i, v, l = 0, 0, len(parts) - if not l: return v - while i<3: + if not l: + return v + while i < 3: try: - v += int(parts[i])*int(math.pow(10,(2-i)*2)) + v += int(parts[i]) * int(math.pow(10, (2 - i) * 2)) l -= 1 i += 1 except ValueError: return v - if not l: return v + if not l: + return v return v try: - v += 10000*int(parts[0]) + v += 10000 * int(parts[0]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v try: - v += 100*int(parts[1]) + v += 100 * int(parts[1]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v try: v += int(parts[0]) l -= 1 except ValueError: return v - if not l: return v + if not l: + return v + def get_ipython_version(): """Returns the current IPython version""" @@ -207,19 +224,24 @@ def get_ipython_version(): print e3 return v + def get_ipython_version_number(): """Returns the current IPython version number""" ipyver_str = get_ipython_version() - if ipyver_str is None: return None + if ipyver_str is None: + return None return translate_version_str2int(ipyver_str) + def get_python_version(): - return '.'.join(map(str,sys.version_info[:3])) + return '.'.join(map(str, sys.version_info[:3])) + def get_python_version_number(): pyver_str = get_python_version() return translate_version_str2int(pyver_str) + def get_ipython_profiles(path=None): """list profiles in a given root directory""" if path is None: @@ -229,13 +251,14 @@ def get_ipython_profiles(path=None): for f in files: full_path = os.path.join(path, f) if os.path.isdir(full_path) and f.startswith('profile_'): - profiles.append(f.split('_',1)[-1]) + profiles.append(f.split('_', 1)[-1]) return profiles #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # PyTango utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def get_pytango_version(): try: import PyTango @@ -246,11 +269,14 @@ def get_pytango_version(): except: return None + def get_pytango_version_number(): tgver_str = get_pytango_version() - if tgver_str is None: return None + if tgver_str is None: + return None return translate_version_str2int(tgver_str) + def get_server_for_device(device_name): db = get_tango_db() device_name = device_name.lower() @@ -261,6 +287,7 @@ def get_server_for_device(device_name): return server return None + def get_macroserver_for_door(door_name): """Returns the MacroServer device name in the same DeviceServer as the given door device""" @@ -281,7 +308,8 @@ def get_macroserver_for_door(door_name): else: return None -def get_device_from_user(expected_class, dft = None): + +def get_device_from_user(expected_class, dft=None): """Gets a device of the given device class from user input""" dft = print_dev_from_class(expected_class, dft) prompt = "%s name from the list" % expected_class @@ -302,20 +330,21 @@ def get_device_from_user(expected_class, dft = None): cl_name = db.get_class_for_device(name) class_correct = cl_name == expected_class if not class_correct: - print "Warning: the given name is not a %s (it is a %s)"%(expected_class,cl_name) + print "Warning: the given name is not a %s (it is a %s)" % (expected_class, cl_name) except Exception as e: print "Warning: unable to confirm if '%s' is valid" % name print str(e) return full_name + def get_tango_db(): import PyTango tg_host = PyTango.ApiUtil.get_env_var("TANGO_HOST") db = None if tg_host is None: - host,port = get_tango_host_from_user() - tg_host = "%s:%d" % (host,port) + host, port = get_tango_host_from_user() + tg_host = "%s:%d" % (host, port) os.environ["TANGO_HOST"] = tg_host db = PyTango.Database() else: @@ -323,13 +352,14 @@ def get_tango_db(): db = PyTango.Database() except: # tg host is not valid. Find a valid one - host,port = get_tango_host_from_user() - tg_host = "%s:%d" % (host,port) + host, port = get_tango_host_from_user() + tg_host = "%s:%d" % (host, port) os.environ["TANGO_HOST"] = tg_host db = PyTango.Database() return db + def get_tango_host_from_user(): import PyTango while True: @@ -356,7 +386,8 @@ def get_tango_host_from_user(): exp = "Invalid tango host. %s " % exp print exp -def print_dev_from_class(classname, dft = None): + +def print_dev_from_class(classname, dft=None): db = get_tango_db() pytg_ver = get_pytango_version_number() @@ -371,23 +402,27 @@ def print_dev_from_class(classname, dft = None): exp_dev_list = [] res = None - dev_list = db.get_device_name(server_wildcard,classname) - tg_host = "%s:%s" % (db.get_db_host(),db.get_db_port()) - print "Available",classname,"devices from",tg_host,":" + dev_list = db.get_device_name(server_wildcard, classname) + tg_host = "%s:%s" % (db.get_db_host(), db.get_db_port()) + print "Available", classname, "devices from", tg_host, ":" for dev in dev_list: _, name, alias = from_name_to_tango(dev) out = alias or name - if alias: out += ' (a.k.a. %s)' % name + if alias: + out += ' (a.k.a. %s)' % name out = "%-25s" % out if dev in exp_dev_list: out += " (running)" print out if dft: - if dft.lower() == name.lower(): res = name - elif not alias is None and dft.lower() == alias.lower(): res = alias + if dft.lower() == name.lower(): + res = name + elif not alias is None and dft.lower() == alias.lower(): + res = alias return res + def from_name_to_tango(name): db = get_tango_db() @@ -397,7 +432,7 @@ def from_name_to_tango(name): c = name.count('/') # if the db prefix is there, remove it first if c == 3 or c == 1: - name = name[name.index("/")+1:] + name = name[name.index("/") + 1:] elems = name.split('/') l = len(elems) @@ -422,9 +457,11 @@ def from_name_to_tango(name): # taurus utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def clean_up(): taurus.Manager().cleanUp() + def get_taurus_core_version(): try: import taurus @@ -434,21 +471,25 @@ def get_taurus_core_version(): traceback.print_exc() return '0.0.0' + def get_taurus_core_version_number(): tgver_str = get_taurus_core_version() - if tgver_str is None: return None + if tgver_str is None: + return None return translate_version_str2int(tgver_str) #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Requirements checking #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def check_requirements(): r = requirements minPyTango, recPyTango = map(translate_version_str2int, r["PyTango"]) minIPython, recIPython = map(translate_version_str2int, r["IPython"]) minPython, recPython = map(translate_version_str2int, r["Python"]) - minTaurusCore, recTaurusCore = map(translate_version_str2int, r["taurus.core"]) + minTaurusCore, recTaurusCore = map( + translate_version_str2int, r["taurus.core"]) currPython = get_python_version_number() currIPython = get_ipython_version_number() @@ -460,24 +501,30 @@ def check_requirements(): errPython, errIPython, errPyTango, errTaurusCore = False, False, False, False if currPython is None: - errMsg += "Spock needs Python version >= %s. No python installation found\n" % requirements["Python"][0] + errMsg += "Spock needs Python version >= %s. No python installation found\n" % requirements[ + "Python"][0] errPython = True elif currPython < minPython: - errMsg += "Spock needs Python version >= %s. Current version is %s\n" % (requirements["Python"][0], get_python_version()) + errMsg += "Spock needs Python version >= %s. Current version is %s\n" % ( + requirements["Python"][0], get_python_version()) errPython = True if currIPython is None: - errMsg += "Spock needs IPython version >= %s. No IPython installation found\n" % requirements["IPython"][0] + errMsg += "Spock needs IPython version >= %s. No IPython installation found\n" % requirements[ + "IPython"][0] errIPython = True elif currIPython < minIPython: - errMsg += "Spock needs IPython version >= %s. Current version is %s\n" % (requirements["IPython"][0], get_ipython_version()) + errMsg += "Spock needs IPython version >= %s. Current version is %s\n" % ( + requirements["IPython"][0], get_ipython_version()) errIPython = True if currPyTango is None: - errMsg += "Spock needs PyTango version >= %s. No PyTango installation found\n" % requirements["IPython"][0] + errMsg += "Spock needs PyTango version >= %s. No PyTango installation found\n" % requirements[ + "IPython"][0] errPyTango = True elif currPyTango < minPyTango: - errMsg += "Spock needs PyTango version >= %s. " % requirements["PyTango"][0] + errMsg += "Spock needs PyTango version >= %s. " % requirements[ + "PyTango"][0] if currPyTango > 0: errMsg += "Current version is %s\n" % get_pytango_version() else: @@ -491,10 +538,12 @@ def check_requirements(): errMsg += "Spock needs itango version >= 0.0.1, < 0.1.0 (PyTango < 9) or version >= 0.1.6 (PyTanog >= 9). No itango installation found\n" if currTaurusCore is None: - errMsg += "Spock needs taurus.core version >= %s. No taurus.core installation found\n" % requirements["taurus.core"][0] + errMsg += "Spock needs taurus.core version >= %s. No taurus.core installation found\n" % requirements[ + "taurus.core"][0] errTaurusCore = True elif currTaurusCore < minTaurusCore: - errMsg += "Spock needs taurus.core version >= %s. " % requirements["taurus.core"][0] + errMsg += "Spock needs taurus.core version >= %s. " % requirements[ + "taurus.core"][0] if currTaurusCore > 0: errMsg += "Current version is %s\n" % get_taurus_core_version() else: @@ -531,6 +580,7 @@ def check_requirements(): return True + def _get_dev(dev_type): spock_config = get_config().Spock taurus_dev = None @@ -552,12 +602,15 @@ def _get_dev(dev_type): shell.user_ns["_" + dev_type_upper] = taurus_dev return taurus_dev + def get_door(): return _get_dev('door') + def get_macro_server(): return _get_dev('macro_server') + def _macro_completer(self, event): """Method called by the IPython autocompleter. It will determine possible values for macro arguments. @@ -567,11 +620,13 @@ def _macro_completer(self, event): macro_name = event.command.lstrip('%') # calculate parameter index param_idx = len(event.line.split()) - 1 - if not event.line.endswith(' '): param_idx -= 1 + if not event.line.endswith(' '): + param_idx -= 1 # get macro info info = ms.getMacroInfoObj(macro_name) # if macro doesn't have parameters return - if param_idx < 0 or not info.hasParams() : return + if param_idx < 0 or not info.hasParams(): + return # get the parameter info possible_params = info.getPossibleParams(param_idx) # return the existing elements for the given parameter type @@ -581,6 +636,7 @@ def _macro_completer(self, event): res.extend(ms.getElementNamesWithInterface(param['type'])) return res + def expose_magic(name, fn, completer_func=_macro_completer): shell = get_shell() fn.old_magic = shell.register_magic_function(fn, magic_name=name) @@ -591,36 +647,41 @@ def expose_magic(name, fn, completer_func=_macro_completer): # enable macro param completion if completer_func is not None: - shell.set_hook('complete_command', completer_func, str_key = name) - shell.set_hook('complete_command', completer_func, str_key = '%'+name) + shell.set_hook('complete_command', completer_func, str_key=name) + shell.set_hook('complete_command', completer_func, str_key='%' + name) + def unexpose_magic(name): shell = get_shell() mg_name = 'magic_' + name if hasattr(shell, mg_name): - magic_fn = getattr(shell, mg_name) + magic_fn = getattr(shell, mg_name) delattr(shell, mg_name) if hasattr(magic_fn, 'old_magic') and magic_fn.old_magic is not None: expose_magic(name, magic_fn.old_magic, magic_fn.old_completer) + def expose_variable(name, value): get_shell().user_ns[name] = value + def expose_variables(d): get_shell().user_ns.update(d) + def unexpose_variable(name): user_ns = get_shell().user_ns del user_ns[name] + def _create_config_file(location, door_name=None): ########################################################################### # NOTE: BaseIPythonApplication.config_file_name.default_value should return - # the config file name, but it returns an empty string instead (at least + # the config file name, but it returns an empty string instead (at least # in some cases). For now, we give a hardcoded name if it is empty # TODO: Check why this is the case - config_file_name = BaseIPythonApplication.config_file_name.default_value - config_file_name = config_file_name or 'ipython_config.py' + config_file_name = BaseIPythonApplication.config_file_name.default_value + config_file_name = config_file_name or 'ipython_config.py' ########################################################################### abs_config_file_name = os.path.join(location, config_file_name) @@ -654,7 +715,7 @@ def _create_config_file(location, door_name=None): # Discover door name # if door_name is None: - door_name = get_device_from_user("Door" ) + door_name = get_device_from_user("Door") else: full_door_name, door_name, _ = from_name_to_tango(door_name) door_name = full_door_name @@ -693,6 +754,7 @@ def create_spock_profile(userdir, profile, door_name=None): _create_config_file(ipy_profile_dir) + def upgrade_spock_profile(ipy_profile_dir, door_name): """Upgrade spock profile by recreating configuration file from scratch @@ -701,6 +763,7 @@ def upgrade_spock_profile(ipy_profile_dir, door_name): """ _create_config_file(ipy_profile_dir, door_name) + def check_for_upgrade(ipy_profile_dir): """Check if the current profile is up to date with the spock version @@ -711,10 +774,10 @@ def check_for_upgrade(ipy_profile_dir): ########################################################################### # NOTE: BaseIPythonApplication.config_file_name.default_value should return - # the config file name, but it returns an empty string instead (at least + # the config file name, but it returns an empty string instead (at least # in some cases). For now, we give a hardcoded name if it is empty # TODO: Check why this is the case - config_file_name = BaseIPythonApplication.config_file_name.default_value + config_file_name = BaseIPythonApplication.config_file_name.default_value config_file_name = config_file_name or 'ipython_config.py' ########################################################################### abs_config_file_name = os.path.join(ipy_profile_dir, config_file_name) @@ -722,11 +785,12 @@ def check_for_upgrade(ipy_profile_dir): # search for version and door inside the ipy_profile file with file(abs_config_file_name, "r") as ipy_config_file: for i, line in enumerate(ipy_config_file): - if i > 20 : break; # give up after 20 lines + if i > 20: + break # give up after 20 lines if line.startswith('# spock_creation_version = '): - spock_profile_ver_str = line[line.index('=')+1:].strip() + spock_profile_ver_str = line[line.index('=') + 1:].strip() if line.startswith('# door_name = '): - door_name = line[line.index('=')+1:].strip() + door_name = line[line.index('=') + 1:].strip() # convert version from string to numbers spock_lib_ver_str = release.version @@ -734,13 +798,14 @@ def check_for_upgrade(ipy_profile_dir): spock_profile_ver = translate_version_str2int(spock_profile_ver_str) alpha_in_spock_profile = "-alpha" in spock_profile_ver_str - alpha_in_spock_lib = "-alpha" in spock_lib_ver_str + alpha_in_spock_lib = "-alpha" in spock_lib_ver_str if spocklib_ver == spock_profile_ver and \ - alpha_in_spock_profile == alpha_in_spock_lib: + alpha_in_spock_profile == alpha_in_spock_lib: return if spocklib_ver < spock_profile_ver: print '%sYour spock profile (%s) is newer than your spock version ' \ - '(%s)!' % (SpockTermColors.Brown, spock_profile_ver_str, spock_lib_ver_str) + '(%s)!' % (SpockTermColors.Brown, + spock_profile_ver_str, spock_lib_ver_str) print 'Please upgrade spock or delete the current profile %s' % SpockTermColors.Normal sys.exit(1) @@ -758,6 +823,7 @@ def check_for_upgrade(ipy_profile_dir): upgrade_spock_profile(ipy_profile_dir, door_name) sys.exit(0) + def get_args(argv): script_name = argv[0] @@ -772,7 +838,7 @@ def get_args(argv): try: for _, arg in enumerate(argv[1:]): if arg.startswith('--profile='): - profile=arg[10:] + profile = arg[10:] break else: argv.append("--profile=" + profile) @@ -784,14 +850,15 @@ def get_args(argv): ProfileDir.find_profile_dir_by_name(ipython_dir, profile) except ProfileDirError: r = '' - while not r in ('y','n'): + while not r in ('y', 'n'): prompt = 'Profile \'%s\' does not exist. Do you want to create '\ 'one now ([y]/n)? ' % profile r = raw_input(prompt) or 'y' if r.lower() == 'y': create_spock_profile(ipython_dir, profile) else: - sys.stdout.write('No spock door extension profile was created. Starting normal spock...\n') + sys.stdout.write( + 'No spock door extension profile was created. Starting normal spock...\n') sys.stdout.flush() profile = '' @@ -799,9 +866,9 @@ def get_args(argv): if not '--profile=' in argv and profile: argv.append('--profile=' + profile) - user_ns = { 'MACRO_SERVER_NAME' : macro_server, - 'DOOR_NAME' : door, - 'PROFILE' : profile } + user_ns = {'MACRO_SERVER_NAME': macro_server, + 'DOOR_NAME': door, + 'PROFILE': profile} return user_ns @@ -813,14 +880,15 @@ def get_args(argv): MSG_R = '[%s%%s%s]' % (SpockTermColors.Red, SpockTermColors.Normal) MSG_FAILED = MSG_R % 'FAILED' MSG_FAILED_WR = MSG_R % 'FAILED: %s' -MSG_ERROR = MSG_R % 'ERROR' -MSG_DONE = MSG_G % 'DONE' -MSG_OK = MSG_G % 'OK' +MSG_ERROR = MSG_R % 'ERROR' +MSG_DONE = MSG_G % 'DONE' +MSG_OK = MSG_G % 'OK' #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # initialization methods #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def init_taurus(): # the CodecFactory is not thread safe. There are two attributes who will # request for it in the first event at startup in different threads @@ -859,7 +927,7 @@ def load_ipython_extension(ipython): #shell.set_hook('late_startup_hook', magic.spock_late_startup_hook) ipython.set_hook('pre_prompt_hook', magic.spock_pre_prompt_hook) - #if ip.IP.alias_table.has_key('mv'): + # if ip.IP.alias_table.has_key('mv'): # del ip.IP.alias_table['mv'] door = get_door() @@ -867,9 +935,10 @@ def load_ipython_extension(ipython): # Initialize the environment expose_variable(ENV_NAME, macro_server.getEnvironment()) - - new_style_magics = hasattr(IPython.core.magic, 'Magics') and hasattr(IPython.core.magic, 'magics_class') - + + new_style_magics = hasattr(IPython.core.magic, 'Magics') and hasattr( + IPython.core.magic, 'magics_class') + if new_style_magics: @IPython.core.magic.magics_class class Sardana(IPython.core.magic.Magics): @@ -881,7 +950,7 @@ class Sardana(IPython.core.magic.Magics): edmac = IPython.core.magic.line_magic(magic.edmac) showscan = IPython.core.magic.line_magic(magic.showscan) expconf = IPython.core.magic.line_magic(magic.expconf) - + ipython.register_magics(Sardana) else: expose_magic('debug', magic.debug, magic.debug_completer) @@ -895,6 +964,7 @@ class Sardana(IPython.core.magic.Magics): door.setConsoleReady(True) + def unload_ipython_extension(ipython): pass @@ -923,13 +993,13 @@ def load_config(config): config.Spock.macro_server_alias = ms_alias config.Spock.door_alias = door_alias - d = { "version" : spockver, - "pyver" : pyver, - "ipyver" : ipyver, - "pytangover" : pytangover, - "taurusver" : tauruscorever, - #"profile" : ip.user_ns["PROFILE"], - "door" : door_alias } + d = {"version": spockver, + "pyver": pyver, + "ipyver": ipyver, + "pytangover": pytangover, + "taurusver": tauruscorever, + #"profile" : ip.user_ns["PROFILE"], + "door": door_alias} d.update(TermColors.__dict__) @@ -976,6 +1046,7 @@ def load_config(config): from IPython.terminal.prompts import (Prompts, Token) class SpockPrompts(Prompts): + def in_prompt_tokens(self, cli=None): return [ (Token.Prompt, door_alias), @@ -1027,7 +1098,7 @@ def out_prompt_tokens(self): term_app = config.TerminalIPythonApp term_app.display_banner = True term_app.gui = gui_mode - term_app.pylab='qt' + term_app.pylab = 'qt' #term_app.nosep = False #term_app.classic = True @@ -1036,7 +1107,7 @@ def out_prompt_tokens(self): # ------------------------------------ #kernel_app = config.IPKernelApp ipython_widget = config.IPythonWidget - ipython_widget.in_prompt = ' Spock [%i]: ' + ipython_widget.in_prompt = ' Spock [%i]: ' ipython_widget.out_prompt = 'Result [%i]: ' ipython_widget.input_sep = '\n' ipython_widget.output_sep = '' @@ -1105,6 +1176,7 @@ def out_prompt_tokens(self): config.Spock.ready = True return config + def start(user_ns=None): # Make sure the log level is changed to warning CodecFactory() @@ -1136,11 +1208,13 @@ def start(user_ns=None): #config = get_config() return app + def mainloop(app=None, user_ns=None): if app is None: app = start(user_ns) app.start() + def prepare_input_handler(): # initialize input handler as soon as possible import sardana.spock.inputhandler @@ -1159,11 +1233,11 @@ def prepare_cmdline(argv=None): profile, append_profile = "spockdoor", True try: # in ipython the last option in the list takes precedence - # so reversing order for searching of the profile + # so reversing order for searching of the profile reversed_argv = reversed(argv[1:]) for _, arg in enumerate(reversed_argv): if arg.startswith('--profile='): - profile=arg[10:] + profile = arg[10:] append_profile = False break except: @@ -1190,7 +1264,7 @@ def prepare_cmdline(argv=None): argv.remove(arg) return else: - ipy_profile_dir = pd.location # directory with the spock profile + ipy_profile_dir = pd.location # directory with the spock profile check_for_upgrade(ipy_profile_dir) if append_profile: @@ -1211,7 +1285,7 @@ def run(): from IPython.qt.console.rich_ipython_widget import RichIPythonWidget from IPython.qt.console.qtconsoleapp import IPythonQtConsoleApp IPythonQtConsoleApp.version.default_value = release.version - + class SpockConsole(RichIPythonWidget): banner = Unicode(config=True) @@ -1232,9 +1306,8 @@ def _banner_default(self): sys.exit(-1) except exception.SpockMissingRecommended, recommended: print str(recommended) - + prepare_input_handler() prepare_cmdline() launch_new_instance() - diff --git a/src/sardana/spock/magic.py b/src/sardana/spock/magic.py index e5ac0a3c7d..db0e0bf9b3 100644 --- a/src/sardana/spock/magic.py +++ b/src/sardana/spock/magic.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -50,15 +50,16 @@ def expconf(self, parameter_s=''): except TypeError: # TODO: For Taurus 4 adaptation doorname = get_door().fullname - #=========================================================================== - ## ugly hack to avoid ipython/qt thread problems #e.g. see - ## https://sourceforge.net/p/sardana/tickets/10/ - ## this hack does not allow inter-process communication and leaves the - ## widget open after closing spock - ## @todo: investigate cause of segfaults when using launching qt widgets from ipython - # + #========================================================================= + # ugly hack to avoid ipython/qt thread problems #e.g. see + # https://sourceforge.net/p/sardana/tickets/10/ + # this hack does not allow inter-process communication and leaves the + # widget open after closing spock + # @todo: investigate cause of segfaults when using launching qt widgets from ipython + # # w = ExpDescriptionEditor(door=doorname) - # w.show() #launching it like this, produces the problem of https://sourceforge.net/p/sardana/tickets/10/ + # w.show() #launching it like this, produces the problem of + # https://sourceforge.net/p/sardana/tickets/10/ import subprocess import sys @@ -133,7 +134,7 @@ def www(self, parameter_s=''): door.writeln("No macro ran from this console yet!") return if not hasattr(last_macro, 'exc_stack') or last_macro.exc_stack is None: - door.writeln("Sorry, but no exception occurred running last " \ + door.writeln("Sorry, but no exception occurred running last " "macro (%s)." % last_macro.name) return exc = "".join(last_macro.exc_stack) @@ -173,7 +174,7 @@ def post_mortem(self, parameter_s='', from_www=False): def macrodata(self, parameter_s=''): """macrodata - + Returns the data produced by the last macro""" door = get_door() macro_data = door.read_attribute("RecordData") @@ -218,7 +219,7 @@ def edmac(self, parameter_s=''): if macro_info_obj is not None: msg = ('Do you want to create macro "%s" in module "%s" that will' ' override the already existing macro in module "%s"' - % (macro_name, macro_lib, macro_info_obj.module)) + % (macro_name, macro_lib, macro_info_obj.module)) if not ask_yes_no(msg, 'y'): print "Aborting edition..." return diff --git a/src/sardana/spock/parameter.py b/src/sardana/spock/parameter.py index dd7ce82670..8352a665c0 100644 --- a/src/sardana/spock/parameter.py +++ b/src/sardana/spock/parameter.py @@ -3,91 +3,94 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """Parameter parsing""" __all__ = ['AbstractParam', 'Param', 'ParamRepeat', 'ParamList'] - + import sys + class AbstractParam: - + def __init__(self, name=None, desc=None): - self.name = name - self.desc = desc - - def getParam(self,idx=0): + self.name = name + self.desc = desc + + def getParam(self, idx=0): return self def getParamStr(self): - return "<"+self.name+">" + return "<" + self.name + ">" def getParamDescr(self): str = self.name + " (" + self.type + ") - " + self.desc if self.defvalue != 'None': - str = str + "\nDefault value: " + self.defvalue + str = str + "\nDefault value: " + self.defvalue return str def getParamCount(self): return 1 - def formatParamValue(self,value): + def formatParamValue(self, value): return value - + def __str__(self): return "%s(%s)" % (self.__class__.__name__, self.name) + class Param(AbstractParam): - + def __init__(self, name=None, type_name=None, desc=None, defvalue=None, from_array=None): - AbstractParam.__init__(self,name=name,desc=desc) - self.type = type_name + AbstractParam.__init__(self, name=name, desc=desc) + self.type = type_name self.defvalue = defvalue if from_array is not None: for key in ['name', 'type', 'desc', 'defvalue']: setattr(self, key, from_array.read()) - - def formatParamValue(self,value): + + def formatParamValue(self, value): ret = value if self.type == "File": - f = open(ret,'r') + f = open(ret, 'r') ret = f.read() f.close() return ret - - + + class ParamRepeat(AbstractParam): + def __init__(self, name=None, desc=None, opts=None, param_def=None, from_array=None): - AbstractParam.__init__(self,name=name,desc=desc) - self.opts = opts + AbstractParam.__init__(self, name=name, desc=desc) + self.opts = opts self.param_def = param_def if from_array is not None: self.name = from_array.read() - type_name = from_array.read() + type_name = from_array.read() if type_name != 'ParamRepeat': msg = 'Expecting "ParamRepeat" type, got ' + type_name raise ValueError, msg @@ -100,37 +103,40 @@ def __init__(self, name=None, desc=None, opts=None, param_def=None, if val == repr(None): val = None else: - try: val = int(val) - except: pass + try: + val = int(val) + except: + pass opts[name] = val self.opts = opts self.param_def = ParamList(from_array=from_array) - def getParam(self,idx=0): + def getParam(self, idx=0): idx = idx % len(self.param_def.pars) return self.param_def.getParam(idx) - + def getParamStr(self): return "[" + self.param_def.getParamStr() + " ]" def getParamDescr(self): return self.param_def.getParamDescr() - + def getParamCount(self): return self.param_def.getParamCount() - - def formatParamValue(self,value): + + def formatParamValue(self, value): return self.param_def.formatParamValue(value) - + class ParamList(AbstractParam): - + def __init__(self, from_array): - AbstractParam.__init__(self,name="ParamList",desc="List of parameters") - + AbstractParam.__init__(self, name="ParamList", + desc="List of parameters") + self.pars = [] self.has_param_repeat = False - + npars = int(from_array.read()) for i in range(npars): if from_array[1] == 'ParamRepeat': @@ -139,8 +145,8 @@ def __init__(self, from_array): else: par = Param(from_array=from_array) self.pars.append(par) - - def getParam(self,idx=0): + + def getParam(self, idx=0): par_nb = len(self.pars) if idx < par_nb: par = idx @@ -150,7 +156,7 @@ def getParam(self,idx=0): local_idx = idx - i local_nb = self.pars[i].getParamCount() if local_idx < local_nb: - return self.pars[i].getParam(local_idx) + return self.pars[i].getParam(local_idx) def getParamStr(self): str = "" @@ -168,17 +174,18 @@ def getParamCount(self): nb = 0 for par in self.pars: local_nb = par.getParamCount() - if local_nb == sys.maxint: + if local_nb == sys.maxint: return sys.maxint nb += local_nb return nb - - def formatParamValue(self,value): - - # for now we are not able to handle ParamRepeat with special value format + + def formatParamValue(self, value): + + # for now we are not able to handle ParamRepeat with special value + # format if self.has_param_repeat: return value - - for i,v in enumerate(value): + + for i, v in enumerate(value): value[i] = self.pars[i].formatParamValue(v) - return value \ No newline at end of file + return value diff --git a/src/sardana/spock/parser.py b/src/sardana/spock/parser.py index 2994d64534..7668b6b668 100644 --- a/src/sardana/spock/parser.py +++ b/src/sardana/spock/parser.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -42,7 +42,8 @@ RPAREN, WS])) # Tokenizer -Token = collections.namedtuple("Token", ["type","value"]) +Token = collections.namedtuple("Token", ["type", "value"]) + def generate_tokens(text): scanner = master_pat.scanner(text) @@ -66,7 +67,7 @@ class ParamParser: Inspired on Python Cookbook 3 (chapter 2.19) """ - def parse(self,text): + def parse(self, text): self.tokens = generate_tokens(text) self.tok = None # Last symbol consumed self.nexttok = None # Next symbol tokenized @@ -77,7 +78,7 @@ def _advance(self): """Advance one token ahead""" self.tok, self.nexttok = self.nexttok, next(self.tokens, None) - def _accept(self,toktype): + def _accept(self, toktype): """Test and consume the next token if it matches toktype""" if self.nexttok and self.nexttok.type == toktype: self._advance() @@ -85,7 +86,7 @@ def _accept(self,toktype): else: return False - def _expect(self,toktype): + def _expect(self, toktype): """Consume next token if it matches toktype or raise SyntaxError""" if not self._accept(toktype): raise SyntaxError("Expected " + toktype) diff --git a/src/sardana/spock/release.py b/src/sardana/spock/release.py index 45cd5e75d9..1fe5871afc 100644 --- a/src/sardana/spock/release.py +++ b/src/sardana/spock/release.py @@ -3,28 +3,28 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## -#### DEPRECATED MODULE!!!! +# DEPRECATED MODULE!!!! # This module is deprecated avoid to use anything from it. # Use sardana.release module instead #### @@ -49,7 +49,7 @@ description = "An enhanced interactive Macro Server shell." long_description = \ -""" + """ Spock provides an interactive environment for interacting with the Tango MacroServer Device. It is completely based on IPython which itself provides a replacement for the interactive Python interpreter with extra functionality. @@ -57,14 +57,14 @@ license = 'GNU' -authors = {'Tiago' : ('Tiago Coutinho','tiago.coutinho@esrf.fr'), - 'Reszela' : ('Zbigniew Reszela','zreszela@cells.es') , - 'Pascual-Izarra' : ('Carlos Pascual-Izarra','cpascual@cells.es') } +authors = {'Tiago': ('Tiago Coutinho', 'tiago.coutinho@esrf.fr'), + 'Reszela': ('Zbigniew Reszela', 'zreszela@cells.es'), + 'Pascual-Izarra': ('Carlos Pascual-Izarra', 'cpascual@cells.es')} url = '' download_url = '' -platforms = ['Linux','Windows XP/2000/NT','Windows 95/98/ME'] +platforms = ['Linux', 'Windows XP/2000/NT', 'Windows 95/98/ME'] keywords = ['Sardana', 'Interactive', 'MacroServer', 'Tango', 'Shell'] diff --git a/src/sardana/spock/spockms.py b/src/sardana/spock/spockms.py index 9c408c3eba..4d62c49b5b 100755 --- a/src/sardana/spock/spockms.py +++ b/src/sardana/spock/spockms.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -60,6 +60,7 @@ from taurus.core import TaurusDevState RUNNING_STATE = TaurusDevState.Ready + class GUIViewer(BaseGUIViewer): def __init__(self, door=None): @@ -71,17 +72,17 @@ def run(self): def show_scan(self, scan_nb=None, scan_history_info=None, directory_map=None): if scan_nb is None and scan_history_info is None: - #=================================================================== - ##Hack to avoid ipython-qt issues. See similar workaround in expconf magic command - ## @todo: do this in a better way + #================================================================== + # Hack to avoid ipython-qt issues. See similar workaround in expconf magic command + # @todo: do this in a better way #import taurus.qt.qtgui.plot #w = taurus.qt.qtgui.plot.TaurusTrend() #w.model = "scan://" + self._door.getNormalName() - #w.show() + # w.show() import subprocess args = ['taurustrend', 'scan://%s' % self._door.getNormalName()] subprocess.Popen(args) - #=================================================================== + #================================================================== return scan_dir, scan_file = None, None @@ -130,7 +131,8 @@ def show_scan(self, scan_nb=None, scan_history_info=None, directory_map=None): if isinstance(local_directories, (str, unicode)): local_directories = [local_directories] locations = local_directories - if scan_dir not in locations: locations.append(scan_dir) + if scan_dir not in locations: + locations.append(scan_dir) for local_directory in local_directories: if os.path.isdir(local_directory): if scan_file in os.listdir(local_directory): @@ -157,11 +159,13 @@ def show_scan(self, scan_nb=None, scan_history_info=None, directory_map=None): try: #entry_index = taurus_nexus_widget.findNodeIndex(local_file, entry_name) - measurement_index = taurus_nexus_widget.findNodeIndex(local_file, measurement_name) - #nexus_widget.setRootIndex(entry_index) + measurement_index = taurus_nexus_widget.findNodeIndex( + local_file, measurement_name) + # nexus_widget.setRootIndex(entry_index) nexus_widget.setCurrentIndex(measurement_index) nexus_widget.expand(measurement_index) - title_index = taurus_nexus_widget.findNodeIndex(local_file, title_name) + title_index = taurus_nexus_widget.findNodeIndex( + local_file, title_name) file_model = nexus_widget.model() title = file_model.getNodeFromIndex(title_index)[0] windowTitle += " - " + title @@ -195,7 +199,8 @@ def plot(self): program = door.getNormalName().replace('/', '').replace('_', '') try: - array = env['ActiveMntGrp'].replace('/', '').replace('_', '').upper() + "0D" + array = env['ActiveMntGrp'].replace( + '/', '').replace('_', '').upper() + "0D" array_ENV = '%s_ENV' % array except: print 'ActiveMntGrp not defined. No plotting' @@ -229,7 +234,6 @@ def plot(self): env[k] = v i += 1 - labels = env['axistitles'].split(' ') col_nb = len(labels) @@ -273,7 +277,8 @@ class SpockBaseDoor(BaseDoor): def __init__(self, name, **kw): self._consoleReady = kw.get("consoleReady", False) - if not kw.has_key('silent'): kw['silent'] = False + if not kw.has_key('silent'): + kw['silent'] = False self._lines = [] self._spock_state = None self._plotter = GUIViewer(self) @@ -310,7 +315,8 @@ def _preprocessParameters(self, parameters): par = '' else: par += c - if par: pars.append(par) + if par: + pars.append(par) return pars elif is_non_str_seq(parameters): return parameters @@ -322,7 +328,7 @@ def runMacro(self, obj, parameters=[], synch=False): return BaseDoor.runMacro(self, obj, parameters=parameters, synch=synch) def _runMacro(self, xml, **kwargs): - #kwargs like 'synch' are ignored in this re-implementation + # kwargs like 'synch' are ignored in this re-implementation if self._spock_state != RUNNING_STATE: print "Unable to run macro: No connection to door '%s'" % self.getSimpleName() raise Exception("Unable to run macro: No connection") @@ -352,7 +358,8 @@ def _runMacro(self, xml, **kwargs): elif reason == 'MissingEnv': print "Missing environment:", desc elif reason in ('API_CantConnectToDevice', 'API_DeviceNotExported'): - self._updateState(self._old_sw_door_state, TaurusSWDevState.Shutdown, silent=True) + self._updateState(self._old_sw_door_state, + TaurusSWDevState.Shutdown, silent=True) print "Unable to run macro: No connection to door '%s'" % self.getSimpleName() else: print "Unable to run macro:", reason, desc @@ -376,7 +383,7 @@ def _getMacroResult(self, macro): remote_f_name = ret[1] line_nb = ret[3] commit = CommitFile(commit_cmd, local_f_name, remote_f_name) - self.pending_commits.update({ remote_f_name : commit }) + self.pending_commits.update({remote_f_name: commit}) ip = genutils.get_ipapi() editor = genutils.get_editor() @@ -424,10 +431,11 @@ def _updateState(self, old_sw_state, new_sw_state, silent=False): ss = self._spock_state if ss is not None and ss != new_sw_state and not silent: if ss == RUNNING_STATE: - self.write_asynch("\nConnection to door '%s' was lost.\n" % self.getSimpleName()) + self.write_asynch( + "\nConnection to door '%s' was lost.\n" % self.getSimpleName()) elif new_sw_state == RUNNING_STATE: - self.write_asynch("\nConnection to the door (%s) has " \ - "been restablished\n" % self.getSimpleName()) + self.write_asynch("\nConnection to the door (%s) has " + "been restablished\n" % self.getSimpleName()) self._spock_state = new_sw_state def write_asynch(self, msg): @@ -453,7 +461,8 @@ def write(self, msg, stream=None): return BaseDoor.write(self, msg, stream=stream) def processRecordData(self, data): - if data is None: return + if data is None: + return data = data[1] if data['type'] == 'function': func_name = data['func_name'] @@ -473,12 +482,14 @@ def processRecordData(self, data): try: func(*args, **kwargs) except Exception as e: - self.logReceived(self.Warning, ['Unable to execute %s: ' % func_name, str(e)]) + self.logReceived( + self.Warning, ['Unable to execute %s: ' % func_name, str(e)]) _RECORD_DATA_THRESOLD = 4 * 1024 * 1024 # 4Mb def _processInput(self, input_data): - pyos_inputhook_ptr = ctypes.c_void_p.in_dll(ctypes.pythonapi, "PyOS_InputHook") + pyos_inputhook_ptr = ctypes.c_void_p.in_dll( + ctypes.pythonapi, "PyOS_InputHook") old_pyos_inputhook_ptr = pyos_inputhook_ptr.value pyos_inputhook_ptr.value = ctypes.c_void_p(None).value ret = BaseDoor._processInput(self, input_data) @@ -486,18 +497,20 @@ def _processInput(self, input_data): return ret def _processRecordData(self, data): - if data is None: return + if data is None: + return value = data.value size = len(value[1]) if size > self._RECORD_DATA_THRESOLD: sizekb = size / 1024 self.logReceived(self.Info, ['Received long data record (%d Kb)' % sizekb, - 'It may take some time to process. Please wait...']) + 'It may take some time to process. Please wait...']) return BaseDoor._processRecordData(self, data) from taurus.external.qt import Qt + class QSpockDoor(SpockBaseDoor): def __init__(self, name, **kw): @@ -508,7 +521,8 @@ def __init__(self, name, **kw): def recordDataReceived(self, s, t, v): if genutils.get_pylab_mode() == "inline": - if t not in CHANGE_EVTS: return + if t not in CHANGE_EVTS: + return res = BaseDoor.recordDataReceived(self, s, t, v) self.processRecordData(res) else: diff --git a/src/sardana/spock/test/__init__.py b/src/sardana/spock/test/__init__.py index c058d0cbc5..b9f9196959 100644 --- a/src/sardana/spock/test/__init__.py +++ b/src/sardana/spock/test/__init__.py @@ -2,23 +2,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/spock/test/test_parameter.py b/src/sardana/spock/test/test_parameter.py index 1f1d5059ac..89783d635a 100644 --- a/src/sardana/spock/test/test_parameter.py +++ b/src/sardana/spock/test/test_parameter.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/spock/test/test_parser.py b/src/sardana/spock/test/test_parser.py index 8903e0bc8a..6f2d6449df 100644 --- a/src/sardana/spock/test/test_parser.py +++ b/src/sardana/spock/test/test_parser.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,6 +29,7 @@ from taurus.test import insertTest from sardana.spock.parser import ParamParser + @insertTest(helper_name="parse", params_str='ScanFile "[\\"file.nxs\\", \\"file.dat\\"]"', params=["ScanFile", '["file.nxs", "file.dat"]']) diff --git a/src/sardana/tango/__init__.py b/src/sardana/tango/__init__.py index df0f5dfe2d..5242b40b6e 100644 --- a/src/sardana/tango/__init__.py +++ b/src/sardana/tango/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,12 +29,14 @@ SERVER_NAME = "Sardana" + def prepare_sardana(util): import pool import macroserver pool.prepare_pool(util) macroserver.prepare_macroserver(util) + def main_sardana(args=None, start_time=None, mode=None): import core.util # pass server name so the scripts generated with setuptools work on Windows @@ -43,6 +45,7 @@ def main_sardana(args=None, start_time=None, mode=None): run = main_sardana + def main(): import datetime run(start_time=datetime.datetime.now()) diff --git a/src/sardana/tango/core/SardanaDevice.py b/src/sardana/tango/core/SardanaDevice.py index 74b2b9df45..55f8059eb9 100644 --- a/src/sardana/tango/core/SardanaDevice.py +++ b/src/sardana/tango/core/SardanaDevice.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -95,7 +95,7 @@ def __init__(self, dclass, name): def init(self, name): """initialize the device once in the object lifetime. Override when necessary but **always** call the method from your super class - + :param str name: device name""" db = self.get_database() @@ -121,7 +121,7 @@ def get_alias(self): def get_full_name(self): """Returns the device full name in format dbname:dbport/// - + :return: this device full name :rtype: str""" db = self.get_database() @@ -176,7 +176,7 @@ def delete_device(self): def set_change_events(self, evts_checked, evts_not_checked): """Helper method to set change events on attributes - + :param evts_checked: list of attribute names to activate change events programatically with tango filter active @@ -200,14 +200,14 @@ def initialize_dynamic_attributes(self): def get_event_thread_pool(self): """Return the :class:`~taurus.core.util.ThreadPool` used by sardana to send tango events. - + :return: the sardana :class:`~taurus.core.util.ThreadPool` :rtype: :class:`~taurus.core.util.ThreadPool`""" return self._event_thread_pool def get_attribute_by_name(self, attr_name): """Gets the attribute for the given name. - + :param attr_name: attribute name :type attr_name: str :return: the attribute object @@ -216,7 +216,7 @@ def get_attribute_by_name(self, attr_name): def get_wattribute_by_name(self, attr_name): """Gets the writable attribute for the given name. - + :param attr_name: attribute name :type attr_name: str :return: the attribute object @@ -225,7 +225,7 @@ def get_wattribute_by_name(self, attr_name): def get_database(self): """Helper method to return a reference to the current tango database - + :return: the Tango database :rtype: :class:`~PyTango.Database`""" return Util.instance().get_database() @@ -240,7 +240,8 @@ def set_write_attribute(self, attr, w_value): if reason == PyTango.constants.API_WAttrOutsideLimit: desc = self.alias + ": " + df0.desc _df = DevFailed(*df[1:]) - PyTango.Except.re_throw_exception(_df, df0.reason, desc, df0.origin) + PyTango.Except.re_throw_exception( + _df, df0.reason, desc, df0.origin) raise df def set_attribute(self, attr, value=None, w_value=None, timestamp=None, @@ -250,7 +251,7 @@ def set_attribute(self, attr, value=None, w_value=None, timestamp=None, is given an error event is sent (with no value and quality INVALID). If priority is > 1, the event filter is temporarily disabled so the event is sent for sure. If synch is set to True, wait for fire event to finish - + :param attr: the tango attribute :type attr: :class:`PyTango.Attribute` @@ -304,12 +305,12 @@ def set_attribute_push(self, attr, value=None, w_value=None, timestamp=None, if priority > 0 and not synch: with self.tango_lock: return self._set_attribute_push(attr, value=value, - w_value=w_value, timestamp=timestamp, quality=quality, - error=error, priority=priority) + w_value=w_value, timestamp=timestamp, quality=quality, + error=error, priority=priority) else: return self._set_attribute_push(attr, value=value, - w_value=w_value, timestamp=timestamp, quality=quality, - error=error, priority=priority) + w_value=w_value, timestamp=timestamp, quality=quality, + error=error, priority=priority) def _set_attribute_push(self, attr, value=None, w_value=None, timestamp=None, quality=None, error=None, priority=1): @@ -324,7 +325,8 @@ def _set_attribute_push(self, attr, value=None, w_value=None, timestamp=None, attr_name = attr.get_name().lower() if value is None and error is None: - raise Exception("Cannot set value of attribute '%s' with None" % (attr_name,)) + raise Exception( + "Cannot set value of attribute '%s' with None" % (attr_name,)) try: if error is not None and fire_event: @@ -368,7 +370,7 @@ def _set_attribute_push(self, attr, value=None, w_value=None, timestamp=None, # or anyone trusting the w_value. # # TODO: Remove the try/except protection whenever Sardana - # feature-286 has been implemented and bug-54 has been fixed. + # feature-286 has been implemented and bug-54 has been fixed. # The lack of the feature and the bug can lead to the situation # when motor's position write value is out of range. # @@ -390,7 +392,7 @@ def _set_attribute_push(self, attr, value=None, w_value=None, timestamp=None, msg = ('Unable to update "w_value" because it is' + ' out of range') self.warning(msg) - self.debug('Details:', exc_info = 1) + self.debug('Details:', exc_info=1) else: raise df ############################################################### @@ -414,7 +416,7 @@ def _set_attribute_push(self, attr, value=None, w_value=None, timestamp=None, def calculate_tango_state(self, ctrl_state, update=False): """Calculate tango state based on the controller state. - + :param ctrl_state: the state returned by the controller :type ctrl_state: :obj:`~sardana.sardanadefs.State` :param bool update: @@ -429,7 +431,7 @@ def calculate_tango_state(self, ctrl_state, update=False): def calculate_tango_status(self, ctrl_status, update=False): """Calculate tango status based on the controller status. - + :param str ctrl_status: the status returned by the controller :param bool update: if True, set the state of this device with the calculated tango @@ -501,7 +503,7 @@ def dyn_attr(self, dev_list): """Invoked to create dynamic attributes for the given devices. Default implementation calls :meth:`SardanaDevice.initialize_dynamic_attributes` for each device - + :param dev_list: list of devices :type dev_list: :class:`PyTango.DeviceImpl`""" for dev in dev_list: @@ -513,7 +515,7 @@ def dyn_attr(self, dev_list): def device_name_factory(self, dev_name_list): """Builds list of device names to use when no Database is being used - + :param dev_name_list: list to be filled with device names :type dev_name_list: seq""" tango_class = self.get_name() diff --git a/src/sardana/tango/core/__init__.py b/src/sardana/tango/core/__init__.py index 4401cf5084..87e73a11e3 100644 --- a/src/sardana/tango/core/__init__.py +++ b/src/sardana/tango/core/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -32,33 +32,33 @@ def __init_pytango_devfailed(mod): consts = ( -"API_AttrConfig", "API_AttrEventProp", "API_AttrIncorrectDataNumber", -"API_AttrNoAlarm", "API_AttrNotAllowed", "API_AttrNotFound", -"API_AttrNotWritable", "API_AttrOptProp", "API_AttrPropValueNotSet", -"API_AttrValueNotSet", "API_AttrWrongDefined", "API_AttrWrongMemValue", -"API_BadConfigurationProperty", "API_BlackBoxArgument", "API_BlackBoxEmpty", -"API_CannotCheckAccessControl", "API_CannotOpenFile", -"API_CantActivatePOAManager", "API_CantCreateClassPoa", -"API_CantCreateLockingThread", "API_CantFindLockingThread", -"API_CantGetClientIdent", "API_CantGetDevObjectId", -"API_CantInstallSignal", "API_CantRetrieveClass", "API_CantRetrieveClassList", -"API_CantStoreDeviceClass", "API_ClassNotFound", -"API_CmdArgumentTypeNotSupported", "API_CommandNotAllowed", -"API_CommandNotFound", "API_CorbaSysException", "API_CorruptedDatabase", -"API_DatabaseAccess", "API_DeviceLocked", "API_DeviceNotFound", -"API_DeviceNotLocked", "API_DeviceUnlockable", "API_DeviceUnlocked", -"API_EventSupplierNotConstructed", "API_IncoherentDbData", -"API_IncoherentDevData", "API_IncoherentValues", "API_IncompatibleAttrDataType", -"API_IncompatibleCmdArgumentType", "API_InitMethodNotFound", -"API_InitNotPublic", "API_InitThrowsException", -"API_JavaRuntimeSecurityException", "API_MemoryAllocation", -"API_MethodArgument", "API_MethodNotFound", "API_MissedEvents", -"API_NotSupportedFeature", "API_NtDebugWindowError", -"API_OverloadingNotSupported", "API_PolledDeviceNotInPoolConf", -"API_PolledDeviceNotInPoolMap", "API_PollingThreadNotFound", -"API_ReadOnlyMode", "API_SignalOutOfRange", "API_SystemCallFailed", -"API_WAttrOutsideLimit", "API_WizardConfError", "API_WrongEventData", -"API_WrongHistoryDataBuffer", "API_WrongLockingStatus", "API_ZmqInitFailed") + "API_AttrConfig", "API_AttrEventProp", "API_AttrIncorrectDataNumber", + "API_AttrNoAlarm", "API_AttrNotAllowed", "API_AttrNotFound", + "API_AttrNotWritable", "API_AttrOptProp", "API_AttrPropValueNotSet", + "API_AttrValueNotSet", "API_AttrWrongDefined", "API_AttrWrongMemValue", + "API_BadConfigurationProperty", "API_BlackBoxArgument", "API_BlackBoxEmpty", + "API_CannotCheckAccessControl", "API_CannotOpenFile", + "API_CantActivatePOAManager", "API_CantCreateClassPoa", + "API_CantCreateLockingThread", "API_CantFindLockingThread", + "API_CantGetClientIdent", "API_CantGetDevObjectId", + "API_CantInstallSignal", "API_CantRetrieveClass", "API_CantRetrieveClassList", + "API_CantStoreDeviceClass", "API_ClassNotFound", + "API_CmdArgumentTypeNotSupported", "API_CommandNotAllowed", + "API_CommandNotFound", "API_CorbaSysException", "API_CorruptedDatabase", + "API_DatabaseAccess", "API_DeviceLocked", "API_DeviceNotFound", + "API_DeviceNotLocked", "API_DeviceUnlockable", "API_DeviceUnlocked", + "API_EventSupplierNotConstructed", "API_IncoherentDbData", + "API_IncoherentDevData", "API_IncoherentValues", "API_IncompatibleAttrDataType", + "API_IncompatibleCmdArgumentType", "API_InitMethodNotFound", + "API_InitNotPublic", "API_InitThrowsException", + "API_JavaRuntimeSecurityException", "API_MemoryAllocation", + "API_MethodArgument", "API_MethodNotFound", "API_MissedEvents", + "API_NotSupportedFeature", "API_NtDebugWindowError", + "API_OverloadingNotSupported", "API_PolledDeviceNotInPoolConf", + "API_PolledDeviceNotInPoolMap", "API_PollingThreadNotFound", + "API_ReadOnlyMode", "API_SignalOutOfRange", "API_SystemCallFailed", + "API_WAttrOutsideLimit", "API_WizardConfError", "API_WrongEventData", + "API_WrongHistoryDataBuffer", "API_WrongLockingStatus", "API_ZmqInitFailed") for const in consts: setattr(mod, const, const) diff --git a/src/sardana/tango/core/attributehandler.py b/src/sardana/tango/core/attributehandler.py index 0b81befdd6..9c130a3a30 100644 --- a/src/sardana/tango/core/attributehandler.py +++ b/src/sardana/tango/core/attributehandler.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/tango/core/util.py b/src/sardana/tango/core/util.py index b1acf02894..ef152dbeff 100644 --- a/src/sardana/tango/core/util.py +++ b/src/sardana/tango/core/util.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -68,10 +68,10 @@ NO_DB_MAP = { - "Pool" : ( + "Pool": ( ("pool_demo", "sardana/pool/demo", dict(Version="1.0.0"),), ), - "Controller" : ( + "Controller": ( ("motctrl", "controller/dummymotorcontroller/motctrl", dict(Id=1, Type="Motor", Klass="DummyMotorController", Library="DummyMotorController.py", Role_ids=(),),), @@ -91,53 +91,80 @@ dict(Id=6, Type="PseudoCounter", Klass="IoverI0", Library="IoverI0.py", Role_ids=(),),), ), - "Motor" : ( - ("slt", "motor/motctrl/1", dict(Id=101, Axis=1, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), - ("slb", "motor/motctrl/2", dict(Id=102, Axis=2, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), - ("mot1", "motor/motctrl/3", dict(Id=103, Axis=3, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), - ("mot2", "motor/motctrl/4", dict(Id=104, Axis=4, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), - ("mot3", "motor/motctrl/5", dict(Id=105, Axis=5, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), - ("mot4", "motor/motctrl/6", dict(Id=106, Axis=6, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), - ("th", "motor/motctrl/7", dict(Id=107, Axis=7, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), - ("tth", "motor/motctrl/8", dict(Id=108, Axis=8, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), - ("chi", "motor/motctrl/9", dict(Id=109, Axis=9, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), - ("phi", "motor/motctrl/10", dict(Id=110, Axis=10, Ctrl_id=1, Instrument_id=InvalidId, Sleep_bef_last_read=0),), + "Motor": ( + ("slt", "motor/motctrl/1", dict(Id=101, Axis=1, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), + ("slb", "motor/motctrl/2", dict(Id=102, Axis=2, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), + ("mot1", "motor/motctrl/3", dict(Id=103, Axis=3, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), + ("mot2", "motor/motctrl/4", dict(Id=104, Axis=4, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), + ("mot3", "motor/motctrl/5", dict(Id=105, Axis=5, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), + ("mot4", "motor/motctrl/6", dict(Id=106, Axis=6, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), + ("th", "motor/motctrl/7", dict(Id=107, Axis=7, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), + ("tth", "motor/motctrl/8", dict(Id=108, Axis=8, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), + ("chi", "motor/motctrl/9", dict(Id=109, Axis=9, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), + ("phi", "motor/motctrl/10", dict(Id=110, Axis=10, Ctrl_id=1, + Instrument_id=InvalidId, Sleep_bef_last_read=0),), ), - "IORegister" : ( - ("ior1", "ioregister/iorctrl/1", dict(Id=201, Axis=1, Ctrl_id=2, Instrument_id=InvalidId),), - ("ior2", "ioregister/iorctrl/2", dict(Id=202, Axis=2, Ctrl_id=2, Instrument_id=InvalidId),), - ("ior3", "ioregister/iorctrl/3", dict(Id=203, Axis=3, Ctrl_id=2, Instrument_id=InvalidId),), - ("ior4", "ioregister/iorctrl/4", dict(Id=204, Axis=4, Ctrl_id=2, Instrument_id=InvalidId),), + "IORegister": ( + ("ior1", "ioregister/iorctrl/1", dict(Id=201, + Axis=1, Ctrl_id=2, Instrument_id=InvalidId),), + ("ior2", "ioregister/iorctrl/2", dict(Id=202, + Axis=2, Ctrl_id=2, Instrument_id=InvalidId),), + ("ior3", "ioregister/iorctrl/3", dict(Id=203, + Axis=3, Ctrl_id=2, Instrument_id=InvalidId),), + ("ior4", "ioregister/iorctrl/4", dict(Id=204, + Axis=4, Ctrl_id=2, Instrument_id=InvalidId),), ), - "CTExpChannel" : ( - ("ct1", "expchan/ctctrl/1", dict(Id=301, Axis=1, Ctrl_id=3, Instrument_id=InvalidId),), - ("ct2", "expchan/ctctrl/2", dict(Id=302, Axis=2, Ctrl_id=3, Instrument_id=InvalidId),), - ("ct3", "expchan/ctctrl/3", dict(Id=303, Axis=3, Ctrl_id=3, Instrument_id=InvalidId),), - ("ct4", "expchan/ctctrl/4", dict(Id=304, Axis=4, Ctrl_id=3, Instrument_id=InvalidId),), + "CTExpChannel": ( + ("ct1", "expchan/ctctrl/1", dict(Id=301, + Axis=1, Ctrl_id=3, Instrument_id=InvalidId),), + ("ct2", "expchan/ctctrl/2", dict(Id=302, + Axis=2, Ctrl_id=3, Instrument_id=InvalidId),), + ("ct3", "expchan/ctctrl/3", dict(Id=303, + Axis=3, Ctrl_id=3, Instrument_id=InvalidId),), + ("ct4", "expchan/ctctrl/4", dict(Id=304, + Axis=4, Ctrl_id=3, Instrument_id=InvalidId),), ), - "ZeroDExpChannel" : ( - ("zerod1", "expchan/zerodctrl/1", dict(Id=401, Axis=1, Ctrl_id=4, Instrument_id=InvalidId),), - ("zerod2", "expchan/zerodctrl/2", dict(Id=402, Axis=2, Ctrl_id=4, Instrument_id=InvalidId),), - ("zerod3", "expchan/zerodctrl/3", dict(Id=403, Axis=3, Ctrl_id=4, Instrument_id=InvalidId),), - ("zerod4", "expchan/zerodctrl/4", dict(Id=404, Axis=4, Ctrl_id=4, Instrument_id=InvalidId),), + "ZeroDExpChannel": ( + ("zerod1", "expchan/zerodctrl/1", dict(Id=401, + Axis=1, Ctrl_id=4, Instrument_id=InvalidId),), + ("zerod2", "expchan/zerodctrl/2", dict(Id=402, + Axis=2, Ctrl_id=4, Instrument_id=InvalidId),), + ("zerod3", "expchan/zerodctrl/3", dict(Id=403, + Axis=3, Ctrl_id=4, Instrument_id=InvalidId),), + ("zerod4", "expchan/zerodctrl/4", dict(Id=404, + Axis=4, Ctrl_id=4, Instrument_id=InvalidId),), ), - "PseudoMotor" : ( - ("gap", "pm/slitctrl/1", dict(Id=501, Axis=1, Ctrl_id=5, Instrument_id=InvalidId, Elements=("101", "102",)),), - ("offset", "pm/slitctrl/2", dict(Id=502, Axis=2, Ctrl_id=5, Instrument_id=InvalidId, Elements=("101", "102",)),), + "PseudoMotor": ( + ("gap", "pm/slitctrl/1", dict(Id=501, Axis=1, Ctrl_id=5, + Instrument_id=InvalidId, Elements=("101", "102",)),), + ("offset", "pm/slitctrl/2", dict(Id=502, Axis=2, Ctrl_id=5, + Instrument_id=InvalidId, Elements=("101", "102",)),), ), - "PseudoCounter" : ( - ("inorm", "pc/ioi0ctrl/1", dict(Id=601, Axis=1, Ctrl_id=6, Instrument_id=InvalidId, Elements=("301", "302",)),), + "PseudoCounter": ( + ("inorm", "pc/ioi0ctrl/1", dict(Id=601, Axis=1, Ctrl_id=6, + Instrument_id=InvalidId, Elements=("301", "302",)),), ), - "MotorGroup" : ( - ("motgrp1", "mg/pool_demo/motgrp1", dict(Id=701, Elements=("103", "104",)),), + "MotorGroup": ( + ("motgrp1", "mg/pool_demo/motgrp1", + dict(Id=701, Elements=("103", "104",)),), ), - "MeasurementGroup" : ( - ("mntgrp1", "mntgrp/pool_demo/mntgrp1", dict(Id=701, Elements=("301", "302", "303", "401",)),), + "MeasurementGroup": ( + ("mntgrp1", "mntgrp/pool_demo/mntgrp1", + dict(Id=701, Elements=("301", "302", "303", "401",)),), ), - "MacroServer" : ( + "MacroServer": ( ("MS_demo", "sardana/ms/demo", dict(PoolNames=["sardana/pool/demo"]),), ), - "Door" : ( + "Door": ( ("Door_demo", "sardana/door/demo", dict(Id=1001, MacroServerName="sardana/ms/demo", MaxMsgBufferSize=512),), ), @@ -147,6 +174,7 @@ # PyTango utilities #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + def get_pytango_version_str(): try: import PyTango @@ -157,6 +185,7 @@ def get_pytango_version_str(): except: return '0.0.0' + def get_pytango_version_number(): tgver_str = get_pytango_version_str() if tgver_str is None: @@ -164,6 +193,7 @@ def get_pytango_version_number(): import sardana.sardanautils return sardana.sardanautils.translate_version_str2int(tgver_str) + def get_tango_version_str(): try: import PyTango.constants @@ -174,6 +204,7 @@ def get_tango_version_str(): except: return '0.0.0' + def get_tango_version_number(): tgver_str = get_tango_version_str() if tgver_str is None: @@ -181,6 +212,7 @@ def get_tango_version_number(): import sardana.sardanautils return sardana.sardanautils.translate_version_str2int(tgver_str) + class GenericScalarAttr(Attr): pass @@ -196,24 +228,29 @@ class GenericImageAttr(ImageAttr): def __init__(self, name, tg_type, tg_access, dim_x=2048, dim_y=2048): ImageAttr.__init__(self, name, tg_type, tg_access, dim_x, dim_y) + def clean_device_attribute_memorized(db, dev_name, attr_name): props = "__value", "__value_ts" - db.delete_device_attribute_property(dev_name, {attr_name : props }) + db.delete_device_attribute_property(dev_name, {attr_name: props}) + def clean_device_memorized(db, dev_name): for attr_name in PyTango.DeviceProxy(dev_name).get_attribute_list(): clean_device_attribute_memorized(db, dev_name, attr_name) + def clean_server_memorized(db, server_name, server_instance): server = server_name + "/" + server_instance dev_names = db.get_device_class_list(server)[::2] for dev_name in dev_names: clean_device_memorized(db, dev_name) + def __set_last_write_value(attribute, lrv): attribute._last_write_value = lrv return lrv + def __get_last_write_value(attribute): if hasattr(attribute, '_last_write_value'): lrv = attribute._last_write_value @@ -221,15 +258,16 @@ def __get_last_write_value(attribute): attribute._last_write_value = lrv = None return lrv + def memorize_write_attribute(write_attr_func): """The main purpose is to use this as a decorator for write_ device methods. - + Properly memorizes the attribute write value: - + - only memorize if write doesn't throw exception - also memorize the timestamp - + :param write_attr_func: the write method :type write_attr_func: callable :return: a write method safely wrapping the given write method @@ -264,11 +302,13 @@ def write_attr_wrapper(self, attribute): attr_values = dict(__value_ts=store[1]) if store_value: attr_values['__value'] = store[0] - db.put_device_attribute_property(dev_name, { attr_name : attr_values }) + db.put_device_attribute_property( + dev_name, {attr_name: attr_values}) return ret return write_attr_wrapper + def tango_protect(wrapped, *args, **kwargs): @wraps(wrapped) def wrapper(self, *args, **kwargs): @@ -276,6 +316,7 @@ def wrapper(self, *args, **kwargs): return wrapped(self, *args, **kwargs) return wrapper + def from_deviceattribute_value(da): if da.has_failed: return @@ -286,9 +327,10 @@ def from_deviceattribute_value(da): elif dformat == PyTango.SPECTRUM: return list(map(from_tango_state_to_state, value)) elif dformat == PyTango.IMAGE: - return [ list(map(from_tango_state_to_state, v)) for v in value ] + return [list(map(from_tango_state_to_state, v)) for v in value] return value + def from_deviceattribute(da): if da.has_failed: exc_info = DevFailed(*da.get_err_stack()) @@ -303,71 +345,77 @@ def from_deviceattribute(da): timestamp=da.time.totime(), dtype=dtype, dformat=dformat) return ret + def to_tango_state(state): return DevState(state) + def from_tango_state_to_state(state): return int(state) #: dictionary dict<:class:`sardana.DataType`, :class:`PyTango.CmdArgType`> TTYPE_MAP = { - DataType.Integer : DevLong, - DataType.Double : DevDouble, - DataType.String : DevString, - DataType.Boolean : DevBoolean, + DataType.Integer: DevLong, + DataType.Double: DevDouble, + DataType.String: DevString, + DataType.Boolean: DevBoolean, } R_TTYPE_MAP = dict((v, k) for k, v in TTYPE_MAP.items()) #: dictionary dict<:class:`sardana.DataFormat`, :class:`PyTango.AttrFormat`> TFORMAT_MAP = { - DataFormat.Scalar : SCALAR, - DataFormat.OneD : SPECTRUM, - DataFormat.TwoD : IMAGE, + DataFormat.Scalar: SCALAR, + DataFormat.OneD: SPECTRUM, + DataFormat.TwoD: IMAGE, } R_TFORMAT_MAP = dict((v, k) for k, v in TFORMAT_MAP.items()) #: dictionary dict<:class:`sardana.DataAccess`, :class:`PyTango.AttrWriteType`> TACCESS_MAP = { - DataAccess.ReadOnly : READ, - DataAccess.ReadWrite : READ_WRITE, + DataAccess.ReadOnly: READ, + DataAccess.ReadWrite: READ_WRITE, } R_TACCESS_MAP = dict((v, k) for k, v in TACCESS_MAP.items()) + def exception_str(etype=None, value=None, sep='\n'): if etype is None: etype, value = sys.exc_info()[:2] return sep.join(traceback.format_exception_only(etype, value)) + def to_tango_access(access): """Transforms a :obj:`~sardana.DataAccess` into a :obj:`~PyTango.AttrWriteType` - + :param access: the access to be transformed :type access: :obj:`~sardana.DataAccess` :return: the tango attribute write type :rtype: :obj:`PyTango.AttrWriteType`""" return TACCESS_MAP[access] + def from_tango_access(access): """Transforms a :obj:`~PyTango.AttrWriteType` into a :obj:`~sardana.DataAccess` - + :param access: the tango access to be transformed :type access: :obj:`~PyTango.AttrWriteType` :return: the sardana attribute write type :rtype: :obj:`~sardana.DataAccess`""" return R_TACCESS_MAP[access] + def to_tango_type_format(dtype_or_info, dformat=None): """Transforms a :obj:`~sardana.DataType` :obj:`~sardana.DataFormat` into a :obj:`~PyTango.CmdArgType`, :obj:`~PyTango.AttrDataFormat` tuple - + :param dtype_or_info: the type to be transformed :type dtype_or_info: :obj:`~sardana.DataType` :param dformat: the format to be transformed :type dformat: :obj:`~sardana.DataFormat` - + :return: a tuple of two elements: the tango attribute write type, tango data format :rtype: tuple< :obj:`PyTango.CmdArgType`, :obj:`PyTango.AttrDataFormat` >""" dtype = dtype_or_info @@ -375,19 +423,21 @@ def to_tango_type_format(dtype_or_info, dformat=None): dtype, dformat = to_dtype_dformat(dtype) return TTYPE_MAP.get(dtype, DevVoid), TFORMAT_MAP.get(dformat, FMT_UNKNOWN) + def from_tango_type_format(dtype, dformat=PyTango.SCALAR): """Transforms a :obj:`~PyTango.CmdArgType`, :obj:`~PyTango.AttrDataFormat` into a :obj:`~sardana.DataType` :obj:`~sardana.DataFormat` tuple - + :param dtype: the type to be transformed :type dtype: :obj:`~PyTango.CmdArgType` :param dformat: the format to be transformed :type dformat: :obj:`~PyTango.AttrDataFormat` - + :return: a tuple of two elements: data type, data format :rtype: tuple< :obj:`~sardana.DataType`, :obj:`~sardana.DataFormat` >""" return R_TTYPE_MAP[dtype], R_TFORMAT_MAP[dformat] + def to_tango_attr_info(attr_name, attr_info): if isinstance(attr_info, DataInfo): data_type, data_format = attr_info.dtype, attr_info.dformat @@ -402,7 +452,7 @@ def to_tango_attr_info(attr_name, attr_info): tg_type, tg_format = to_tango_type_format(data_type, data_format) tg_access = to_tango_access(data_access) - tg_attr_info = [ [ tg_type, tg_format, tg_access ] ] + tg_attr_info = [[tg_type, tg_format, tg_access]] extra = {} tg_attr_info.append(extra) @@ -412,6 +462,7 @@ def to_tango_attr_info(attr_name, attr_info): extra['memorized'] = memorized return attr_name, tg_attr_info + def throw_sardana_exception(exc): """Throws an exception as a tango exception""" if isinstance(exc, SardanaException): @@ -427,6 +478,7 @@ def throw_sardana_exception(exc): else: raise exc + def ask_yes_no(prompt, default=None): """Asks a question and returns a boolean (y/n) answer. @@ -437,7 +489,7 @@ def ask_yes_no(prompt, default=None): exception is raised to prevent infinite loops. Valid answers are: y/yes/n/no (match is not case sensitive).""" - answers = {'y':True, 'n':False, 'yes':True, 'no':False} + answers = {'y': True, 'n': False, 'yes': True, 'no': False} ans = None if default is not None: d_l = default.lower() @@ -462,6 +514,7 @@ def ask_yes_no(prompt, default=None): return answers[ans] + def clean_tango_args(args): ret, ret_for_tango, ret_for_ORB = [], [], [] @@ -502,10 +555,11 @@ def clean_tango_args(args): i += 1 return ret, ret_for_tango, ret_for_ORB + def prepare_cmdline(parser=None, args=None): """Prepares the command line separating tango options from server specific options. - + :return: a sequence of options, arguments, tango arguments :rtype: seq, list>""" import optparse @@ -529,8 +583,8 @@ def prepare_cmdline(parser=None, args=None): "debug (4), trace (5) [default: %default]. " \ "Ignored if --without-log-file is True" help_fnlog = "log file name. When given, MUST be absolute file name. " \ - "[default: /tmp/tango///log.txt]. " \ - "Ignored if --without-log-file is True" + "[default: /tmp/tango///log.txt]. " \ + "Ignored if --without-log-file is True" help_wflog = "When set to True disables logging into a file [default: %default]" help_rfoo = "rconsole port number. [default: %default meaning rconsole NOT active]" parser.add_option("--log-level", dest="log_level", metavar="LOG_LEVEL", @@ -551,6 +605,7 @@ def prepare_cmdline(parser=None, args=None): res.append(ORB_args) return res + def prepare_environment(args, tango_args, ORB_args): """Since we have to create a Tango Database object before the Tango Util, omniORB doesn't recognize parameters on the command line anymore @@ -567,6 +622,7 @@ def prepare_environment(args, tango_args, ORB_args): log_messages.append(("setting %s=%s", env_name, env_val)) return log_messages + def prepare_server(args, tango_args): """Register a proper server if the user gave an unknown server""" log_messages = [] @@ -584,8 +640,9 @@ def prepare_server(args, tango_args): if len(tango_args) < 2: valid = False while not valid: - inst_name = raw_input("Please indicate %s instance name: " % server_name) - #should be a instance name validator. + inst_name = raw_input( + "Please indicate %s instance name: " % server_name) + # should be a instance name validator. valid_set = string.letters + string.digits + '_' + '-' out = ''.join([c for c in inst_name if c not in valid_set]) valid = len(inst_name) > 0 and len(out) == 0 @@ -602,8 +659,9 @@ def prepare_server(args, tango_args): db = Database() if not exists_server_instance(db, server_name, inst_name): if ask_yes_no('%s does not exist. Do you wish create a new one' % inst_name, default='y'): - if server_name == 'MacroServer' : - # build list of pools to which the MacroServer should connect to + if server_name == 'MacroServer': + # build list of pools to which the MacroServer should connect + # to pool_names = [] pools = get_dev_from_class(db, "Pool") all_pools = pools.keys() @@ -615,7 +673,8 @@ def prepare_server(args, tango_args): for i in pools: print pools[i][3] while True: - elem = raw_input("Please select pool to connect to (return to finish): ").strip() + elem = raw_input( + "Please select pool to connect to (return to finish): ").strip() if not len(elem): break if elem.lower() not in all_pools: @@ -623,20 +682,23 @@ def prepare_server(args, tango_args): print all_pools else: pool_names.append(elem) - log_messages += register_sardana(db, server_name, inst_name, pool_names) + log_messages += register_sardana(db, + server_name, inst_name, pool_names) else: log_messages += register_sardana(db, server_name, inst_name) return log_messages + def exists_server_instance(db, server_name, server_instance): known_inst = map(str.lower, db.get_instance_name_list(server_name)) return server_instance.lower() in known_inst + def register_sardana(db, bin_name, inst_name, pool_names=None): devices = [] log_messages = [] if bin_name == 'MacroServer': - props = {'PoolNames' : pool_names} + props = {'PoolNames': pool_names} ms_alias = get_free_alias(db, "MS_" + inst_name) devices.append(('MacroServer', None, ms_alias, props)) door_alias = get_free_alias(db, "Door_" + inst_name) @@ -650,7 +712,7 @@ def register_sardana(db, bin_name, inst_name, pool_names=None): devices.append(('Pool', pool_dev_name, pool_alias, {})) ms_alias = get_free_alias(db, "MS_" + inst_name) devices.append(('MacroServer', None, ms_alias, - {'PoolNames' : [pool_dev_name]})) + {'PoolNames': [pool_dev_name]})) door_alias = get_free_alias(db, "Door_" + inst_name) devices.append(("Door", None, door_alias, {})) register_server_with_devices(db, bin_name, inst_name, devices) @@ -660,6 +722,7 @@ def register_sardana(db, bin_name, inst_name, pool_names=None): log_messages.append(("Registered %s %s", dev_class, dev_alias)) return log_messages + def register_server_with_devices(db, server_name, server_instance, devices): """Registers a new server with some devices in the Database. Devices is a seq>> where each item is a @@ -696,6 +759,7 @@ def register_server_with_devices(db, server_name, server_instance, devices): if props is not None: db.put_device_property(info.name, props) + def from_name_to_tango(db, name): alias = None @@ -723,6 +787,7 @@ def from_name_to_tango(db, name): full_name = "%s:%s/%s" % (db.get_db_host(), db.get_db_port(), name) return full_name, name, alias + def get_dev_from_class(db, classname): """Returns tuple""" server_wildcard = '*' @@ -736,13 +801,15 @@ def get_dev_from_class(db, classname): for dev in dev_list: full_name, name, alias = from_name_to_tango(db, dev) out = alias or name - if alias: out += ' (a.k.a. %s)' % name + if alias: + out += ' (a.k.a. %s)' % name out = "%-25s" % out if dev in exp_dev_list: out += " (running)" res[dev] = full_name, name, alias, out return res + def get_free_server(db, prefix, start_from=1): prefix = prefix + "_" server_members = db.get_server_list(prefix + "*") @@ -751,12 +818,14 @@ def get_free_server(db, prefix, start_from=1): start_from += 1 return prefix + str(start_from) + def get_free_device(db, prefix, start_from=1): members = db.get_device_member(prefix + "/*") while str(start_from) in members: start_from += 1 return prefix + "/" + str(start_from) + def get_free_alias(db, prefix, start_from=1): '''Iterates until failure, trying to retrieve from the database device of the given alias. This way, first which fails is available in the database. @@ -769,33 +838,35 @@ def get_free_alias(db, prefix, start_from=1): while True: name = prefix + "_" + str(start_from) try: - db.get_device_from_alias(name) # PyTango >= 8.1.0 + db.get_device_from_alias(name) # PyTango >= 8.1.0 except PyTango.DevFailed: return name except AttributeError: try: - db.get_device_alias(name) # deprecated since PyTango 8.1.0 + db.get_device_alias(name) # deprecated since PyTango 8.1.0 except PyTango.DevFailed: return name start_from += 1 + def prepare_taurus(options, args, tango_args): # make sure the polling is not active factory = taurus.Factory() factory.disablePolling() + def prepare_logging(options, args, tango_args, start_time=None, log_messages=None): taurus.setLogLevel(taurus.Debug) root = Logger.getRootLog() # output logger configuration log_output_level = options.log_level - log_level_map = { "0" : taurus.Critical, "critical" : taurus.Critical, - "1" : taurus.Error, "error" : taurus.Error, - "2" : taurus.Warning, "warning" : taurus.Warning, - "3" : taurus.Info, "info" : taurus.Info, - "4" : taurus.Debug, "debug" : taurus.Debug, - "5" : taurus.Trace, "trace" : taurus.Trace, + log_level_map = {"0": taurus.Critical, "critical": taurus.Critical, + "1": taurus.Error, "error": taurus.Error, + "2": taurus.Warning, "warning": taurus.Warning, + "3": taurus.Info, "info": taurus.Info, + "4": taurus.Debug, "debug": taurus.Debug, + "5": taurus.Trace, "trace": taurus.Trace, } log_output_level = log_level_map[log_output_level] root.handlers[0].setLevel(log_output_level) @@ -811,7 +882,8 @@ def prepare_logging(options, args, tango_args, start_time=None, log_messages=Non ds_instance = args[-1].lower() import getpass try: - tangodir = 'tango-%s' % getpass.getuser() #include the user name to avoid permission errors + # include the user name to avoid permission errors + tangodir = 'tango-%s' % getpass.getuser() except: tangodir = 'tango' % getpass.getuser() path = os.path.join(os.sep, "tmp", tangodir, ds_name, ds_instance) @@ -828,8 +900,8 @@ def prepare_logging(options, args, tango_args, start_time=None, log_messages=Non try: if not os.path.exists(path): os.makedirs(path, 0777) - - from sardana import sardanacustomsettings + + from sardana import sardanacustomsettings maxBytes = getattr(sardanacustomsettings, 'LOG_FILES_SIZE', 1E7) backupCount = getattr(sardanacustomsettings, 'LOG_BCK_COUNT', 5) @@ -864,9 +936,13 @@ def prepare_logging(options, args, tango_args, start_time=None, log_messages=Non taurus.debug("Start args=%s", args) taurus.debug("Start tango args=%s", tango_args) taurus.debug("Start options=%s", options) - taurus.debug("Using PyTango %s from %s", PyTango.Release.version, PyTango.__path__[0]) - taurus.debug("Using taurus %s from %s", taurus.Release.version, taurus.__path__[0]) - taurus.debug("Using sardana %s from %s", sardana.Release.version, sardana.__path__[0]) + taurus.debug("Using PyTango %s from %s", + PyTango.Release.version, PyTango.__path__[0]) + taurus.debug("Using taurus %s from %s", + taurus.Release.version, taurus.__path__[0]) + taurus.debug("Using sardana %s from %s", + sardana.Release.version, sardana.__path__[0]) + def prepare_rconsole(options, args, tango_args): port = options.rconsole_port @@ -880,6 +956,7 @@ def prepare_rconsole(options, args, tango_args): except: taurus.debug("Failed to setup rconsole", exc_info=1) + def run_tango_server(tango_util=None, start_time=None): try: if tango_util is None: @@ -908,6 +985,7 @@ def run_tango_server(tango_util=None, start_time=None): taurus.critical("Server exited with unforeseen exception", exc_info=1) taurus.info("Exited") + def run(prepare_func, args=None, tango_util=None, start_time=None, mode=None, name=None): @@ -916,7 +994,7 @@ def run(prepare_func, args=None, tango_util=None, start_time=None, mode=None, if args is None: if mode != ServerRunMode.SynchPure: - raise Exception("When running in separate thread/process, " \ + raise Exception("When running in separate thread/process, " "'args' must be given") args = sys.argv @@ -928,7 +1006,9 @@ def run(prepare_func, args=None, tango_util=None, start_time=None, mode=None, if mode != ServerRunMode.SynchPure: if mode in (ServerRunMode.SynchThread, ServerRunMode.AsynchThread): import threading + class task_klass(threading.Thread): + def terminate(self): if not self.is_alive(): return diff --git a/src/sardana/tango/macroserver/Door.py b/src/sardana/tango/macroserver/Door.py index f16f070fb3..7abab67a64 100644 --- a/src/sardana/tango/macroserver/Door.py +++ b/src/sardana/tango/macroserver/Door.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -49,14 +49,14 @@ class TangoInputHandler(BaseInputHandler): - + def __init__(self, door, attr): self._value = None self._input_waitting = False self._input_event = threading.Event() self._door = door self._attr = attr - + def input(self, input_data=None): if input_data is None: input_data = {} @@ -70,7 +70,7 @@ def input(self, input_data=None): res = self.input_wait(timeout=timeout) finally: self._input_waitting = False - + if res is None or res.get('cancel', False): raise InputCancelled('Input cancelled by user') return res['input'] @@ -85,7 +85,7 @@ def input_wait(self, timeout=None): wait = self._input_event.wait(timeout) # if there was a timeout: # - set the value to the default value (if one exists) - # - inform clients that timeout occured and they should not wait for + # - inform clients that timeout occured and they should not wait for # user input anymore if not self._input_event.is_set(): if 'default_value' in self.input_data: @@ -111,13 +111,14 @@ def __init__(self, door, attr, module_name, format="bz2_pickle"): self.attr = attr self.module_name = module_name self.format = format - + def handle(self, func_name, *args, **kwargs): codec = CodecFactory().getCodec(self.format) - data = dict(type='function', func_name=func_name, args=args, kwargs=kwargs) + data = dict(type='function', func_name=func_name, + args=args, kwargs=kwargs) event_value = codec.encode(('', data)) self.door.set_attribute(self.attr, value=event_value) - + def __getattr__(self, name): def f(*args, **kwargs): full_name = self.module_name + "." + name @@ -132,13 +133,13 @@ def __init__(self, door, attr, format="bz2_pickle"): TangoFunctionHandler.__init__(self, door, attr, "pylab", format="bz2_pickle") - + class TangoPyplotHandler(TangoFunctionHandler): def __init__(self, door, attr, format="bz2_pickle"): TangoFunctionHandler.__init__(self, door, attr, "pyplot", format="bz2_pickle") - + class Door(SardanaDevice): @@ -172,7 +173,7 @@ def delete_device(self): if self.getRunningMacro(): self.debug("aborting running macro") self.macro_executor.abort() - + for handler, filter, format in self._handler_dict.values(): handler.finish() @@ -191,7 +192,7 @@ def init_device(self): util = Util.instance() db = util.get_database() - + # Find the macro server for this door macro_servers = util.get_device_list_by_class("MacroServer") if self.MacroServerName is None: @@ -203,12 +204,12 @@ def init_device(self): ms.alias.lower() == ms_name: self._macro_server_device = ms break - + # support for old doors which didn't have ID if self.Id == InvalidId: self.Id = self.macro_server_device.macro_server.get_new_id() db.put_device_property(self.get_name(), dict(Id=self.Id)) - + door = self.door if door is None: full_name = self.get_name() @@ -224,12 +225,13 @@ def init_device(self): input_attr = multi_attr.get_attr_by_name('Input') self._input_handler = ih = TangoInputHandler(self, input_attr) door.set_input_handler(ih) - + recorddata_attr = multi_attr.get_attr_by_name('RecordData') self._pylab_handler = pylabh = TangoPylabHandler(self, recorddata_attr) door.set_pylab_handler(pylabh) - - self._pyplot_handler = pyploth = TangoPyplotHandler(self, recorddata_attr) + + self._pyplot_handler = pyploth = TangoPyplotHandler( + self, recorddata_attr) door.set_pyplot_handler(pyploth) door.add_listener(self.on_door_changed) @@ -245,23 +247,23 @@ def _setupLogHandlers(self, levels): self.addLogHandler(handler) format = None self._handler_dict[level] = handler, filter, format - + def on_door_changed(self, event_source, event_type, event_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return - + timestamp = time.time() - + name = event_type.name.lower() - + multi_attr = self.get_device_attr() try: attr = multi_attr.get_attr_by_name(name) except DevFailed: return - + if name == "state": event_value = self.calculate_tango_state(event_value) elif name == "status": @@ -276,19 +278,19 @@ def on_door_changed(self, event_source, event_type, event_value): error = Except.to_dev_failed(*event_value.exc_info) timestamp = event_value.timestamp event_value = event_value.value - + if attr.get_data_type() == ArgType.DevEncoded: codec = CodecFactory().getCodec('json') event_value = codec.encode(('', event_value)) self.set_attribute(attr, value=event_value, timestamp=timestamp) - + @property def macro_executor(self): return self.door.macro_executor - + def getRunningMacro(self): return self.door.running_macro - + def always_executed_hook(self): pass @@ -304,40 +306,39 @@ def dev_status(self): self._status += mstack return self._status - - def read_attr_hardware(self,data): + def read_attr_hardware(self, data): pass - + def readLogAttr(self, attr): name = attr.get_name() handler, filter, format = self._handler_dict[name] handler.read(attr) - + read_Critical = read_Error = read_Warning = read_Info = read_Output = \ - read_Debug = read_Trace = readLogAttr - + read_Debug = read_Trace = readLogAttr + def read_Input(self, attr): attr.set_value('') - + def write_Input(self, attr): value = attr.get_write_value() self.door.get_input_handler().input_received(value) - + #@DebugIt() def read_ElementList(self, attr): element_list = self.macro_server_device.getElementList() attr.set_value(*element_list) - + def sendRecordData(self, format, data): self.push_change_event('RecordData', format, data) def getLogAttr(self, name): return self._handler_dict.get(name) - + def read_Result(self, attr): # Add your own code here attr.set_value(self._last_result) - + def read_RecordData(self, attr): try: macro_data = self.door.get_macro_data() @@ -347,19 +348,19 @@ def read_RecordData(self, attr): throw_sardana_exception(mse) attr.set_value(*data) - + def read_MacroStatus(self, attr): attr.set_value('', '') - + def Abort(self): self.debug("Abort is deprecated. Use StopMacro instead") return self.StopMacro() - + def AbortMacro(self): self.debug("Aborting") self.macro_executor.abort() self.debug("Finished aborting") - + def is_Abort_allowed(self): return True @@ -379,28 +380,28 @@ def StopMacro(self): return self.debug("stopping macro %s" % macro._getDescription()) self.macro_executor.stop() - + def is_StopMacro_allowed(self): return self.get_state() == Macro.Running - + def ResumeMacro(self): macro = self.getRunningMacro() if macro is None: return self.debug("resume macro %s" % macro._getDescription()) self.macro_executor.resume() - + def is_ResumeMacro_allowed(self): return self.get_state() == Macro.Pause - + def RunMacro(self, par_str_list): - #first empty all the buffers + # first empty all the buffers for handler, filter, fmt in self._handler_dict.values(): handler.clearBuffer() - + if len(par_str_list) == 0: return [] - + xml_seq = self.door.run_macro(par_str_list, asynch=True) return [etree.tostring(xml_seq, pretty_print=False)] @@ -410,7 +411,7 @@ def is_RunMacro_allowed(self): def SimulateMacro(self, par_str_list): raise Exception("Not implemented yet") - + def GetMacroEnv(self, argin): macro_name = argin[0] if len(argin) > 1: @@ -419,10 +420,10 @@ def GetMacroEnv(self, argin): macro_env = self.door.get_macro_class_info(macro_name).env env = self.door.get_env(macro_env, macro_name=macro_name) ret = [] - for k,v in env.iteritems(): - ret.extend((k,v)) + for k, v in env.iteritems(): + ret.extend((k, v)) return ret - + def is_GetMacroEnv_allowed(self): return self.get_state() in [Macro.Finished, Macro.Abort, Macro.Exception] @@ -432,87 +433,87 @@ class DoorClass(SardanaDeviceClass): # Class Properties class_property_list = { - } + } # Device Properties device_property_list = { - 'Id': [DevLong64, "Internal ID", [ InvalidId ] ], + 'Id': [DevLong64, "Internal ID", [InvalidId]], 'MaxMsgBufferSize': [DevLong, - 'Maximum size for the Output, Result, Error, Warning, Debug and ' - 'Info buffers', - [512] ], + 'Maximum size for the Output, Result, Error, Warning, Debug and ' + 'Info buffers', + [512]], 'MacroServerName': [DevString, - 'Name of the macro server device to connect to. [default: None, ' - 'meaning connect to the first registered macroserver', - None ], - } + 'Name of the macro server device to connect to. [default: None, ' + 'meaning connect to the first registered macroserver', + None], + } # Command definitions cmd_list = { 'Abort': - [ [ DevVoid, ""], - [ DevVoid, ""] ], + [[DevVoid, ""], + [DevVoid, ""]], 'PauseMacro': - [ [DevVoid, ""], - [DevVoid, ""] ], + [[DevVoid, ""], + [DevVoid, ""]], 'AbortMacro': - [ [DevVoid, ""], - [DevVoid, ""] ], + [[DevVoid, ""], + [DevVoid, ""]], 'StopMacro': - [ [DevVoid, ""], - [DevVoid, ""] ], + [[DevVoid, ""], + [DevVoid, ""]], 'ResumeMacro': - [ [DevVoid, ""], - [DevVoid, ""] ], + [[DevVoid, ""], + [DevVoid, ""]], 'RunMacro': - [ [DevVarStringArray, 'Macro name and parameters'], - [DevVarStringArray, 'Macro Result']], + [[DevVarStringArray, 'Macro name and parameters'], + [DevVarStringArray, 'Macro Result']], 'SimulateMacro': - [ [DevVarStringArray, 'Macro name and parameters'], - [DevVarStringArray, 'Macro statistics']], + [[DevVarStringArray, 'Macro name and parameters'], + [DevVarStringArray, 'Macro statistics']], 'GetMacroEnv': - [ [ DevVarStringArray, 'Macro name followed by an ' \ - 'optional list of environment names' ], - [ DevVarStringArray, 'Macro environment as a list of '\ - 'pairs keys, value'] ], -# 'ReloadMacro': -# [[DevVarStringArray, "Macro(s) name(s)"], -# [DevVarStringArray, "[OK] if successfull or a traceback " \ -# "if there was a error (one string with complete traceback of " \ -# "each error)"]], -# 'ReloadMacroLib': -# [[DevVarStringArray, "MacroLib(s) name(s)"], -# [DevVarStringArray, "[OK] if successfull or a traceback " \ -# "if there was a error (one string with complete traceback of " \ -# "each error)"]], - } + [[DevVarStringArray, 'Macro name followed by an ' + 'optional list of environment names'], + [DevVarStringArray, 'Macro environment as a list of ' + 'pairs keys, value']], + # 'ReloadMacro': + # [[DevVarStringArray, "Macro(s) name(s)"], + # [DevVarStringArray, "[OK] if successfull or a traceback " \ + # "if there was a error (one string with complete traceback of " \ + # "each error)"]], + # 'ReloadMacroLib': + # [[DevVarStringArray, "MacroLib(s) name(s)"], + # [DevVarStringArray, "[OK] if successfull or a traceback " \ + # "if there was a error (one string with complete traceback of " \ + # "each error)"]], + } # Attribute definitions attr_list = { - 'Result' : [ [ DevString, SPECTRUM, READ, 512], - { 'label' : 'Result for the last macro', } ], - 'Critical' : [ [ DevString, SPECTRUM, READ, 512], - { 'label' : 'Macro critical error message', } ], - 'Error' : [ [ DevString, SPECTRUM, READ, 512], - { 'label' : 'Macro error message', } ], - 'Warning' : [ [ DevString, SPECTRUM, READ, 512], - { 'label' : 'Macro warning message', } ], - 'Info' : [ [ DevString, SPECTRUM, READ, 512], - { 'label' : 'Macro information message', } ], - 'Debug' : [ [ DevString, SPECTRUM, READ, 512], - { 'label' : 'Macro debug message', } ], - 'Output' : [ [ DevString, SPECTRUM, READ, 512], - { 'label' : 'Macro output message', } ], - 'Input' : [ [ DevString, SCALAR, READ_WRITE], - { 'label' : 'Macro input prompt', } ], - 'RecordData' : [ [ DevEncoded, SCALAR, READ], - { 'label' : 'Record Data', } ], - 'MacroStatus' : [ [ DevEncoded, SCALAR, READ], - { 'label' : 'Macro Status', } ], - 'ElementList' : [ [ DevEncoded, SCALAR, READ], - { 'label':"Element list", - 'description' : 'the list of all elements (a ' - 'JSON encoded dict)', } ], - } + 'Result': [[DevString, SPECTRUM, READ, 512], + {'label': 'Result for the last macro', }], + 'Critical': [[DevString, SPECTRUM, READ, 512], + {'label': 'Macro critical error message', }], + 'Error': [[DevString, SPECTRUM, READ, 512], + {'label': 'Macro error message', }], + 'Warning': [[DevString, SPECTRUM, READ, 512], + {'label': 'Macro warning message', }], + 'Info': [[DevString, SPECTRUM, READ, 512], + {'label': 'Macro information message', }], + 'Debug': [[DevString, SPECTRUM, READ, 512], + {'label': 'Macro debug message', }], + 'Output': [[DevString, SPECTRUM, READ, 512], + {'label': 'Macro output message', }], + 'Input': [[DevString, SCALAR, READ_WRITE], + {'label': 'Macro input prompt', }], + 'RecordData': [[DevEncoded, SCALAR, READ], + {'label': 'Record Data', }], + 'MacroStatus': [[DevEncoded, SCALAR, READ], + {'label': 'Macro Status', }], + 'ElementList': [[DevEncoded, SCALAR, READ], + {'label': "Element list", + 'description': 'the list of all elements (a ' + 'JSON encoded dict)', }], + } diff --git a/src/sardana/tango/macroserver/MacroServer.py b/src/sardana/tango/macroserver/MacroServer.py index 54951b397f..350e3144b1 100644 --- a/src/sardana/tango/macroserver/MacroServer.py +++ b/src/sardana/tango/macroserver/MacroServer.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -41,27 +41,27 @@ class MacroServer(SardanaDevice): """The MacroServer tango class""" - + ElementsCache = None EnvironmentCache = None - - def __init__(self,cl, name): + + def __init__(self, cl, name): self._macro_server = None - SardanaDevice.__init__(self,cl, name) - + SardanaDevice.__init__(self, cl, name) + def init(self, name): SardanaDevice.init(self, name) - + if self._alias is None: self._alias = Util.instance().get_ds_inst_name() - + self._macro_server = ms = MS(self.get_full_name(), self.alias) ms.add_listener(self.on_macro_server_changed) - + @property def macro_server(self): return self._macro_server - + def delete_device(self): SardanaDevice.delete_device(self) self._macro_server.clear_log_report() @@ -76,24 +76,25 @@ def init_device(self): self.set_change_event('MacroLibList', True, False) self.set_change_event('Elements', True, False) self.set_change_event('Environment', True, False) - + dev_class = self.get_device_class() self.get_device_properties(dev_class) - + self.EnvironmentDb = self._calculate_name(self.EnvironmentDb) self.LogReportFilename = self._calculate_name(self.LogReportFilename) macro_server = self.macro_server macro_server.set_python_path(self.PythonPath) macro_server.set_max_parallel_macros(self.MaxParallelMacros) - - # if it is not possible to store/retrieve the environment from the - # current path then setup a new unique path and store the environment + + # if it is not possible to store/retrieve the environment from the + # current path then setup a new unique path and store the environment # there forever try: macro_server.set_environment_db(self.EnvironmentDb) except: - self.error("Failed to set environment DB to %s", self.EnvironmentDb) + self.error("Failed to set environment DB to %s", + self.EnvironmentDb) self.debug("Details:", exc_info=1) import tempfile env_db = os.path.join(tempfile.mkdtemp(), @@ -103,9 +104,10 @@ def init_device(self): db.put_device_property(self.get_name(), dict(EnvironmentDb=env_db)) self.EnvironmentDb = env_db macro_server.set_environment_db(self.EnvironmentDb) - + try: - macro_server.set_log_report(self.LogReportFilename, self.LogReportFormat) + macro_server.set_log_report( + self.LogReportFilename, self.LogReportFormat) except: self.error("Failed to setup log report to %s", self.LogReportFilename) @@ -114,7 +116,7 @@ def init_device(self): macro_server.set_recorder_path(self.RecorderPath) macro_server.set_macro_path(self.MacroPath) macro_server.set_pool_names(self.PoolNames) - + if self.RConsolePort: try: import rfoo.utils.rconsole @@ -123,23 +125,23 @@ def init_device(self): self.warning("Failed to start rconsole") self.debug("Details:", exc_info=1) self.set_state(DevState.ON) - + def _calculate_name(self, name): if name is None: return None util = Util.instance() - return name % { 'ds_name' : util.get_ds_name().lower(), - 'ds_exec_name' : util.get_ds_exec_name(), - 'ds_inst_name' : util.get_ds_inst_name().lower() } - + return name % {'ds_name': util.get_ds_name().lower(), + 'ds_exec_name': util.get_ds_exec_name(), + 'ds_inst_name': util.get_ds_inst_name().lower()} + def on_macro_server_changed(self, evt_src, evt_type, evt_value): # during server startup and shutdown avoid processing element # creation events if SardanaServer.server_state != State.Running: return - + evt_name = evt_type.name.lower() - + multi_attr = self.get_device_attr() elems_attr = multi_attr.get_attr_by_name("Elements") if evt_name == "poolelementschanged": @@ -154,8 +156,8 @@ def on_macro_server_changed(self, evt_src, evt_type, evt_value): self.ElementsCache = None elem = evt_value - - value = { } + + value = {} if "created" in evt_name: key = 'new' else: @@ -169,7 +171,7 @@ def on_macro_server_changed(self, evt_src, evt_type, evt_value): # force the element list cache to be rebuild next time someone reads # the element list self.ElementsCache = None - + ms_name = self.macro_server.full_name new_values, changed_values, deleted_values = [], [], [] for elem in evt_value['new']: @@ -181,8 +183,8 @@ def on_macro_server_changed(self, evt_src, evt_type, evt_value): for elem in evt_value['del']: json_elem = elem.serialize(macro_server=ms_name) deleted_values.append(json_elem) - value = { "new" : new_values, "change": changed_values, - "del" : deleted_values } + value = {"new": new_values, "change": changed_values, + "del": deleted_values} value = CodecFactory().getCodec('json').encode(('', value)) self.set_attribute(elems_attr, value=value) #self.push_change_event('Elements', *value) @@ -191,31 +193,30 @@ def on_macro_server_changed(self, evt_src, evt_type, evt_value): env_attr = multi_attr.get_attr_by_name("Environment") value = CodecFactory().getCodec('pickle').encode(('', evt_value)) self.set_attribute(env_attr, value=value) - - + def always_executed_hook(self): pass - - def read_attr_hardware(self,data): + + def read_attr_hardware(self, data): pass - + def read_DoorList(self, attr): door_names = self.macro_server.get_door_names() attr.set_value(door_names) - + @DebugIt() def read_MacroList(self, attr): macro_names = self.macro_server.get_macro_names() attr.set_value(macro_names) - + def read_MacroLibList(self, attr): macro_lib_names = self.macro_server.get_macro_lib_names() attr.set_value(macro_lib_names) - + def read_TypeList(self, attr): type_names = self.macro_server.get_data_type_names_with_asterisc() attr.set_value(type_names) - + #@DebugIt() def getElements(self, cache=True): value = self.ElementsCache @@ -226,7 +227,7 @@ def getElements(self, cache=True): value = CodecFactory().getCodec('json').encode(('', value)) self.ElementsCache = value return value - + #@DebugIt() def read_Elements(self, attr): fmt, data = self.getElements() @@ -236,16 +237,16 @@ def is_Elements_allowed(self, req_type): return SardanaServer.server_state == State.Running is_DoorList_allowed = \ - is_MacroList_allowed = \ - is_MacroLibList_allowed = \ - is_TypeList_allowed = is_Elements_allowed - + is_MacroList_allowed = \ + is_MacroLibList_allowed = \ + is_TypeList_allowed = is_Elements_allowed + def GetMacroInfo(self, macro_names): """GetMacroInfo(list macro_names): - + Returns a list of string containing macro information. Each string is a JSON encoded. - + Params: - macro_name: a list of strings with the macro(s) name(s) Returns: @@ -253,14 +254,14 @@ def GetMacroInfo(self, macro_names): """ macro_server = self.macro_server codec = CodecFactory().getCodec('json') - ret = [ ] - + ret = [] + for _, macro in macro_server.get_macros().items(): if macro.name in macro_names: ret.append(codec.encode(('', macro.serialize()))[1]) - + return ret - + def ReloadMacro(self, macro_names): """ReloadMacro(list macro_names):""" try: @@ -269,7 +270,7 @@ def ReloadMacro(self, macro_names): except MacroServerException, mse: Except.throw_exception(mse.type, mse.msg, 'ReloadMacro') return ['OK'] - + def ReloadMacroLib(self, lib_names): """ReloadMacroLib(sequence lib_names): """ @@ -279,19 +280,20 @@ def ReloadMacroLib(self, lib_names): except MacroServerException, mse: Except.throw_exception(mse.type, mse.msg, 'ReloadMacroLib') return ['OK'] - + def GetMacroCode(self, argin): """GetMacroCode( [, ]) -> full filename, code, line_nb """ ret = self.macro_server.get_or_create_macro_lib(*argin) return map(str, ret) - + def SetMacroCode(self, argin): lib_name, code = argin[:2] auto_reload = True if len(argin) > 2: auto_reload = argin[2].lower() in ('true', 'yes') - self.macro_server.set_macro_lib(lib_name, code, auto_reload=auto_reload) + self.macro_server.set_macro_lib( + lib_name, code, auto_reload=auto_reload) #@DebugIt() def getEnvironment(self, cache=True): @@ -303,126 +305,124 @@ def getEnvironment(self, cache=True): value = CodecFactory().getCodec('pickle').encode(('', value)) self.EnvironmentCache = value return value - + def read_Environment(self, attr): fmt, data = self.getEnvironment() attr.set_value(fmt, data) - + def write_Environment(self, attr): data = attr.get_write_value() data = CodecFactory().getCodec('pickle').decode(data)[1] self.macro_server.change_env(data) - + def is_Environment_allowed(self, req_type): return True class MacroServerClass(SardanaDeviceClass): """MacroServer Tango class class""" - + # Class Properties class_property_list = { } - - + DefaultEnvBaseDir = "/tmp/tango" DefaultEnvRelDir = "%(ds_exec_name)s/%(ds_inst_name)s/macroserver.properties" - + DefaultLogReportFormat = '%(levelname)-8s %(asctime)s: %(message)s' - + # Device Properties device_property_list = { 'PoolNames': [DevVarStringArray, - "Sardana device pool device names", - [] ], + "Sardana device pool device names", + []], 'MacroPath': [DevVarStringArray, - "list of directories to search for macros (path separators " - "can be '\n' or ':')", - [] ], + "list of directories to search for macros (path separators " + "can be '\n' or ':')", + []], 'RecorderPath': [DevVarStringArray, - "list of directories to search for recorders (path separators " - "can be '\n' or ':')", - [] ], + "list of directories to search for recorders (path separators " + "can be '\n' or ':')", + []], 'PythonPath': [DevVarStringArray, - "list of directories to be appended to sys.path at startup (path " - "separators can be '\n' or ':')", - [] ], + "list of directories to be appended to sys.path at startup (path " + "separators can be '\n' or ':')", + []], 'MaxParallelMacros': [DevLong, - "Maximum number of macros that can execute concurrently.", - [10] ], + "Maximum number of macros that can execute concurrently.", + [10]], 'EnvironmentDb': [DevString, - "The environment database (usually a plain file).", - os.path.join(DefaultEnvBaseDir, DefaultEnvRelDir) ], + "The environment database (usually a plain file).", + os.path.join(DefaultEnvBaseDir, DefaultEnvRelDir)], 'RConsolePort': [DevLong, - "The rconsole port number", - None ], + "The rconsole port number", + None], 'LogReportFilename': [DevString, - "Filename (absolute) which contains user log reports [default: " - "None, meaning don't store log report messages]. The system will " - "save old log files by appending extensions to the filename. The " - "extensions are date-and-time based, using the strftime " - "format %Y-%m-%d_%H-%M-%S or a leading portion thereof, " - "depending on the rollover interval.", - None ], + "Filename (absolute) which contains user log reports [default: " + "None, meaning don't store log report messages]. The system will " + "save old log files by appending extensions to the filename. The " + "extensions are date-and-time based, using the strftime " + "format %Y-%m-%d_%H-%M-%S or a leading portion thereof, " + "depending on the rollover interval.", + None], 'LogReportFormat': [DevString, - "Log report format [default: '%s']" % DefaultLogReportFormat, - DefaultLogReportFormat], + "Log report format [default: '%s']" % DefaultLogReportFormat, + DefaultLogReportFormat], } # Command definitions cmd_list = { 'GetMacroInfo': [[DevVarStringArray, "Macro(s) name(s)"], - [DevVarStringArray, "Macro(s) description(s)"]], + [DevVarStringArray, "Macro(s) description(s)"]], 'ReloadMacro': [[DevVarStringArray, "Macro(s) name(s)"], - [DevVarStringArray, "[OK] if successfull or a traceback " \ - "if there was a error (one string with complete traceback of " \ + [DevVarStringArray, "[OK] if successfull or a traceback " + "if there was a error (one string with complete traceback of " "each error)"]], 'ReloadMacroLib': [[DevVarStringArray, "MacroLib(s) name(s)"], - [DevVarStringArray, "[OK] if successfull or a traceback " \ - "if there was a error (one string with complete traceback of " \ - "each error)" ]], + [DevVarStringArray, "[OK] if successfull or a traceback " + "if there was a error (one string with complete traceback of " + "each error)"]], 'GetMacroCode': [[DevVarStringArray, " [, ]"], - [DevVarStringArray, "result is a sequence of 3 strings:\n" - ", , " ]], + [DevVarStringArray, "result is a sequence of 3 strings:\n" + ", , "]], 'SetMacroCode': - [[DevVarStringArray, ", [, =True]\n" \ - "- if macro lib is a simple module name:\n" \ - " - if it exists, it is overwritten, otherwise a new python " \ - "file is created in the directory of the first element in "\ - "the MacroPath property" \ - "- if macro lib is the full path name:\n" \ - " - if path is not in the MacroPath, an exception is thrown" \ - " - if file exists it is overwritten otherwise a new file " \ + [[DevVarStringArray, ", [, =True]\n" + "- if macro lib is a simple module name:\n" + " - if it exists, it is overwritten, otherwise a new python " + "file is created in the directory of the first element in " + "the MacroPath property" + "- if macro lib is the full path name:\n" + " - if path is not in the MacroPath, an exception is thrown" + " - if file exists it is overwritten otherwise a new file " "is created"], - [DevVoid, "" ]], + [DevVoid, ""]], } # Attribute definitions attr_list = { - 'DoorList' : [ [ DevString, SPECTRUM, READ, 256 ] ], - 'MacroList' : [ [ DevString, SPECTRUM, READ, 4096 ] ], - 'MacroLibList' : [ [ DevString, SPECTRUM, READ, 1024 ] ], - 'TypeList' : [ [ DevString, SPECTRUM, READ, 256 ] ], - 'Elements' : [ [ DevEncoded, SCALAR, READ ], - { 'label' : "Elements", - 'description' : "the list of all elements " - "(a JSON encoded dict)", } ], - 'Environment' : [ [ DevEncoded, SCALAR, READ_WRITE], - { 'label' : 'Environment', - 'description' : "The macro server environment " - "(a JSON encoded dict)", } ], + 'DoorList': [[DevString, SPECTRUM, READ, 256]], + 'MacroList': [[DevString, SPECTRUM, READ, 4096]], + 'MacroLibList': [[DevString, SPECTRUM, READ, 1024]], + 'TypeList': [[DevString, SPECTRUM, READ, 256]], + 'Elements': [[DevEncoded, SCALAR, READ], + {'label': "Elements", + 'description': "the list of all elements " + "(a JSON encoded dict)", }], + 'Environment': [[DevEncoded, SCALAR, READ_WRITE], + {'label': 'Environment', + 'description': "The macro server environment " + "(a JSON encoded dict)", }], } - diff --git a/src/sardana/tango/macroserver/__init__.py b/src/sardana/tango/macroserver/__init__.py index 27b793bdb5..9cbdafb717 100644 --- a/src/sardana/tango/macroserver/__init__.py +++ b/src/sardana/tango/macroserver/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -32,11 +32,12 @@ SERVER_NAME = "MacroServer" + def prepare_macroserver(util): import taurus.core.util.log Logger = taurus.core.util.log.Logger - # Two additional log levels: + # Two additional log levels: # output of a macro Logger.addLevelName(15, "OUTPUT") @@ -50,7 +51,8 @@ def output(loggable, msg, *args, **kw): util.add_class(MacroServerClass, MacroServer) util.add_class(DoorClass, Door) - + + def main_macroserver(args=None, start_time=None, mode=None): import sardana.tango.core.util # pass server name so the scripts generated with setuptools work on Windows @@ -60,6 +62,7 @@ def main_macroserver(args=None, start_time=None, mode=None): run = main_macroserver + def main(): import datetime run(start_time=datetime.datetime.now()) diff --git a/src/sardana/tango/macroserver/test/__init__.py b/src/sardana/tango/macroserver/test/__init__.py index cfcda5aebf..6d9650059e 100644 --- a/src/sardana/tango/macroserver/test/__init__.py +++ b/src/sardana/tango/macroserver/test/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/tango/macroserver/test/base.py b/src/sardana/tango/macroserver/test/base.py index 750104160f..daf0f77597 100755 --- a/src/sardana/tango/macroserver/test/base.py +++ b/src/sardana/tango/macroserver/test/base.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -58,20 +58,21 @@ def setUp(self, pool_name): dev_name_parts = self.ms_name.split('/') prefix = '/'.join(dev_name_parts[0:2]) start_from = int(dev_name_parts[2]) - self.ms_name = get_free_device(PyTango.Database(), prefix, start_from) + self.ms_name = get_free_device( + PyTango.Database(), prefix, start_from) self._msstarter.addNewDevice(self.ms_name, klass='MacroServer') # register Door device dev_name_parts = self.door_name.split('/') prefix = '/'.join(dev_name_parts[0:2]) start_from = int(dev_name_parts[2]) - self.door_name = get_free_device(PyTango.Database(), prefix, + self.door_name = get_free_device(PyTango.Database(), prefix, start_from) self._msstarter.addNewDevice(self.door_name, klass='Door') # start MS server self._msstarter.startDs() # devices self.macroserver = PyTango.DeviceProxy(self.ms_name) - self.macroserver.put_property({'PoolNames':pool_name}) + self.macroserver.put_property({'PoolNames': pool_name}) self.macroserver.Init() self.door = PyTango.DeviceProxy(self.door_name) except Exception, e: diff --git a/src/sardana/tango/macroserver/test/macroexecutor.py b/src/sardana/tango/macroserver/test/macroexecutor.py index 5bd8a56bf0..e9708f5739 100644 --- a/src/sardana/tango/macroserver/test/macroexecutor.py +++ b/src/sardana/tango/macroserver/test/macroexecutor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -92,7 +92,7 @@ def push_event(self, *args, **kwargs): self._tango_macro_executor._done_event.set() # make sure we get it as string since PyTango 7.1.4 returns a buffer # object and json.loads doesn't support buffer objects (only str) - + attr_value = getattr(event_data, 'attr_value') if attr_value is None: return @@ -111,13 +111,13 @@ def push_event(self, *args, **kwargs): self._tango_macro_executor._exception = macro_status.get( 'exc_type') if state in self.START_STATES: - #print 'TangoStatusCb.push_event: setting _started_event' + # print 'TangoStatusCb.push_event: setting _started_event' self._tango_macro_executor._started_event.set() elif state in self.DONE_STATES: # print 'TangoStatusCb.push_event: setting _done_event %s' # %(state) self._tango_macro_executor._done_event.set() - #else: + # else: # print 'State %s' %(state) self._tango_macro_executor._state_buffer.append(state) @@ -157,7 +157,7 @@ def _run(self, macro_name, macro_params): def _wait(self, timeout): '''reimplemented from :class:`BaseMacroExecutor`''' - #TODO: In case of timeout = inf if the macro excecutor run a macro + # TODO: In case of timeout = inf if the macro excecutor run a macro # with wrong parameters it'll never awake of the done_event wait # Pending to remove this comment when Sardana resolves the bug. if self._done_event: @@ -168,7 +168,7 @@ def _wait(self, timeout): # - in case of stopping a macro, the events are emitted: first # finish and then stop # TODO: base the wait condition on the events from door state - # attribute + # attribute time.sleep(3) self._door.unsubscribe_event(self._status_id) diff --git a/src/sardana/tango/pool/CTExpChannel.py b/src/sardana/tango/pool/CTExpChannel.py index cc9fda6c2c..a9b9799356 100644 --- a/src/sardana/tango/pool/CTExpChannel.py +++ b/src/sardana/tango/pool/CTExpChannel.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -80,13 +80,13 @@ def init_device(self): name = self.alias or full_name self.ct = ct = \ self.pool.create_element(type="CTExpChannel", - name=name, full_name=full_name, id=self.Id, axis=self.Axis, - ctrl_id=self.Ctrl_id) + name=name, full_name=full_name, id=self.Id, axis=self.Axis, + ctrl_id=self.Ctrl_id) if self.instrument is not None: ct.set_instrument(self.instrument) ct.add_listener(self.on_ct_changed) - ## force a state read to initialize the state attribute + # force a state read to initialize the state attribute #state = ct.state self.set_state(DevState.ON) @@ -159,7 +159,8 @@ def _encode_value_chunk(self, value_chunk): :return: json string representing value chunk :rtype: str""" - value = []; index = [] + value = [] + index = [] for sv in value_chunk: value.append(sv.value) index.append(sv.idx) @@ -256,7 +257,7 @@ class CTExpChannelClass(PoolElementDeviceClass): # Command definitions cmd_list = { - 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], + 'Start': [[DevVoid, ""], [DevVoid, ""]], } cmd_list.update(PoolElementDeviceClass.cmd_list) @@ -265,13 +266,12 @@ class CTExpChannelClass(PoolElementDeviceClass): attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { - 'Value' : [ [ DevDouble, SCALAR, READ ], - { 'abs_change' : '1.0', } ], - 'Data' : [ [ DevString, SCALAR, READ ] ] #@TODO: think about DevEncoded + 'Value': [[DevDouble, SCALAR, READ], + {'abs_change': '1.0', }], + 'Data': [[DevString, SCALAR, READ]] # @TODO: think about DevEncoded } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) - def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "Counter/Timer device class" diff --git a/src/sardana/tango/pool/Controller.py b/src/sardana/tango/pool/Controller.py index d355c0120f..9b590505c6 100644 --- a/src/sardana/tango/pool/Controller.py +++ b/src/sardana/tango/pool/Controller.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -93,8 +93,8 @@ def init_device(self): ctrl.add_listener(self.on_controller_changed) self.ctrl = ctrl self.set_state(DevState.ON) - #self.set_state(to_tango_state(ctrl.get_state())) - #self.set_status(ctrl.get_status()) + # self.set_state(to_tango_state(ctrl.get_state())) + # self.set_status(ctrl.get_status()) else: ctrl.re_init() @@ -102,9 +102,11 @@ def get_role_ids(self): db = Util.instance().get_database() if db is None: return [] - role_ids = db.get_device_property(self.get_name(), ['motor_role_ids'])['motor_role_ids'] + role_ids = db.get_device_property(self.get_name(), ['motor_role_ids'])[ + 'motor_role_ids'] if len(role_ids) == 0: - role_ids = db.get_device_property(self.get_name(), ['counter_role_ids'])['counter_role_ids'] + role_ids = db.get_device_property(self.get_name(), ['counter_role_ids'])[ + 'counter_role_ids'] if len(role_ids) == 0: role_ids = self.Role_ids role_ids = map(int, role_ids) @@ -124,9 +126,11 @@ def _get_ctrl_properties(self): props = {} if prop_infos: - props.update(db.get_device_property(self.get_name(), prop_infos.keys())) + props.update(db.get_device_property( + self.get_name(), prop_infos.keys())) for p in props.keys(): - if len(props[p]) == 0: props[p] = None + if len(props[p]) == 0: + props[p] = None ret = {} missing_props = [] @@ -189,7 +193,7 @@ def DeleteElement(self, argin): def get_element_names(self): elements = self.ctrl.get_elements() - return [ elements[id].get_name() for id in sorted(elements) ] + return [elements[id].get_name() for id in sorted(elements)] def on_controller_changed(self, event_src, event_type, event_value): # during server startup and shutdown avoid processing element @@ -226,7 +230,8 @@ def get_dynamic_attributes(self): return self._standard_attributes_cache, self._dynamic_attributes_cache info = self.ctrl.ctrl_info if info is None: - self.warning("Controller %s doesn't have any information", self.ctrl) + self.warning( + "Controller %s doesn't have any information", self.ctrl) return PoolDevice.get_dynamic_attributes(self) self._dynamic_attributes_cache = dyn_attrs = CaselessDict() self._standard_attributes_cache = std_attrs = CaselessDict() @@ -262,28 +267,28 @@ class ControllerClass(PoolDeviceClass): # Device Properties device_property_list = { - 'Type': [DevString, "", None ], - 'Library': [DevString, "", None ], - 'Klass': [DevString, "", None ], - 'Role_ids': [DevVarLongArray, "", [] ], + 'Type': [DevString, "", None], + 'Library': [DevString, "", None], + 'Klass': [DevString, "", None], + 'Role_ids': [DevVarLongArray, "", []], } device_property_list.update(PoolDeviceClass.device_property_list) # Command definitions cmd_list = { - 'CreateElement': [ [DevVarStringArray, ""], [DevVoid, ""] ], - 'DeleteElement': [ [DevString, ""], [DevVoid, ""] ], + 'CreateElement': [[DevVarStringArray, ""], [DevVoid, ""]], + 'DeleteElement': [[DevString, ""], [DevVoid, ""]], } cmd_list.update(PoolDeviceClass.cmd_list) # Attribute definitions attr_list = { - 'ElementList': [ [DevString, SPECTRUM, READ, 4096] ], - 'LogLevel': [ [DevLong, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'label' : "Log level", - 'Display level' : DispLevel.EXPERT } ], - } + 'ElementList': [[DevString, SPECTRUM, READ, 4096]], + 'LogLevel': [[DevLong, SCALAR, READ_WRITE], + {'Memorized': "true", + 'label': "Log level", + 'Display level': DispLevel.EXPERT}], + } attr_list.update(PoolDeviceClass.attr_list) def _get_class_properties(self): @@ -291,4 +296,3 @@ def _get_class_properties(self): ret['Description'] = "Controller device class" ret['InheritedFrom'].insert(0, 'PoolDevice') return ret - diff --git a/src/sardana/tango/pool/IORegister.py b/src/sardana/tango/pool/IORegister.py index e961f64c61..56ee9c1109 100644 --- a/src/sardana/tango/pool/IORegister.py +++ b/src/sardana/tango/pool/IORegister.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -69,14 +69,16 @@ def set_ior(self, ior): def set_write_value_to_db(self): value_attr = self.ior.get_value_attribute() if value_attr.has_write_value(): - data = dict(Value=dict(__value=value_attr.w_value, __value_ts=value_attr.w_timestamp)) + data = dict(Value=dict(__value=value_attr.w_value, + __value_ts=value_attr.w_timestamp)) db = self.get_database() db.put_device_attribute_property(self.get_name(), data) def get_write_value_from_db(self): name = 'Value' db = self.get_database() - val_props = db.get_device_attribute_property(self.get_name(), name)[name] + val_props = db.get_device_attribute_property( + self.get_name(), name)[name] w_val = val_props["__value"][0] _, _, attr_info = self.get_dynamic_attributes()[0][name] @@ -104,13 +106,13 @@ def init_device(self): name = self.alias or full_name self.ior = ior = \ self.pool.create_element(type="IORegister", name=name, - full_name=full_name, id=self.Id, axis=self.Axis, - ctrl_id=self.Ctrl_id) + full_name=full_name, id=self.Id, axis=self.Axis, + ctrl_id=self.Ctrl_id) if self.instrument is not None: ior.set_instrument(self.instrument) ior.add_listener(self.on_ior_changed) - ## force a state read to initialize the state attribute + # force a state read to initialize the state attribute #state = ior.get_state(cache=False) self.set_state(DevState.ON) @@ -231,7 +233,7 @@ class IORegisterClass(PoolElementDeviceClass): # Command definitions cmd_list = { - 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], + 'Start': [[DevVoid, ""], [DevVoid, ""]], } cmd_list.update(PoolElementDeviceClass.cmd_list) @@ -240,8 +242,8 @@ class IORegisterClass(PoolElementDeviceClass): attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { - 'Value' : [ [ DevLong, SCALAR, READ_WRITE ], - { 'Memorized' : "true_without_hard_applied", }, ], + 'Value': [[DevLong, SCALAR, READ_WRITE], + {'Memorized': "true_without_hard_applied", }, ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) diff --git a/src/sardana/tango/pool/MeasurementGroup.py b/src/sardana/tango/pool/MeasurementGroup.py index ab6fd63158..343fefda99 100644 --- a/src/sardana/tango/pool/MeasurementGroup.py +++ b/src/sardana/tango/pool/MeasurementGroup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -90,8 +90,8 @@ def init_device(self): name = self.alias or full_name self.measurement_group = mg = \ self.pool.create_measurement_group(name=name, - full_name=full_name, id=self.Id, - user_elements=self.Elements) + full_name=full_name, id=self.Id, + user_elements=self.Elements) mg.add_listener(self.on_measurement_group_changed) # force a state read to initialize the state attribute @@ -100,7 +100,8 @@ def init_device(self): def on_measurement_group_changed(self, event_source, event_type, event_value): try: - self._on_measurement_group_changed(event_source, event_type, event_value) + self._on_measurement_group_changed( + event_source, event_type, event_value) except: msg = 'Error occured "on_measurement_group_changed(%s.%s): %s"' exc_info = sys.exc_info() @@ -200,7 +201,7 @@ def write_AcquisitionMode(self, attr): try: acq_mode = AcqMode.lookup[acq_mode_str] except KeyError: - raise Exception("Invalid acquisition mode. Must be one of " + \ + raise Exception("Invalid acquisition mode. Must be one of " + ", ".join(AcqMode.keys())) self.measurement_group.acquisition_mode = acq_mode @@ -243,7 +244,7 @@ def write_Synchronization(self, attr): data = attr.get_write_value() synchronization = CodecFactory().decode(('json', data), ensure_ascii=True) - # translate dictionary keys + # translate dictionary keys synchronization = self._synchronization_str2enum(synchronization) self.measurement_group.synchronization = synchronization @@ -268,6 +269,7 @@ def StartMultiple(self, n): raise Exception("Cannot acquire: already involved in an operation") self.measurement_group.start_acquisition(multiple=n) + class MeasurementGroupClass(PoolGroupDeviceClass): # Class Properties @@ -281,36 +283,36 @@ class MeasurementGroupClass(PoolGroupDeviceClass): # Command definitions cmd_list = { - 'Start': [ [DevVoid, ""], [DevVoid, ""] ], - 'StartMultiple': [ [DevLong, ""], [DevVoid, ""] ], + 'Start': [[DevVoid, ""], [DevVoid, ""]], + 'StartMultiple': [[DevLong, ""], [DevVoid, ""]], } cmd_list.update(PoolGroupDeviceClass.cmd_list) # Attribute definitions attr_list = { - 'IntegrationTime': [ [DevDouble, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'Display level' : DispLevel.OPERATOR } ], - 'MonitorCount': [ [DevLong, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'Display level' : DispLevel.OPERATOR } ], - 'AcquisitionMode': [ [DevString, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'Display level' : DispLevel.OPERATOR } ], - 'Configuration': [ [DevString, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'Display level' : DispLevel.EXPERT } ], - 'Repetitions': [ [DevLong, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'Display level' : DispLevel.OPERATOR } ], - 'Moveable': [ [DevString, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'Display level' : DispLevel.EXPERT } ], - 'Synchronization': [ [DevString, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'Display level' : DispLevel.EXPERT } ], - 'LatencyTime': [ [DevDouble, SCALAR, READ], - { 'Display level' : DispLevel.EXPERT } ], + 'IntegrationTime': [[DevDouble, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.OPERATOR}], + 'MonitorCount': [[DevLong, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.OPERATOR}], + 'AcquisitionMode': [[DevString, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.OPERATOR}], + 'Configuration': [[DevString, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.EXPERT}], + 'Repetitions': [[DevLong, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.OPERATOR}], + 'Moveable': [[DevString, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.EXPERT}], + 'Synchronization': [[DevString, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.EXPERT}], + 'LatencyTime': [[DevDouble, SCALAR, READ], + {'Display level': DispLevel.EXPERT}], } attr_list.update(PoolGroupDeviceClass.attr_list) diff --git a/src/sardana/tango/pool/Motor.py b/src/sardana/tango/pool/Motor.py index 1b7111b020..7edd6f9446 100644 --- a/src/sardana/tango/pool/Motor.py +++ b/src/sardana/tango/pool/Motor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -51,7 +51,7 @@ class Motor(PoolElementDevice): """The tango motor device class. This class exposes through a tango device the sardana motor (:class:`~sardana.pool.poolmotor.PoolMotor`). - + .. rubric:: The states The motor interface knows five states which are ON, MOVING, ALARM, @@ -131,9 +131,9 @@ class Motor(PoolElementDevice): - **DialPosition** : This attribute is the motor dial position. The following formula links together the Position, DialPosition, Sign and Offset attributes: - + Position = Sign * DialPosition + Offset - + This allows to have the motor position centered around any position defined by the Offset attribute (classically the X ray beam position). It is a read only attribute. To set the motor position, the user has @@ -174,11 +174,11 @@ class Motor(PoolElementDevice): spectrum attribute with 3 values which are: - Data[0] : The Home switch value - + - Data[1] : The Upper switch value - + - Data[2] : The Lower switch value - + - **SimulationMode** : This is a read only scalar boolean attribute. When set, all motion requests are not forwarded to the software controller and then to the hardware. When set, the motor position is simulated and is immediately @@ -213,7 +213,7 @@ class Motor(PoolElementDevice): MOVING. Some hardware motor controllers are able to manage this backlash feature. If it is not the case, the motor interface will implement this behavior. - + All the motor devices will have the already described attributes but some hardware motor controller supports other features which are not covered by this list of pre-defined attributes. Using Tango dynamic @@ -289,14 +289,16 @@ def set_motor(self, motor): def set_write_dial_position_to_db(self): dial = self.motor.get_dial_position_attribute() if dial.has_write_value(): - data = dict(DialPosition=dict(__value=dial.w_value, __value_ts=dial.w_timestamp)) + data = dict(DialPosition=dict( + __value=dial.w_value, __value_ts=dial.w_timestamp)) db = self.get_database() db.put_device_attribute_property(self.get_name(), data) def get_write_dial_position_from_db(self): name = 'DialPosition' db = self.get_database() - pos_props = db.get_device_attribute_property(self.get_name(), name)[name] + pos_props = db.get_device_attribute_property( + self.get_name(), name)[name] w_pos = pos_props["__value"][0] _, _, attr_info = self.get_dynamic_attributes()[0][name] @@ -323,8 +325,8 @@ def init_device(self): name = self.alias or full_name self.motor = motor = \ self.pool.create_element(type="Motor", name=name, - full_name=full_name, id=self.Id, axis=self.Axis, - ctrl_id=self.Ctrl_id) + full_name=full_name, id=self.Id, axis=self.Axis, + ctrl_id=self.Ctrl_id) if self.instrument is not None: motor.set_instrument(self.instrument) # if in constructor, for all memorized no init attributes (position) @@ -365,7 +367,8 @@ def _on_motor_changed(self, event_source, event_type, event_value): name = event_type.name.lower() if name == "w_position" and not self.in_write_position: - self.debug("Storing dial set point: %s", self.motor.dial_position.w_value) + self.debug("Storing dial set point: %s", + self.motor.dial_position.w_value) self.set_write_dial_position_to_db() return @@ -614,21 +617,21 @@ class MotorClass(PoolElementDeviceClass): # Device Properties device_property_list = { - 'Sleep_bef_last_read' : [DevLong, - "Number of mS to sleep before the last read during a motor " - "movement", 0], - '_Acceleration' : [DevDouble, "", -1], - '_Deceleration' : [DevDouble, "", -1], - '_Velocity' : [DevDouble, "", -1], - '_Base_rate' : [DevDouble, "", -1], + 'Sleep_bef_last_read': [DevLong, + "Number of mS to sleep before the last read during a motor " + "movement", 0], + '_Acceleration': [DevDouble, "", -1], + '_Deceleration': [DevDouble, "", -1], + '_Velocity': [DevDouble, "", -1], + '_Base_rate': [DevDouble, "", -1], } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { - 'DefinePosition' : [ [DevDouble, "New position"], [DevVoid, ""] ], - 'SaveConfig' : [ [DevVoid, ""], [DevVoid, ""] ], - 'MoveRelative' : [ [DevDouble, "amount to move"], [DevVoid, ""] ], + 'DefinePosition': [[DevDouble, "New position"], [DevVoid, ""]], + 'SaveConfig': [[DevVoid, ""], [DevVoid, ""]], + 'MoveRelative': [[DevDouble, "amount to move"], [DevVoid, ""]], } cmd_list.update(PoolElementDeviceClass.cmd_list) @@ -637,42 +640,42 @@ class MotorClass(PoolElementDeviceClass): attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { - 'Position' : [ [ DevDouble, SCALAR, READ_WRITE ], - { 'abs_change' : '1.0', } ], - 'Acceleration' : [ [ DevDouble, SCALAR, READ_WRITE ], - { 'Memorized' : "true", } ], - 'Deceleration' : [ [ DevDouble, SCALAR, READ_WRITE ], - { 'Memorized' : "true", } ], - 'Base_rate' : [ [ DevDouble, SCALAR, READ_WRITE ], - { 'Memorized' : "true", - 'label' : 'Base rate', } ], - 'Velocity' : [ [ DevDouble, SCALAR, READ_WRITE ], - { 'Memorized' : "true", } ], - 'Offset' : [ [ DevDouble, SCALAR, READ_WRITE ], - { 'Memorized' : "true", - 'Display level' : DispLevel.EXPERT } ], - 'DialPosition' : [ [ DevDouble, SCALAR, READ ], - { 'label' : "Dial position", - 'Display level' : DispLevel.EXPERT } ], - 'Step_per_unit': [ [ DevDouble, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'label' : "Steps p/ unit", - 'Display level' : DispLevel.EXPERT } ], - 'Backlash' : [ [ DevLong, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'Display level' : DispLevel.EXPERT } ], - 'Sign' : [ [ DevShort, SCALAR, READ_WRITE], - { 'Memorized' : "true", - 'Display level' : DispLevel.EXPERT } ], - 'Limit_switches': [ [ DevBoolean, SPECTRUM, READ, 3], - { 'label' : "Limit switches (H,U,L)", - 'description' : "This attribute is the motor "\ - "limit switches state. It's an array with 3 \n"\ - "elements which are:\n"\ - "0 - The home switch\n"\ - "1 - The upper limit switch\n"\ - "2 - The lower limit switch\n"\ - "False means not active. True means active" } ], + 'Position': [[DevDouble, SCALAR, READ_WRITE], + {'abs_change': '1.0', }], + 'Acceleration': [[DevDouble, SCALAR, READ_WRITE], + {'Memorized': "true", }], + 'Deceleration': [[DevDouble, SCALAR, READ_WRITE], + {'Memorized': "true", }], + 'Base_rate': [[DevDouble, SCALAR, READ_WRITE], + {'Memorized': "true", + 'label': 'Base rate', }], + 'Velocity': [[DevDouble, SCALAR, READ_WRITE], + {'Memorized': "true", }], + 'Offset': [[DevDouble, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.EXPERT}], + 'DialPosition': [[DevDouble, SCALAR, READ], + {'label': "Dial position", + 'Display level': DispLevel.EXPERT}], + 'Step_per_unit': [[DevDouble, SCALAR, READ_WRITE], + {'Memorized': "true", + 'label': "Steps p/ unit", + 'Display level': DispLevel.EXPERT}], + 'Backlash': [[DevLong, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.EXPERT}], + 'Sign': [[DevShort, SCALAR, READ_WRITE], + {'Memorized': "true", + 'Display level': DispLevel.EXPERT}], + 'Limit_switches': [[DevBoolean, SPECTRUM, READ, 3], + {'label': "Limit switches (H,U,L)", + 'description': "This attribute is the motor " + "limit switches state. It's an array with 3 \n" + "elements which are:\n" + "0 - The home switch\n" + "1 - The upper limit switch\n" + "2 - The lower limit switch\n" + "False means not active. True means active"}], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) diff --git a/src/sardana/tango/pool/MotorGroup.py b/src/sardana/tango/pool/MotorGroup.py index 482fd74ee4..d5570f2782 100644 --- a/src/sardana/tango/pool/MotorGroup.py +++ b/src/sardana/tango/pool/MotorGroup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -84,7 +84,7 @@ def init_device(self): name = self.alias or full_name self.motor_group = motor_group = \ self.pool.create_motor_group(name=name, id=self.Id, - full_name=full_name, user_elements=self.Elements) + full_name=full_name, user_elements=self.Elements) motor_group.add_listener(self.on_motor_group_changed) self.set_state(DevState.ON) @@ -216,7 +216,7 @@ class MotorGroupClass(PoolGroupDeviceClass): # Attribute definitions attr_list = { - 'Position' : [ [ DevDouble, SPECTRUM, READ_WRITE, 4096 ], ], + 'Position': [[DevDouble, SPECTRUM, READ_WRITE, 4096], ], } attr_list.update(PoolGroupDeviceClass.attr_list) diff --git a/src/sardana/tango/pool/OneDExpChannel.py b/src/sardana/tango/pool/OneDExpChannel.py index 2d3cf465ba..7bfc3a74d1 100644 --- a/src/sardana/tango/pool/OneDExpChannel.py +++ b/src/sardana/tango/pool/OneDExpChannel.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -78,13 +78,13 @@ def init_device(self): name = self.alias or full_name self.oned = oned = \ self.pool.create_element(type="OneDExpChannel", - name=name, full_name=full_name, id=self.Id, axis=self.Axis, - ctrl_id=self.Ctrl_id) + name=name, full_name=full_name, id=self.Id, axis=self.Axis, + ctrl_id=self.Ctrl_id) if self.instrument is not None: oned.set_instrument(self.instrument) oned.add_listener(self.on_oned_changed) - ## force a state read to initialize the state attribute + # force a state read to initialize the state attribute #state = ct.state self.set_state(DevState.ON) @@ -203,7 +203,8 @@ def Start(self): _DFT_VALUE_INFO = OneDController.standard_axis_attributes['Value'] _DFT_VALUE_MAX_SHAPE = _DFT_VALUE_INFO[MaxDimSize] -_DFT_VALUE_TYPE, _DFT_VALUE_FORMAT = to_tango_type_format(_DFT_VALUE_INFO[Type], DataFormat.OneD) +_DFT_VALUE_TYPE, _DFT_VALUE_FORMAT = to_tango_type_format( + _DFT_VALUE_INFO[Type], DataFormat.OneD) class OneDExpChannelClass(PoolElementDeviceClass): @@ -219,20 +220,20 @@ class OneDExpChannelClass(PoolElementDeviceClass): # Command definitions cmd_list = { - 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], + 'Start': [[DevVoid, ""], [DevVoid, ""]], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions attr_list = { - 'DataSource' : [ [ DevString, SCALAR, READ ] ], + 'DataSource': [[DevString, SCALAR, READ]], } attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { - 'Value' : [ [ _DFT_VALUE_TYPE, _DFT_VALUE_FORMAT, READ, - _DFT_VALUE_MAX_SHAPE[0] ], - { 'abs_change' : '1.0', } ], + 'Value': [[_DFT_VALUE_TYPE, _DFT_VALUE_FORMAT, READ, + _DFT_VALUE_MAX_SHAPE[0]], + {'abs_change': '1.0', }], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) diff --git a/src/sardana/tango/pool/Pool.py b/src/sardana/tango/pool/Pool.py index 9cf80a7a3d..18686066b4 100644 --- a/src/sardana/tango/pool/Pool.py +++ b/src/sardana/tango/pool/Pool.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -83,7 +83,7 @@ def pool(self): @DebugIt() def delete_device(self): - #self.pool.monitor.pause() + # self.pool.monitor.pause() pass @DebugIt() @@ -94,7 +94,8 @@ def init_device(self): p.set_python_path(self.PythonPath) p.set_path(self.PoolPath) p.set_motion_loop_sleep_time(self.MotionLoop_SleepTime / 1000.0) - p.set_motion_loop_states_per_position(self.MotionLoop_StatesPerPosition) + p.set_motion_loop_states_per_position( + self.MotionLoop_StatesPerPosition) p.set_acq_loop_sleep_time(self.AcqLoop_SleepTime / 1000.0) p.set_acq_loop_states_per_value(self.AcqLoop_StatesPerValue) p.set_drift_correction(self.DriftCorrection) @@ -121,8 +122,8 @@ def init_device(self): self.set_change_event("State", True, False) self.set_change_event("Status", True, False) self.set_change_event("Elements", True, False) - #hold the monitor thread for now! - #self.pool.monitor.resume() + # hold the monitor thread for now! + # self.pool.monitor.resume() self.set_state(PyTango.DevState.ON) def _recalculate_instruments(self): @@ -135,7 +136,7 @@ def _recalculate_instruments(self): iid = int(iid) ids.add(iid) if iid in instruments: - #TODO make sure the instrument didn't change + # TODO make sure the instrument didn't change pass else: p.create_instrument(iname, iklass, id=iid) @@ -166,7 +167,7 @@ def read_ControllerList(self, attr): def read_InstrumentList(self, attr): #instruments = self._pool.get_elements_by_type(ElementType.Instrument) #instrument_names = map(PoolInstrument.get_full_name, instruments) - #attr.set_value(instrument_names) + # attr.set_value(instrument_names) info = self.pool.get_elements_str_info(ElementType.Instrument) attr.set_value(info) @@ -174,9 +175,12 @@ def read_InstrumentList(self, attr): def read_ExpChannelList(self, attr): info = [] info.extend(self.pool.get_elements_str_info(ElementType.CTExpChannel)) - info.extend(self.pool.get_elements_str_info(ElementType.ZeroDExpChannel)) - info.extend(self.pool.get_elements_str_info(ElementType.OneDExpChannel)) - info.extend(self.pool.get_elements_str_info(ElementType.TwoDExpChannel)) + info.extend(self.pool.get_elements_str_info( + ElementType.ZeroDExpChannel)) + info.extend(self.pool.get_elements_str_info( + ElementType.OneDExpChannel)) + info.extend(self.pool.get_elements_str_info( + ElementType.TwoDExpChannel)) info.extend(self.pool.get_elements_str_info(ElementType.PseudoCounter)) attr.set_value(info) @@ -195,7 +199,7 @@ def read_MotorList(self, attr): info = self.pool.get_elements_str_info(ElementType.Motor) info.extend(self.pool.get_elements_str_info(ElementType.PseudoMotor)) attr.set_value(info) - + #@DebugIt() def read_TriggerGateList(self, attr): info = self.pool.get_elements_str_info(ElementType.TriggerGate) @@ -236,17 +240,17 @@ def is_Elements_allowed(self, req_type): return SardanaServer.server_state == State.Running is_ControllerLibList_allowed = \ - is_ControllerClassList_allowed = \ - is_ControllerList_allowed = \ - is_InstrumentList_allowed = \ - is_ExpChannelList_allowed = \ - is_TriggerGateList_allowed = \ - is_AcqChannelList_allowed = \ - is_MotorGroupList_allowed = \ - is_MotorList_allowed = \ - is_MeasurementGroupList_allowed = \ - is_IORegisterList_allowed = \ - is_ComChannelList_allowed = is_Elements_allowed + is_ControllerClassList_allowed = \ + is_ControllerList_allowed = \ + is_InstrumentList_allowed = \ + is_ExpChannelList_allowed = \ + is_TriggerGateList_allowed = \ + is_AcqChannelList_allowed = \ + is_MotorGroupList_allowed = \ + is_MotorList_allowed = \ + is_MeasurementGroupList_allowed = \ + is_IORegisterList_allowed = \ + is_ComChannelList_allowed = is_Elements_allowed def _get_interface_ids(self, interface, elem_names): _pool, motor_ids = self.pool, [] @@ -454,7 +458,7 @@ def CreateInstrument(self, argin): instrument_list.append(instrument.full_name) instrument_list.append(instrument.id) db = PyTango.Util.instance().get_database() - props = { 'InstrumentList' : instrument_list } + props = {'InstrumentList': instrument_list} db.put_device_property(self.get_name(), props) #@DebugIt() @@ -514,8 +518,8 @@ def _create_single_element(self, kwargs): def create_element_cb(device_name): try: db = util.get_database() - data = { "id" : self.pool.get_new_id(), - "ctrl_id" : ctrl.get_id(), "axis" : axis, } + data = {"id": self.pool.get_new_id(), + "ctrl_id": ctrl.get_id(), "axis": axis, } if elem_type in TYPE_PSEUDO_ELEMENTS: data['elements'] = kwargs['elements'] @@ -523,22 +527,23 @@ def create_element_cb(device_name): data = {} if elem_type == ElementType.Motor: - data["position"] = { "abs_change" : "1.0"} - data["dialposition"] = { "abs_change" : "5.0"} + data["position"] = {"abs_change": "1.0"} + data["dialposition"] = {"abs_change": "5.0"} elif elem_type == ElementType.CTExpChannel: - data["value"] = { "abs_change" : "1.0"} + data["value"] = {"abs_change": "1.0"} elif elem_type == ElementType.PseudoMotor: - data["position"] = { "abs_change" : "1.0"} + data["position"] = {"abs_change": "1.0"} elif elem_type == ElementType.PseudoCounter: - data["value"] = { "abs_change" : "1.0"} + data["value"] = {"abs_change": "1.0"} elif elem_type == ElementType.IORegister: - data["value"] = { "abs_change" : "1"} + data["value"] = {"abs_change": "1"} db.put_device_attribute_property(device_name, data) except: import traceback traceback.print_exc() - util.create_device(elem_type_str, full_name, name, cb=create_element_cb) + util.create_device(elem_type_str, full_name, + name, cb=create_element_cb) # Hack to register event abs change until tango bug #3151801 is solved elem_proxy = PyTango.DeviceProxy(full_name) @@ -555,7 +560,8 @@ def create_element_cb(device_name): pass try: if get_tango_version_number() < 80000: - attr = elem_proxy.get_attribute_config_ex("limit_switches")[0] + attr = elem_proxy.get_attribute_config_ex("limit_switches")[ + 0] attr.events.ch_event.abs_change = "1" cfg.append(attr) except: @@ -623,12 +629,12 @@ def CreateMotorGroup(self, argin): def create_motgrp_cb(device_name): db = util.get_database() - data = { "id" : self.pool.get_new_id(), - "elements" : elem_ids } + data = {"id": self.pool.get_new_id(), + "elements": elem_ids} db.put_device_property(device_name, data) data = {} - data["position"] = { "abs_change" : "1.0" } + data["position"] = {"abs_change": "1.0"} db.put_device_attribute_property(device_name, data) @@ -665,11 +671,11 @@ def CreateMeasurementGroup(self, argin): def create_mntgrp_cb(device_name): db = util.get_database() - data = { "id" : self.pool.get_new_id(), - "elements" : elem_ids } + data = {"id": self.pool.get_new_id(), + "elements": elem_ids} db.put_device_property(device_name, data) - data = { } + data = {} db.put_device_attribute_property(device_name, data) @@ -685,14 +691,16 @@ def _check_element(self, name, full_name): e = Exception("The tango alias '%s' already exists" % name) except: pass - if e: raise e + if e: + raise e try: db.import_device(full_name) e = Exception("The tango device '%s' already exists" % full_name) except: pass - if e: raise e + if e: + raise e def on_pool_changed(self, evt_src, evt_type, evt_value): # during server startup and shutdown avoid processing element @@ -718,7 +726,7 @@ def on_pool_changed(self, evt_src, evt_type, evt_value): # the element list self.ElementsCache = None - value = { } + value = {} if evt_name == "elementcreated": key = 'new' elif evt_name == "elementdeleted": @@ -744,8 +752,8 @@ def on_pool_changed(self, evt_src, evt_type, evt_value): for elem in evt_value['del']: json_elem = elem.serialize(pool=pool_name) deleted_values.append(json_elem) - value = { "new" : new_values, "change": changed_values, - "del" : deleted_values } + value = {"new": new_values, "change": changed_values, + "del": deleted_values} value = CodecFactory().getCodec('json').encode(('', value)) self.push_change_event('Elements', *value) @@ -767,8 +775,8 @@ def _format_CreateElement_arguments(self, argin): if len(argin) == 1: return self._format_create_json_arguments(argin) - ret = { 'type' : argin[0], 'ctrl_name' : argin[1], 'axis': int(argin[2]), - 'name' : argin[3] } + ret = {'type': argin[0], 'ctrl_name': argin[1], 'axis': int(argin[2]), + 'name': argin[3]} if len(argin) > 4: ret['full_name'] = argin[4] return [ret] @@ -791,8 +799,8 @@ def _format_CreateController_arguments(self, argin): ret['properties'] = CaselessDict() return ret - ret = { 'type' : argin[0], 'library' : argin[1], 'klass' : argin[2], - 'name' : argin[3] } + ret = {'type': argin[0], 'library': argin[1], 'klass': argin[2], + 'name': argin[3]} i = 4 roles = {} @@ -834,7 +842,7 @@ def _format_CreateMotorGroup_arguments(self, argin): d[str(k)] = str(v) ret.append(d) return ret - ret = { 'name' : argin[0] } + ret = {'name': argin[0]} if argin[-1].count('/') == 2: ret['full_name'] = argin[-1] del argin[-1] @@ -859,8 +867,8 @@ def _format_CreateMeasurementGroup_arguments(self, argin): d[str(k)] = str(v) ret.append(d) return ret - ret = { 'name' : argin[0] } - #if argin[-1].count('/') == 2: + ret = {'name': argin[0]} + # if argin[-1].count('/') == 2: # ret['full_name'] = argin[-1] # del argin[-1] channels = [] @@ -887,7 +895,7 @@ def DeleteElement(self, name): elem_type = elem.get_type() if elem_type == ElementType.Controller: if len(elem.get_elements()) > 0: - raise Exception("Cannot delete controller with elements. " \ + raise Exception("Cannot delete controller with elements. " "Delete elements first") td = TYPE_MAP_OBJ[elem_type] @@ -902,7 +910,7 @@ def DeleteElement(self, name): idx = il.index(full_name) self.InstrumentList = il[:idx - 1] + il[idx + 2:] db = PyTango.Util.instance().get_database() - props = { 'InstrumentList' : self.InstrumentList } + props = {'InstrumentList': self.InstrumentList} db.put_device_property(self.get_name(), props) else: util = PyTango.Util.instance() @@ -1282,54 +1290,54 @@ class PoolClass(PyTango.DeviceClass): # Class Properties class_property_list = { - } + } # Device Properties device_property_list = { 'PoolPath': [PyTango.DevVarStringArray, - "list of directories to search for controllers (path separators " - "can be '\n' or ':')", - []], + "list of directories to search for controllers (path separators " + "can be '\n' or ':')", + []], 'PythonPath': [PyTango.DevVarStringArray, - "list of directories to be appended to sys.path at startup (path " - "separators can be '\n' or ':')", - []], + "list of directories to be appended to sys.path at startup (path " + "separators can be '\n' or ':')", + []], 'MotionLoop_SleepTime': [PyTango.DevLong, - "Sleep time in the motion loop in mS [default: %dms]" % - int(POOL.Default_MotionLoop_SleepTime * 1000), - int(POOL.Default_MotionLoop_SleepTime * 1000)], + "Sleep time in the motion loop in mS [default: %dms]" % + int(POOL.Default_MotionLoop_SleepTime * 1000), + int(POOL.Default_MotionLoop_SleepTime * 1000)], 'MotionLoop_StatesPerPosition': [PyTango.DevLong, - "Number of State reads done before doing a position read in the " - "motion loop [default: %d]" % POOL.Default_MotionLoop_StatesPerPosition, - POOL.Default_MotionLoop_StatesPerPosition], + "Number of State reads done before doing a position read in the " + "motion loop [default: %d]" % POOL.Default_MotionLoop_StatesPerPosition, + POOL.Default_MotionLoop_StatesPerPosition], 'AcqLoop_SleepTime': [PyTango.DevLong, - "Sleep time in the acquisition loop in mS [default: %dms]" % - int(POOL.Default_AcqLoop_SleepTime * 1000), - int(POOL.Default_AcqLoop_SleepTime * 1000)], + "Sleep time in the acquisition loop in mS [default: %dms]" % + int(POOL.Default_AcqLoop_SleepTime * 1000), + int(POOL.Default_AcqLoop_SleepTime * 1000)], 'AcqLoop_StatesPerValue': [PyTango.DevLong, - "Number of State reads done before doing a value read in the " - "acquisition loop [default: %d]" % POOL.Default_AcqLoop_StatesPerValue, - POOL.Default_AcqLoop_StatesPerValue], + "Number of State reads done before doing a value read in the " + "acquisition loop [default: %d]" % POOL.Default_AcqLoop_StatesPerValue, + POOL.Default_AcqLoop_StatesPerValue], 'RemoteLog': [PyTango.DevString, - "Logging (python logging) host:port [default: None]", - None], + "Logging (python logging) host:port [default: None]", + None], 'DriftCorrection': [PyTango.DevBoolean, - "Globally apply drift correction on pseudo motors (can be " - "overwritten at PseudoMotor level [default: %d]." % - POOL.Default_DriftCorrection, - POOL.Default_DriftCorrection], + "Globally apply drift correction on pseudo motors (can be " + "overwritten at PseudoMotor level [default: %d]." % + POOL.Default_DriftCorrection, + POOL.Default_DriftCorrection], 'InstrumentList': [PyTango.DevVarStringArray, - "List of instruments (internal property)", - []], + "List of instruments (internal property)", + []], } # Command definitions @@ -1351,7 +1359,7 @@ class PoolClass(PyTango.DeviceClass): [PyTango.DevVoid, CREATE_MEASUREMENT_GROUP_PAR_OUT_DOC]], 'DeleteElement': [[PyTango.DevString, DELETE_ELEMENT_PAR_IN_DOC], - [PyTango.DevVoid, DELETE_ELEMENT_PAR_OUT_DOC]], + [PyTango.DevVoid, DELETE_ELEMENT_PAR_OUT_DOC]], 'GetControllerClassInfo': [[PyTango.DevString, GET_CONTROLLER_CLASS_INFO_PAR_IN_DOC], [PyTango.DevString, GET_CONTROLLER_CLASS_INFO_PAR_OUT_DOC]], @@ -1366,19 +1374,19 @@ class PoolClass(PyTango.DeviceClass): [PyTango.DevVoid, RENAME_ELEMENT_PAR_OUT_DOC]], 'GetControllerCode': [[PyTango.DevVarStringArray, " [, ]"], - [PyTango.DevVarStringArray, "result is a sequence of 3 strings:\n" - ", , " ]], + [PyTango.DevVarStringArray, "result is a sequence of 3 strings:\n" + ", , "]], 'SetControllerCode': - [[PyTango.DevVarStringArray, ", [, =True]\n" \ - "- if controller library is a simple module name:\n" \ - " - if it exists, it is overwritten, otherwise a new python " \ - "file is created in the directory of the first element in "\ - "the PoolPath property" \ - "- if controller library is the full path name:\n" \ - " - if path is not in the PoolPath, an exception is thrown" \ - " - if file exists it is overwritten otherwise a new file " \ + [[PyTango.DevVarStringArray, ", [, =True]\n" + "- if controller library is a simple module name:\n" + " - if it exists, it is overwritten, otherwise a new python " + "file is created in the directory of the first element in " + "the PoolPath property" + "- if controller library is the full path name:\n" + " - if path is not in the PoolPath, an exception is thrown" + " - if file exists it is overwritten otherwise a new file " "is created"], - [PyTango.DevVoid, "" ]], + [PyTango.DevVoid, ""]], 'Stop': [[PyTango.DevVoid, STOP_PAR_IN_DOC], [PyTango.DevVoid, STOP_PAR_OUT_DOC]], @@ -1396,114 +1404,113 @@ class PoolClass(PyTango.DeviceClass): [PyTango.DevVoid, ""]], } - # Attribute definitions attr_list = { 'InstrumentList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Motor list", - 'description':"the list of instruments (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Motor list", + 'description': "the list of instruments (a JSON encoded dict)", + }], 'ControllerList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Controller list", - 'description':"the list of controllers (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Controller list", + 'description': "the list of controllers (a JSON encoded dict)", + }], 'ExpChannelList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Experiment channel list", - 'description':"The list of experiment channels (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Experiment channel list", + 'description': "The list of experiment channels (a JSON encoded dict)", + }], 'AcqChannelList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Acquisition channel list", - 'description':"The list of all acquisition channels (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Acquisition channel list", + 'description': "The list of all acquisition channels (a JSON encoded dict)", + }], 'MotorGroupList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Motor group list", - 'description':"the list of motor groups (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Motor group list", + 'description': "the list of motor groups (a JSON encoded dict)", + }], 'ControllerLibList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Controller library list", - 'description':"the list of controller libraries (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Controller library list", + 'description': "the list of controller libraries (a JSON encoded dict)", + }], 'ControllerClassList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Controller class list", - 'description':"the list of controller classes (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Controller class list", + 'description': "the list of controller classes (a JSON encoded dict)", + }], 'MotorList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Motor list", - 'description':"the list of motors (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Motor list", + 'description': "the list of motors (a JSON encoded dict)", + }], 'TriggerGateList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"TriggerGate list", - 'description':"the list of trigger/gates (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "TriggerGate list", + 'description': "the list of trigger/gates (a JSON encoded dict)", + }], 'MeasurementGroupList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Measurement group list", - 'description':"the list of measurement groups (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Measurement group list", + 'description': "the list of measurement groups (a JSON encoded dict)", + }], 'IORegisterList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"IORegister list", - 'description':"the list of IORegisters (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "IORegister list", + 'description': "the list of IORegisters (a JSON encoded dict)", + }], 'ComChannelList': [[PyTango.DevString, - PyTango.SPECTRUM, - PyTango.READ, 4096], - { - 'label':"Communication channel list", - 'description':"the list of communication channels (a JSON encoded dict)", - } ], + PyTango.SPECTRUM, + PyTango.READ, 4096], + { + 'label': "Communication channel list", + 'description': "the list of communication channels (a JSON encoded dict)", + }], 'Elements': [[PyTango.DevEncoded, - PyTango.SCALAR, - PyTango.READ], - { - 'label':"Elements", - 'description':"the list of all elements (a JSON encoded dict)", - } ], - } + PyTango.SCALAR, + PyTango.READ], + { + 'label': "Elements", + 'description': "the list of all elements (a JSON encoded dict)", + }], + } def __init__(self, name): PyTango.DeviceClass.__init__(self, name) diff --git a/src/sardana/tango/pool/PoolDevice.py b/src/sardana/tango/pool/PoolDevice.py index 76d09b7316..81fde1806f 100644 --- a/src/sardana/tango/pool/PoolDevice.py +++ b/src/sardana/tango/pool/PoolDevice.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -65,7 +65,7 @@ def __init__(self, dclass, name): def init(self, name): """initialize the device once in the object lifetime. Override when necessary but **always** call the method from your super class - + :param str name: device name""" SardanaDevice.init(self, name) util = Util.instance() @@ -84,19 +84,20 @@ def pool(self): def get_element(self): """Returns the underlying pool element object - + :return: the underlying pool element object :rtype: :class:`~sardana.pool.poolelement.PoolElement`""" return self._element def set_element(self, element): """Associates this device with the sardana element - + :param element: the sardana element :type element: :class:`~sardana.pool.poolelement.PoolElement`""" self._element = element - element = property(get_element, set_element, doc="The underlying sardana element") + element = property(get_element, set_element, + doc="The underlying sardana element") def init_device(self): """Initialize the device. Called during startup after :meth:`init` and @@ -122,7 +123,7 @@ def Abort(self): def is_Abort_allowed(self): """Returns True if it is allowed to execute the tango abort command - + :return: True if it is allowed to execute the tango abort command or False otherwise :rtype: bool""" @@ -138,7 +139,7 @@ def Stop(self): def is_Stop_allowed(self): """Returns True if it is allowed to execute the tango stop command - + :return: True if it is allowed to execute the tango stop command or False otherwise :rtype: bool""" @@ -157,20 +158,20 @@ def _is_allowed(self, req_type): def get_dynamic_attributes(self): """Returns the standard dynamic and fully dynamic attributes for this device. The return is a tuple of two dictionaries: - + - standard attributes: caseless dictionary with key being the attribute name and value is a tuple of attribute name(str), tango information, attribute information - dynamic attributes: caseless dictionary with key being the attribute name and value is a tuple of attribute name(str), tango information, attribute information - + **tango information** seq< :class:`~PyTango.CmdArgType`, :class:`~PyTango.AttrDataFormat`, :class:`~PyTango.AttrWriteType` > - + **attribute information** attribute information as returned by the sardana controller - + :return: the standard dynamic and fully dynamic attributes :rtype: seq< :class:`~taurus.core.util.CaselessDict`, :class:`~taurus.core.util.CaselessDict`\> """ @@ -258,8 +259,8 @@ def remove_unwanted_dynamic_attributes(self, new_std_attrs, new_dyn_attrs): new_attr = new_attrs[attr_name] new_type, new_format, new_access = new_attr[1][0][:3] differ = new_type != old_type or \ - new_format != old_format or \ - new_access != old_access + new_format != old_format or \ + new_access != old_access if differ: self.info("Replacing dynamic attribute %s", attr_name) self.debug("old type: %s, new type: %s", @@ -271,14 +272,14 @@ def remove_unwanted_dynamic_attributes(self, new_std_attrs, new_dyn_attrs): multi_class_attr.remove_attr(attr.get_name(), attr.get_cl_name()) except: - self.warning("Error removing dynamic attribute %s from "\ + self.warning("Error removing dynamic attribute %s from " " device class", attr_name) self.debug("Details:", exc_info=1) def add_dynamic_attribute(self, attr_name, data_info, attr_info, read, write, is_allowed): """Adds a single dynamic attribute - + :param str attr_name: the attribute name :param data_info: tango attribute information :type data_info: seq< :class:`~PyTango.CmdArgType`, :class:`~PyTango.AttrDataFormat`, :class:`~PyTango.AttrWriteType` > @@ -315,7 +316,7 @@ def add_dynamic_attribute(self, attr_name, data_info, attr_info, read, def add_standard_attribute(self, attr_name, data_info, attr_info, read, write, is_allowed): """Adds a single standard dynamic attribute - + :param str attr_name: the attribute name :param data_info: tango attribute information :type data_info: seq< :class:`~PyTango.CmdArgType`, :class:`~PyTango.AttrDataFormat`, :class:`~PyTango.AttrWriteType` > @@ -331,27 +332,27 @@ def add_standard_attribute(self, attr_name, data_info, attr_info, read, def read_DynamicAttribute(self, attr): """Generic read dynamic attribute. Default implementation raises :exc:`NotImplementedError` - + :param attr: attribute to be read :type attr: :class:`~PyTango.Attribute` - + :raises: :exc:`NotImplementedError`""" raise NotImplementedError def write_DynamicAttribute(self, attr): """Generic write dynamic attribute. Default implementation raises :exc:`NotImplementedError` - + :param attr: attribute to be written :type attr: :class:`~PyTango.Attribute` - + :raises: :exc:`NotImplementedError`""" raise NotImplementedError def is_DynamicAttribute_allowed(self, req_type): """Generic is dynamic attribute allowed. Default implementation calls :meth:`_is_allowed` - + :param req_type: request type :type attr: :class:`~PyTango.AttrRequestType`""" return self._is_allowed(req_type) @@ -360,7 +361,7 @@ def _read_DynamicAttribute(self, attr): """Generic internal read dynamic attribute. Checks if this object has a 'read_'+ method and calls it. If not calls :meth:`read_DynamicAttribute`. - + :param attr: attribute to be read :type attr: :class:`~PyTango.Attribute`""" name = attr.get_name() @@ -376,7 +377,7 @@ def _write_DynamicAttribute(self, attr): """Generic internal write dynamic attribute. Checks if this object has a 'write_'+ method and calls it. If not calls :meth:`write_DynamicAttribute`. - + :param attr: attribute to be written :type attr: :class:`~PyTango.Attribute`""" name = attr.get_name() @@ -389,7 +390,7 @@ def _write_DynamicAttribute(self, attr): def _is_DynamicAttribute_allowed(self, req_type): """Generic is dynamic attribute allowed. Default implementation calls :meth:`is_DynamicAttribute_allowed` - + :param req_type: request type :type attr: :class:`~PyTango.AttrRequestType`""" return self.is_DynamicAttribute_allowed(req_type) @@ -397,7 +398,7 @@ def _is_DynamicAttribute_allowed(self, req_type): def dev_state(self): """Calculates and returns the device state. Called by Tango on a read state request. - + :return: the device state :rtype: :class:`~PyTango.DevState`""" element = self.element @@ -414,7 +415,7 @@ def dev_state(self): def dev_status(self): """Calculates and returns the device status. Called by Tango on a read status request. - + :return: the device status :rtype: str""" element = self.element @@ -432,7 +433,7 @@ def dev_status(self): def wait_for_operation(self): """Waits for an operation to finish. It uses the maxumum number of retries. Sleeps 0.01s between retries. - + :raises: :exc:`Exception` in case of a timeout""" element, n = self.element, self.BusyRetries while element.is_in_operation(): @@ -505,7 +506,6 @@ def restore_attribute(self, attribute, write_meth, db_value): self.debug("Details:", exc_info=1) - class PoolDeviceClass(SardanaDeviceClass): """Base Tango Pool Device Class class""" @@ -522,10 +522,10 @@ class PoolDeviceClass(SardanaDeviceClass): #: .. seealso:: :ref:`server` #: device_property_list = { - 'Id' : [DevLong64, "Internal ID", InvalidId ], - 'Force_HW_Read' : [DevBoolean, "Force a hardware read of value even " - "when in operation (motion/acquisition", - False], + 'Id': [DevLong64, "Internal ID", InvalidId], + 'Force_HW_Read': [DevBoolean, "Force a hardware read of value even " + "when in operation (motion/acquisition", + False], } device_property_list.update(SardanaDeviceClass.device_property_list) @@ -535,9 +535,9 @@ class PoolDeviceClass(SardanaDeviceClass): #: .. seealso:: :ref:`server` #: cmd_list = { - 'Stop' : [ [DevVoid, ""], [DevVoid, ""] ], - 'Abort' : [ [DevVoid, ""], [DevVoid, ""] ], - 'Restore' : [ [DevVoid, ""], [DevVoid, ""] ], + 'Stop': [[DevVoid, ""], [DevVoid, ""]], + 'Abort': [[DevVoid, ""], [DevVoid, ""]], + 'Restore': [[DevVoid, ""], [DevVoid, ""]], } cmd_list.update(SardanaDeviceClass.cmd_list) @@ -590,7 +590,7 @@ def read_Instrument(self, attr): """Read the value of the ``Instrument`` tango attribute. Returns the instrument full name or empty string if this element doesn't belong to any instrument - + :param attr: tango instrument attribute :type attr: :class:`~PyTango.Attribute`""" instrument = self.element.instrument @@ -604,7 +604,7 @@ def write_Instrument(self, attr): Sets a new instrument full name or empty string if this element doesn't belong to any instrument. The instrument **must** have been previously created. - + :param attr: tango instrument attribute :type attr: :class:`~PyTango.Attribute`""" name = attr.get_write_value() @@ -615,26 +615,27 @@ def write_Instrument(self, attr): raise Exception("%s is not an instrument" % name) self.element.instrument = instrument db = Util.instance().get_database() - db.put_device_property(self.get_name(), { "Instrument_id" : instrument.id }) + db.put_device_property( + self.get_name(), {"Instrument_id": instrument.id}) def get_dynamic_attributes(self): """Override of :class:`PoolDevice.get_dynamic_attributes`. Returns the standard dynamic and fully dynamic attributes for this device. The return is a tuple of two dictionaries: - + - standard attributes: caseless dictionary with key being the attribute name and value is a tuple of attribute name(str), tango information, attribute information - dynamic attributes: caseless dictionary with key being the attribute name and value is a tuple of attribute name(str), tango information, attribute information - + **tango information** seq< :class:`~PyTango.CmdArgType`, :class:`~PyTango.AttrDataFormat`, :class:`~PyTango.AttrWriteType` > - + **attribute information** attribute information as returned by the sardana controller - + :return: the standard dynamic and fully dynamic attributes :rtype: seq< :class:`~taurus.core.util.CaselessDict`, :class:`~taurus.core.util.CaselessDict`\> """ @@ -654,7 +655,8 @@ def get_dynamic_attributes(self): dev_class = self.get_device_class() axis_attrs = ctrl.get_axis_attributes(self.element.axis) - std_attrs_lower = [ attr.lower() for attr in dev_class.standard_attr_list ] + std_attrs_lower = [attr.lower() + for attr in dev_class.standard_attr_list] for attr_name, attr_info in axis_attrs.items(): attr_name_lower = attr_name.lower() if attr_name_lower in std_attrs_lower: @@ -670,7 +672,7 @@ def get_dynamic_attributes(self): def read_DynamicAttribute(self, attr): """Read a generic dynamic attribute. Calls the controller of this element to get the dynamic attribute value - + :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" name = attr.get_name() @@ -679,13 +681,14 @@ def read_DynamicAttribute(self, attr): raise Exception("Cannot read %s. Controller not build!" % name) v = ctrl.get_axis_attr(self.element.axis, name) if v is None: - raise TypeError("Cannot read %s. Controller returns None" % (name,)) + raise TypeError( + "Cannot read %s. Controller returns None" % (name,)) attr.set_value(v) def write_DynamicAttribute(self, attr): """Write a generic dynamic attribute. Calls the controller of this element to get the dynamic attribute value - + :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" name = attr.get_name() @@ -698,14 +701,14 @@ def write_DynamicAttribute(self, attr): def read_SimulationMode(self, attr): """Read the current simulation mode. - + :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" attr.set_value(self.element.simulation_mode) def write_SimulationMode(self, attr): """Sets the simulation mode. - + :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" self.element.simulation_mode = attr.get_write_value() @@ -720,9 +723,9 @@ class PoolElementDeviceClass(PoolDeviceClass): #: .. seealso:: :ref:`server` #: device_property_list = { - "Axis" : [ DevLong64, "Axis in the controller", [ InvalidAxis ] ], - "Ctrl_id" : [ DevLong64, "Controller ID", [ InvalidId ] ], - "Instrument_id" : [ DevLong64, "Controller ID", [ InvalidId ] ], + "Axis": [DevLong64, "Axis in the controller", [InvalidAxis]], + "Ctrl_id": [DevLong64, "Controller ID", [InvalidId]], + "Instrument_id": [DevLong64, "Controller ID", [InvalidId]], } device_property_list.update(PoolDeviceClass.device_property_list) @@ -732,11 +735,11 @@ class PoolElementDeviceClass(PoolDeviceClass): #: .. seealso:: :ref:`server` #: attr_list = { - 'Instrument' : [ [DevString, SCALAR, READ_WRITE], - { 'label' : "Instrument", - 'Display level' : DispLevel.EXPERT } ], - 'SimulationMode': [ [DevBoolean, SCALAR, READ_WRITE], - { 'label' : "Simulation mode" } ], + 'Instrument': [[DevString, SCALAR, READ_WRITE], + {'label': "Instrument", + 'Display level': DispLevel.EXPERT}], + 'SimulationMode': [[DevBoolean, SCALAR, READ_WRITE], + {'label': "Simulation mode"}], } attr_list.update(PoolDeviceClass.attr_list) @@ -746,7 +749,7 @@ class PoolElementDeviceClass(PoolDeviceClass): def get_standard_attr_info(self, attr): """Returns information about the standard attribute - + :param str attr: attribute name :return: a sequence of tango data_type, data format""" return self.standard_attr_list[attr] @@ -763,17 +766,17 @@ class PoolGroupDevice(PoolDevice): def read_ElementList(self, attr): """Read the element list. - + :param attr: tango attribute :type attr: :class:`~PyTango.Attribute`""" attr.set_value(self.get_element_names()) def get_element_names(self): """Returns the list of element names. - + :return: a list of attribute names""" elements = self.element.get_user_elements() - return [ element.name for element in elements ] + return [element.name for element in elements] def elements_changed(self, evt_src, evt_type, evt_value): """Callback for when the elements of this group changed""" @@ -789,7 +792,7 @@ class PoolGroupDeviceClass(PoolDeviceClass): #: .. seealso:: :ref:`server` #: device_property_list = { - "Elements" : [ DevVarStringArray, "elements in the group", [ ] ], + "Elements": [DevVarStringArray, "elements in the group", []], } device_property_list.update(PoolDeviceClass.device_property_list) @@ -808,7 +811,7 @@ class PoolGroupDeviceClass(PoolDeviceClass): #: .. seealso:: :ref:`server` #: attr_list = { - 'ElementList' : [ [ DevString, SPECTRUM, READ, 4096] ], + 'ElementList': [[DevString, SPECTRUM, READ, 4096]], } attr_list.update(PoolDeviceClass.attr_list) diff --git a/src/sardana/tango/pool/PseudoCounter.py b/src/sardana/tango/pool/PseudoCounter.py index 94b7070960..7256c38017 100644 --- a/src/sardana/tango/pool/PseudoCounter.py +++ b/src/sardana/tango/pool/PseudoCounter.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -82,8 +82,8 @@ def init_device(self): name = self.alias or full_name self.pseudo_counter = pseudo_counter = \ self.pool.create_element(type="PseudoCounter", name=name, - full_name=full_name, id=self.Id, axis=self.Axis, - ctrl_id=self.Ctrl_id, user_elements=self.Elements) + full_name=full_name, id=self.Id, axis=self.Axis, + ctrl_id=self.Ctrl_id, user_elements=self.Elements) if self.instrument is not None: pseudo_counter.set_instrument(self.instrument) pseudo_counter.add_listener(self.on_pseudo_counter_changed) @@ -234,20 +234,20 @@ class PseudoCounterClass(PoolElementDeviceClass): # Device Properties device_property_list = { - "Elements" : [ DevVarStringArray, "elements used by the pseudo", [ ] ], + "Elements": [DevVarStringArray, "elements used by the pseudo", []], } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { - 'CalcPseudo' : [ [DevVarDoubleArray, "physical values"], [DevDouble, "pseudo counter"] ], - 'CalcAllPseudo' : [ [DevVarDoubleArray, "physical positions"], [DevVarDoubleArray, "pseudo counter values"] ], + 'CalcPseudo': [[DevVarDoubleArray, "physical values"], [DevDouble, "pseudo counter"]], + 'CalcAllPseudo': [[DevVarDoubleArray, "physical positions"], [DevVarDoubleArray, "pseudo counter values"]], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions standard_attr_list = { - 'Value' : [ [ DevDouble, SCALAR, READ ] ], + 'Value': [[DevDouble, SCALAR, READ]], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) diff --git a/src/sardana/tango/pool/PseudoMotor.py b/src/sardana/tango/pool/PseudoMotor.py index 1b6e472f0d..e3363e0526 100644 --- a/src/sardana/tango/pool/PseudoMotor.py +++ b/src/sardana/tango/pool/PseudoMotor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -85,8 +85,8 @@ def init_device(self): name = self.alias or full_name self.pseudo_motor = pseudo_motor = \ self.pool.create_element(type="PseudoMotor", name=name, - full_name=full_name, id=self.Id, axis=self.Axis, - ctrl_id=self.Ctrl_id, user_elements=self.Elements) + full_name=full_name, id=self.Id, axis=self.Axis, + ctrl_id=self.Ctrl_id, user_elements=self.Elements) if self.instrument is not None: pseudo_motor.set_instrument(self.instrument) pseudo_motor.set_drift_correction(self.DriftCorrection) @@ -218,7 +218,8 @@ def CalcPseudo(self, physical_positions): """Returns the pseudo motor position for the given physical positions""" if not len(physical_positions): physical_positions = None - result = self.pseudo_motor.calc_pseudo(physical_positions=physical_positions) + result = self.pseudo_motor.calc_pseudo( + physical_positions=physical_positions) if result.error: throw_sardana_exception(result) return result.value @@ -267,30 +268,30 @@ class PseudoMotorClass(PoolElementDeviceClass): # Device Properties device_property_list = { - "Elements" : [ DevVarStringArray, "elements used by the pseudo", [ ] ], + "Elements": [DevVarStringArray, "elements used by the pseudo", []], 'DriftCorrection': [DevBoolean, - "Locally apply drift correction on pseudo motors. Default is the " - "current global drift correction in the Pool Device", - None], + "Locally apply drift correction on pseudo motors. Default is the " + "current global drift correction in the Pool Device", + None], } device_property_list.update(PoolElementDeviceClass.device_property_list) # Command definitions cmd_list = { - 'CalcPseudo' : [ [DevVarDoubleArray, "physical positions"], [DevDouble, "pseudo position"] ], - 'CalcPhysical' : [ [DevDouble, "pseudo position"], [DevVarDoubleArray, "physical positions"] ], - 'CalcAllPseudo' : [ [DevVarDoubleArray, "physical positions"], [DevVarDoubleArray, "pseudo positions"] ], - 'CalcAllPhysical' : [ [DevVarDoubleArray, "pseudo positions"], [DevVarDoubleArray, "physical positions"] ], - 'MoveRelative' : [ [DevDouble, "amount to move"], [DevVoid, ""] ], + 'CalcPseudo': [[DevVarDoubleArray, "physical positions"], [DevDouble, "pseudo position"]], + 'CalcPhysical': [[DevDouble, "pseudo position"], [DevVarDoubleArray, "physical positions"]], + 'CalcAllPseudo': [[DevVarDoubleArray, "physical positions"], [DevVarDoubleArray, "pseudo positions"]], + 'CalcAllPhysical': [[DevVarDoubleArray, "pseudo positions"], [DevVarDoubleArray, "physical positions"]], + 'MoveRelative': [[DevDouble, "amount to move"], [DevVoid, ""]], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions standard_attr_list = { - 'Position' : [ [ DevDouble, SCALAR, READ_WRITE ], - { 'label' : "Position", - 'abs_change' : '1.0', }, ], + 'Position': [[DevDouble, SCALAR, READ_WRITE], + {'label': "Position", + 'abs_change': '1.0', }, ], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) diff --git a/src/sardana/tango/pool/TriggerGate.py b/src/sardana/tango/pool/TriggerGate.py index bdf1ac5403..c3c2d79bc1 100644 --- a/src/sardana/tango/pool/TriggerGate.py +++ b/src/sardana/tango/pool/TriggerGate.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -51,7 +51,6 @@ class TriggerGate(PoolElementDevice): def __init__(self, dclass, name): PoolElementDevice.__init__(self, dclass, name) - def init(self, name): PoolElementDevice.init(self, name) @@ -83,12 +82,12 @@ def init_device(self): name = self.alias or full_name self.tg = tg = \ self.pool.create_element(type="TriggerGate", - name=name, full_name=full_name, id=self.Id, axis=self.Axis, - ctrl_id=self.Ctrl_id) + name=name, full_name=full_name, id=self.Id, axis=self.Axis, + ctrl_id=self.Ctrl_id) tg.add_listener(self.on_tg_changed) self.set_state(DevState.ON) - + def on_tg_changed(self, event_source, event_type, event_value): try: self._on_tg_changed(event_source, event_type, event_value) @@ -135,8 +134,9 @@ def _on_tg_changed(self, event_source, event_type, event_value): timestamp=timestamp, quality=quality, priority=priority, error=error, synch=False) + class TriggerGateClass(PoolElementDeviceClass): - + def _get_class_properties(self): ret = PoolElementDeviceClass._get_class_properties(self) ret['Description'] = "Trigger/Gate device class" diff --git a/src/sardana/tango/pool/TwoDExpChannel.py b/src/sardana/tango/pool/TwoDExpChannel.py index ecb4f39eda..6f74dba2f0 100644 --- a/src/sardana/tango/pool/TwoDExpChannel.py +++ b/src/sardana/tango/pool/TwoDExpChannel.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -78,13 +78,13 @@ def init_device(self): name = self.alias or full_name self.twod = twod = \ self.pool.create_element(type="TwoDExpChannel", - name=name, full_name=full_name, id=self.Id, axis=self.Axis, - ctrl_id=self.Ctrl_id) + name=name, full_name=full_name, id=self.Id, axis=self.Axis, + ctrl_id=self.Ctrl_id) if self.instrument is not None: twod.set_instrument(self.instrument) twod.add_listener(self.on_twod_changed) - ## force a state read to initialize the state attribute + # force a state read to initialize the state attribute #state = ct.state self.set_state(DevState.ON) @@ -204,7 +204,9 @@ def Start(self): _DFT_VALUE_INFO = TwoDController.standard_axis_attributes['Value'] _DFT_VALUE_MAX_SHAPE = _DFT_VALUE_INFO[MaxDimSize] -_DFT_VALUE_TYPE, _DFT_VALUE_FORMAT = to_tango_type_format(_DFT_VALUE_INFO[Type], DataFormat.TwoD) +_DFT_VALUE_TYPE, _DFT_VALUE_FORMAT = to_tango_type_format( + _DFT_VALUE_INFO[Type], DataFormat.TwoD) + class TwoDExpChannelClass(PoolElementDeviceClass): @@ -219,20 +221,20 @@ class TwoDExpChannelClass(PoolElementDeviceClass): # Command definitions cmd_list = { - 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], + 'Start': [[DevVoid, ""], [DevVoid, ""]], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions attr_list = { - 'DataSource' : [ [ DevString, SCALAR, READ ] ], + 'DataSource': [[DevString, SCALAR, READ]], } attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { - 'Value' : [ [ _DFT_VALUE_TYPE, _DFT_VALUE_FORMAT, READ, - _DFT_VALUE_MAX_SHAPE[0], _DFT_VALUE_MAX_SHAPE[1] ], - { 'abs_change' : '1.0', } ], + 'Value': [[_DFT_VALUE_TYPE, _DFT_VALUE_FORMAT, READ, + _DFT_VALUE_MAX_SHAPE[0], _DFT_VALUE_MAX_SHAPE[1]], + {'abs_change': '1.0', }], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) diff --git a/src/sardana/tango/pool/ZeroDExpChannel.py b/src/sardana/tango/pool/ZeroDExpChannel.py index 674d2bf60b..f486d0f584 100644 --- a/src/sardana/tango/pool/ZeroDExpChannel.py +++ b/src/sardana/tango/pool/ZeroDExpChannel.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -79,11 +79,11 @@ def init_device(self): name = self.alias or full_name self.zerod = zerod = \ self.pool.create_element(type="ZeroDExpChannel", name=name, - full_name=full_name, id=self.Id, axis=self.Axis, - ctrl_id=self.Ctrl_id) + full_name=full_name, id=self.Id, axis=self.Axis, + ctrl_id=self.Ctrl_id) zerod.add_listener(self.on_zerod_changed) - ## force a state read to initialize the state attribute + # force a state read to initialize the state attribute #state = zerod.state self.set_state(DevState.ON) @@ -168,7 +168,8 @@ def read_Value(self, attr): quality = None if self.get_state() == State.Moving: quality = AttrQuality.ATTR_CHANGING - self.set_attribute(attr, value=value.value, quality=quality, priority=0) + self.set_attribute(attr, value=value.value, + quality=quality, priority=0) def read_CurrentValue(self, attr): zerod = self.zerod @@ -210,7 +211,8 @@ def _is_allowed(self, req_type): _DFT_VALUE_INFO = ZeroDController.standard_axis_attributes['Value'] -_DFT_VALUE_TYPE, _DFT_VALUE_FORMAT = to_tango_type_format(_DFT_VALUE_INFO[Type], DataFormat.Scalar) +_DFT_VALUE_TYPE, _DFT_VALUE_FORMAT = to_tango_type_format( + _DFT_VALUE_INFO[Type], DataFormat.Scalar) class ZeroDExpChannelClass(PoolElementDeviceClass): @@ -226,24 +228,24 @@ class ZeroDExpChannelClass(PoolElementDeviceClass): # Command definitions cmd_list = { - 'Start' : [ [DevVoid, ""], [DevVoid, ""] ], + 'Start': [[DevVoid, ""], [DevVoid, ""]], } cmd_list.update(PoolElementDeviceClass.cmd_list) # Attribute definitions attr_list = { - 'ValueBuffer' : [ [ DevDouble, SPECTRUM, READ, 16 * 1024 ] ], - 'TimeBuffer' : [ [ DevDouble, SPECTRUM, READ, 16 * 1024 ] ], - 'AccumulationType' : [ [ DevString, SCALAR, READ_WRITE ], - { 'Memorized' : "true", - 'label' : "Accumulation Type", - 'Display level' : DispLevel.EXPERT } ], + 'ValueBuffer': [[DevDouble, SPECTRUM, READ, 16 * 1024]], + 'TimeBuffer': [[DevDouble, SPECTRUM, READ, 16 * 1024]], + 'AccumulationType': [[DevString, SCALAR, READ_WRITE], + {'Memorized': "true", + 'label': "Accumulation Type", + 'Display level': DispLevel.EXPERT}], } attr_list.update(PoolElementDeviceClass.attr_list) standard_attr_list = { - 'Value' : [ [ _DFT_VALUE_TYPE, SCALAR, READ, ], - { 'abs_change' : '1.0', } ], + 'Value': [[_DFT_VALUE_TYPE, SCALAR, READ, ], + {'abs_change': '1.0', }], } standard_attr_list.update(PoolElementDeviceClass.standard_attr_list) diff --git a/src/sardana/tango/pool/__init__.py b/src/sardana/tango/pool/__init__.py index 147173e9b2..9b6e79edd5 100644 --- a/src/sardana/tango/pool/__init__.py +++ b/src/sardana/tango/pool/__init__.py @@ -3,24 +3,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -30,6 +30,7 @@ SERVER_NAME = "Pool" + def prepare_pool(util): import PyTango @@ -55,7 +56,8 @@ def translate(self, value): if not isinstance(value, PyTango.DeviceAttribute): return super(TangoControllerValueTranslator, self).translate(value) if value.type != PyTango.DevState: - raise CannotTranslateException("Expected DevState got %s" % value.type) + raise CannotTranslateException( + "Expected DevState got %s" % value.type) ret = from_deviceattribute(value) return ret @@ -89,6 +91,7 @@ def translate(self, value): util.add_class(MotorGroupClass, MotorGroup) util.add_class(MeasurementGroupClass, MeasurementGroup) + def main_pool(args=None, start_time=None, mode=None): import sardana.tango.core.util # pass server name so the scripts generated with setuptools work on Windows @@ -98,7 +101,7 @@ def main_pool(args=None, start_time=None, mode=None): run = main_pool + def main(): import datetime run(start_time=datetime.datetime.now()) - diff --git a/src/sardana/tango/pool/test/__init__.py b/src/sardana/tango/pool/test/__init__.py index 74102f7501..25b3ca6527 100644 --- a/src/sardana/tango/pool/test/__init__.py +++ b/src/sardana/tango/pool/test/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/tango/pool/test/base.py b/src/sardana/tango/pool/test/base.py index 62f2fa2575..acf2971d74 100644 --- a/src/sardana/tango/pool/test/base.py +++ b/src/sardana/tango/pool/test/base.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -57,7 +57,8 @@ def setUp(self): dev_name_parts = self.pool_name.split('/') prefix = '/'.join(dev_name_parts[0:2]) start_from = int(dev_name_parts[2]) - self.pool_name = get_free_device(PyTango.Database(), prefix, start_from) + self.pool_name = get_free_device( + PyTango.Database(), prefix, start_from) self._starter.addNewDevice(self.pool_name, klass='Pool') # start Pool server self._starter.startDs() @@ -79,6 +80,7 @@ class ControllerLoadsTestCase(BasePoolTestCase): """Class for loading an arbitrary Sardana controller library and class. """ controller_classes = [] + def test_controller_loads(self): """Test that the controller library and class can be loaded. """ @@ -105,7 +107,7 @@ class ControllerCreationTestCase(BasePoolTestCase): def test_controller_creation(self): """Test that the controller has been created with the correct name. """ - for cls, name, props in self.controller_infos: + for cls, name, props in self.controller_infos: ctrl = self.pool.createController(cls, name, *props) msg = 'Controller %s was not correctly created.' % name self.assertEqual(ctrl.getName(), name, msg) @@ -124,7 +126,7 @@ class ElementCreationTestCase(BasePoolTestCase): def test_element_creation(self): """Test that controller and elements have been correctly created. """ - for cls, name, props, elements in self.controller_infos: + for cls, name, props, elements in self.controller_infos: ctrl = self.pool.createController(cls, name, *props) msg = 'Controller %s was not correctly created.' % name self.assertEqual(ctrl.getName(), name, msg) @@ -150,24 +152,24 @@ class BuiltinControllerLoadsTest(ControllerLoadsTestCase, unittest.TestCase): controller_classes = { - 'DummyMotorController':('DummyMotorController',) + 'DummyMotorController': ('DummyMotorController',) } class BuiltinControllerCreationTest(ControllerCreationTestCase, - unittest.TestCase): + unittest.TestCase): controller_infos = [('DummyMotorController', 'unittest', ()) - ] + ] class BuiltinElementCreationTest(ElementCreationTestCase, unittest.TestCase): alias = get_free_alias(PyTango.Database(), "mot_test") controller_infos = [('DummyMotorController', - 'unittest', - (), - [(alias, 1)]) - ] + 'unittest', + (), + [(alias, 1)]) + ] suite = unittest.defaultTestLoader.loadTestsFromTestCase( - BuiltinElementCreationTest) + BuiltinElementCreationTest) unittest.TextTestRunner(descriptions=True, verbosity=2).run(suite) diff --git a/src/sardana/tango/pool/test/base_sartest.py b/src/sardana/tango/pool/test/base_sartest.py index 98669636a2..3e27db008d 100644 --- a/src/sardana/tango/pool/test/base_sartest.py +++ b/src/sardana/tango/pool/test/base_sartest.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -29,6 +29,7 @@ __all__ = ['SarTestTestCase'] + class SarTestTestCase(BasePoolTestCase): """ Base class to setup sardana test environment. It creates the controllers defined in cls_list @@ -42,16 +43,19 @@ class SarTestTestCase(BasePoolTestCase): - The ctrl_name will be prefix + _ctrl_ + postfix. - The elem_name will be prefix + _ + postfix + _ + axis """ - #TODO: Formating PEP8 + # TODO: Formating PEP8 cls_list = [ - ('Motor', 'DummyMotorController', 'DummyMotorController', '_test_mt','1', 5), - ('CTExpChannel', 'DummyCounterTimerController', 'DummyCounterTimerController', '_test_ct', '1', 5), - ('CTExpChannel', 'DummyCounterTimerController', 'DummyCounterTimerController', '_test_ct', '2', 5), - ('TriggerGate', 'DummyTriggerGateController', 'DummyTriggerGateController', '_test_tg', '1', 5), - ('TriggerGate', 'DummyTriggerGateController', 'DummyTriggerGateController', '_test_tg', '2', 5) + ('Motor', 'DummyMotorController', 'DummyMotorController', '_test_mt', '1', 5), + ('CTExpChannel', 'DummyCounterTimerController', + 'DummyCounterTimerController', '_test_ct', '1', 5), + ('CTExpChannel', 'DummyCounterTimerController', + 'DummyCounterTimerController', '_test_ct', '2', 5), + ('TriggerGate', 'DummyTriggerGateController', + 'DummyTriggerGateController', '_test_tg', '1', 5), + ('TriggerGate', 'DummyTriggerGateController', + 'DummyTriggerGateController', '_test_tg', '2', 5) ] - def setUp(self): BasePoolTestCase.setUp(self) @@ -69,13 +73,15 @@ def setUp(self): raise Exception('Aborting SartestTesCase: %s' % (msg)) self.ctrl_list.append(ctrl_name) # Create 5 elemens - for axis in range(1,nelem+1): + for axis in range(1, nelem + 1): elem_name = prefix + "_" + postfix + '_%s' % (axis) try: - self.pool.createElement([sar_type, ctrl_name, str(axis), elem_name]) + self.pool.createElement( + [sar_type, ctrl_name, str(axis), elem_name]) except Exception, e: print e - msg = 'Impossible to create element: "%s"' % (elem_name) + msg = 'Impossible to create element: "%s"' % ( + elem_name) raise Exception('Aborting SartestTesCase: %s' % (msg)) self.elem_list.append(elem_name) except Exception, e: @@ -100,17 +106,17 @@ def tearDown(self): except: dirty_ctrls.append(ctrl_name) - BasePoolTestCase.tearDown(self) + BasePoolTestCase.tearDown(self) - if dirty_elems or dirty_ctrls : + if dirty_elems or dirty_ctrls: msg = "Cleanup failed. Database may be left dirty." + \ - "\n\tCtrls : %s\n\tElems : %s" % (dirty_ctrls, dirty_elems) + "\n\tCtrls : %s\n\tElems : %s" % (dirty_ctrls, dirty_elems) raise Exception(msg) - + if __name__ == "__main__": - stc = SarTestTestCase() - stc.setUp() - import time - time.sleep(15) - stc.tearDown() + stc = SarTestTestCase() + stc.setUp() + import time + time.sleep(15) + stc.tearDown() diff --git a/src/sardana/tango/pool/test/test_Motor.py b/src/sardana/tango/pool/test/test_Motor.py index 57560d6796..f0578923a4 100644 --- a/src/sardana/tango/pool/test/test_Motor.py +++ b/src/sardana/tango/pool/test/test_Motor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -30,10 +30,12 @@ from sardana.tango.core.util import get_free_alias import numbers + class ReadMotorPositionOutsideLim(BasePoolTestCase, unittest.TestCase): """TestCase class for testing that read position is possible when motor is out of SW limits. Verify that position has a numeric type. """ + def setUp(self): """Create dummy motor controller and dummy motor element """ @@ -46,7 +48,7 @@ def setUp(self): self.elem_name = get_free_alias(PyTango.Database(), "mot_test") axis = 1 self.pool.CreateElement([sar_type, self.ctrl_name, str(axis), - self.elem_name]) + self.elem_name]) self.elem = PyTango.DeviceProxy(self.elem_name) self.elem.DefinePosition(0) diff --git a/src/sardana/tango/pool/test/test_measurementgroup.py b/src/sardana/tango/pool/test/test_measurementgroup.py index 15ed1b47bd..e9d3ad124c 100644 --- a/src/sardana/tango/pool/test/test_measurementgroup.py +++ b/src/sardana/tango/pool/test/test_measurementgroup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -37,6 +37,7 @@ # TODO: It will be moved from sardana.pool.test.test_acquisition import AttributeListener + class TangoAttributeListener(AttributeListener): def push_event(self, *args, **kwargs): @@ -60,20 +61,21 @@ def event_received(self, *args, **kwargs): value = _value['data'] idx = _value['index'] dev = event.device - obj_fullname = '%s:%s/%s' % (dev.get_db_host().split('.')[0], - dev.get_db_port(), - dev.name()) + obj_fullname = '%s:%s/%s' % (dev.get_db_host().split('.')[0], + dev.get_db_port(), + dev.name()) # filling the measurement records with self.data_lock: channel_data = self.data.get(obj_fullname, []) expected_idx = len(channel_data) - pad = [None] * (idx[0]-expected_idx) - channel_data.extend(pad+value) + pad = [None] * (idx[0] - expected_idx) + channel_data.extend(pad + value) self.data[obj_fullname] = channel_data except Exception, e: print e raise Exception('"data" event callback failed') + class MeasSarTestTestCase(SarTestTestCase): """ Helper class to setup the need environmet for execute """ @@ -85,7 +87,7 @@ def setUp(self): def create_meas(self, config): """ Create a meas with the given configuration """ - # creating mg + # creating mg self.expchan_names = [] self.tg_names = [] exp_dict = {} @@ -100,16 +102,16 @@ def create_meas(self, config): try: self.meas = PyTango.DeviceProxy(self.mg_name) except: - raise Exception('Could not create the MeasurementGroup: %s' %\ - (self.mg_name)) + raise Exception('Could not create the MeasurementGroup: %s' % + (self.mg_name)) - # When measurement group gets created it fills the configuration with - # the default values. Reusing read configuration in order to set test + # When measurement group gets created it fills the configuration with + # the default values. Reusing read configuration in order to set test # parameters. jcfg = self.meas.read_attribute('configuration').value cfg = json.loads(jcfg) for ctrl in cfg['controllers']: - ctrl_data = cfg['controllers'][ctrl] + ctrl_data = cfg['controllers'][ctrl] channels = ctrl_data['channels'] for chn in channels: name = channels[chn]['name'] @@ -141,11 +143,11 @@ def _add_attribute_listener(self, config): for ch_tg in ctrl: channel = ch_tg[0] dev = PyTango.DeviceProxy(channel) - ch_fullname = '%s:%s/%s' % (dev.get_db_host().split('.')[0], + ch_fullname = '%s:%s/%s' % (dev.get_db_host().split('.')[0], dev.get_db_port(), dev.name()) - event_id = dev.subscribe_event('Data', - PyTango.EventType.CHANGE_EVENT, + event_id = dev.subscribe_event('Data', + PyTango.EventType.CHANGE_EVENT, self.attr_listener) self.event_ids[dev] = event_id chn_names.append(ch_fullname) @@ -199,13 +201,14 @@ def tearDown(self): doc_6 = 'Stop of the synchronized acquisition with four channels from two'\ ' different controllers using hardware and software triggers' + @insertTest(helper_name='meas_cont_acquisition', test_method_doc=doc_1, params=params_1, config=config_1) # TODO: implement dedicated asserts/test for only software synchronized # acquisition. -# Until this TODO gets implemented we comment the test since it may +# Until this TODO gets implemented we comment the test since it may # fail (last acquisitions may not be executed - the previous one could -# still be in progress, so the shape of data will not correspond to the +# still be in progress, so the shape of data will not correspond to the # number of repetitions # @insertTest(helper_name='meas_cont_acquisition', test_method_doc=doc_2, # params=params_1, config=config_2) @@ -244,7 +247,7 @@ def _acq_asserts(self, channel_names, repetitions): for ch_name in header: ch_data_len = len(table[ch_name]) msg = 'length of data for channel %s is %d and should be %d' %\ - (ch_name, ch_data_len, repetitions) + (ch_name, ch_data_len, repetitions) self.assertEqual(ch_data_len, repetitions, msg) def meas_cont_acquisition(self, params, config): @@ -278,13 +281,13 @@ def stop_meas_cont_acquisition(self, params, config): state = self.meas.State() desired_state = PyTango.DevState.ON msg = 'mg state after stop is %s (should be %s)' %\ - (state, desired_state) + (state, desired_state) self.assertEqual(state, desired_state, msg) for name in chn_names: channel = PyTango.DeviceProxy(name) state = channel.state() msg = 'channel %s state after stop is %s (should be %s)' %\ - (name, state, desired_state) + (name, state, desired_state) self.assertEqual(state, desired_state, msg) def stopMeas(self): @@ -293,4 +296,4 @@ def stopMeas(self): def tearDown(self): unittest.TestCase.tearDown(self) - MeasSarTestTestCase.tearDown(self) \ No newline at end of file + MeasSarTestTestCase.tearDown(self) diff --git a/src/sardana/tango/pool/test/test_persistence.py b/src/sardana/tango/pool/test/test_persistence.py index 3dc02cc552..81bbbffadf 100644 --- a/src/sardana/tango/pool/test/test_persistence.py +++ b/src/sardana/tango/pool/test/test_persistence.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,13 +31,15 @@ info1 = ('Motor', 'DummyMotorController', 'DummyMotorController') info2 = ('TriggerGate', 'DummyTriggerGateController', - 'DummyTriggerGateController') -@insertTest(helper_name='check_elems_presistence', + 'DummyTriggerGateController') + + +@insertTest(helper_name='check_elems_presistence', test_method_doc='Test persistence of dummy Motor elements', - info = info1) -@insertTest(helper_name='check_elems_presistence', + info=info1) +@insertTest(helper_name='check_elems_presistence', test_method_doc='Test persistence of dummy TriggerGate elements', - info = info2) + info=info2) class PersistenceTestCase(BasePoolTestCase, unittest.TestCase): """ Test the persistence of the Sardana Tango elements. """ @@ -63,7 +65,7 @@ def check_elems_presistence(self, info): self.elem_name = get_free_alias(PyTango.Database(), base_name) axis = 1 self.pool.CreateElement([sar_type, self.ctrl_name, str(axis), - self.elem_name]) + self.elem_name]) # Restart Pool self._starter.stopDs(hard_kill=True) self._starter.startDs() @@ -75,7 +77,7 @@ def check_elems_presistence(self, info): except: obj = None msg = 'The element "%s" does not exist after restarting the Pool' %\ - (self.elem_name) + (self.elem_name) self.assertIsNotNone(obj, msg) def tearDown(self): diff --git a/src/sardana/taurus/__init__.py b/src/sardana/taurus/__init__.py index e675cd1c3c..01148f6839 100644 --- a/src/sardana/taurus/__init__.py +++ b/src/sardana/taurus/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/core/__init__.py b/src/sardana/taurus/core/__init__.py index ca50553e78..01148f6839 100644 --- a/src/sardana/taurus/core/__init__.py +++ b/src/sardana/taurus/core/__init__.py @@ -2,25 +2,25 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## -"""""" \ No newline at end of file +"""""" diff --git a/src/sardana/taurus/core/tango/__init__.py b/src/sardana/taurus/core/tango/__init__.py index ca50553e78..01148f6839 100644 --- a/src/sardana/taurus/core/tango/__init__.py +++ b/src/sardana/taurus/core/tango/__init__.py @@ -2,25 +2,25 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## -"""""" \ No newline at end of file +"""""" diff --git a/src/sardana/taurus/core/tango/sardana/__init__.py b/src/sardana/taurus/core/tango/sardana/__init__.py index ceb4a07401..b984503c11 100644 --- a/src/sardana/taurus/core/tango/sardana/__init__.py +++ b/src/sardana/taurus/core/tango/sardana/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -37,6 +37,7 @@ def registerExtensions(): pool.registerExtensions() macroserver.registerExtensions() + def unregisterExtensions(): from . import pool from . import macroserver diff --git a/src/sardana/taurus/core/tango/sardana/macro.py b/src/sardana/taurus/core/tango/sardana/macro.py index 10e44ad104..8c76f39e0c 100755 --- a/src/sardana/taurus/core/tango/sardana/macro.py +++ b/src/sardana/taurus/core/tango/sardana/macro.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -68,10 +68,12 @@ def _fromJSON(self, json_str): def _buildDoc(self): if self.hasParams(): self._parameter_line = self._buildParameterLine(self.parameters) - self._parameter_description = self._buildParameterDescription(self.parameters) + self._parameter_description = self._buildParameterDescription( + self.parameters) if self.hasResult(): self._result_line = self._buildResultLine(self.result) - self._result_description = self._buildResultDescription(self.result) + self._result_description = self._buildResultDescription( + self.result) doc = 'Syntax:\n\t%s %s' % (self.name, self.getParamStr()) if self.hasResult(): @@ -106,7 +108,7 @@ def _buildParameterLine(self, parameters): for p in parameters: t = p['type'] if type(t) in types.StringTypes: - #Simple parameter + # Simple parameter l.append('<%s>' % p['name']) else: l.append('[ %s ]' % self._buildParameterLine(t)) @@ -119,7 +121,7 @@ def _buildParameterDescription(self, parameters): for p in parameters: t = p['type'] if type(t) in types.StringTypes: - #Simple parameter + # Simple parameter l.append('{name} : ({type}) {description}'.format(**p)) else: l.extend(self._buildParameterDescription(t)) @@ -129,14 +131,14 @@ def _buildParameterDescription(self, parameters): def hasParams(self): """Determines if the macro has parameters - + :return: (bool) True if the macro has parameters or False otherwise """ - return hasattr(self , 'parameters') + return hasattr(self, 'parameters') def getParamList(self): """Returs the list of parameters - + :return: (sequence) a list of parameters """ if not self.hasParams(): @@ -145,9 +147,9 @@ def getParamList(self): def getParam(self, idx=0): """Gets the parameter for the given index - + :param idx: (int) the index (default is 0) - + :return: (object) the parameter or None if the macro does not have the desired parameter """ @@ -157,7 +159,7 @@ def getParam(self, idx=0): def getPossibleParams(self, idx, parameters=None): """Gets the possible parameters for the given index - + :param idx: (int) parameter index :param parameters: (sequence) sequence of parameter information (default is None which means use the macro parameters @@ -179,7 +181,8 @@ def getPossibleParams(self, idx, parameters=None): for i, p in enumerate(parameters): atomic = self._isParamAtomic(p) if i < idx: - if atomic: continue + if atomic: + continue else: res.extend(self.getPossibleParams(idx - i, p['type'])) elif i == idx: @@ -205,7 +208,7 @@ def getParamStr(self): def getParamDescr(self): """Returns the list of strings, each one documenting each macro parameter - + :return: (sequence) list of parameter lines """ if not self.hasParams(): @@ -214,14 +217,14 @@ def getParamDescr(self): def hasResult(self): """Determines if the macro has a result - + :return: (bool) True if the macro has a result or False otherwise """ - return hasattr(self , 'result') + return hasattr(self, 'result') def getResultList(self): """Returns the list of results - + :return: (sequence) a list of results """ if not self.hasResult(): @@ -230,9 +233,9 @@ def getResultList(self): def getResult(self, idx=0): """Gets the result for the given index - + :param idx: (int) the index (default is 0) - + :return: (object) the result or None if the macro does not have the desired result """ @@ -251,7 +254,7 @@ def getResultStr(self): def getResultDescr(self): """Returns the list of strings, each one documenting each macro result - + :return: (sequence) list of result lines """ if not self.hasResult(): @@ -289,6 +292,7 @@ def formatResult(self, res): def __str__(self): return self.name + class Macro(object): Ready = PyTango.DevState.ON @@ -332,16 +336,16 @@ class BaseNode(object): relationship between sequence, macros and parameters.""" def __init__(self, parent=None): -# if parent: -# parent = weakref.ref(parent) + # if parent: + # parent = weakref.ref(parent) self._parent = parent def parent(self): return self._parent def setParent(self, parent): -# if parent: -# parent = weakref.ref(parent) + # if parent: + # parent = weakref.ref(parent) self._parent = parent def value(self): @@ -356,6 +360,7 @@ def isAllowedMoveDown(self): def isAllowedDelete(self): return False + class BranchNode(BaseNode): """Class used to represent all types of elements which contain a list of other elements (children)""" @@ -385,7 +390,8 @@ def rowOfChild(self, child): def insertChild(self, child, row=-1): child.setParent(self) - if row == -1: row = len(self) + if row == -1: + row = len(self) self.children().insert(row, child) return row @@ -394,13 +400,15 @@ def removeChild(self, child): def upChild(self, child): i = self.children().index(child) - if i == 0: return + if i == 0: + return self.removeChild(child) self.children().insert(child, i - 1) def downChild(self, child): i = self.children().index(child) - if i == len(self) - 1: return + if i == len(self) - 1: + return self.removeChild(child) self.children().insert(i + 1, child) @@ -413,6 +421,7 @@ def toRun(self): alert += ale return values, alert + class ParamNode(BaseNode): """Base class for param elements: single parameters and param repeats. It groups a common interface of them.""" @@ -430,7 +439,6 @@ def __init__(self, parent=None, param=None): self.setMin(str(param.get('min'))) self.setMax(str(param.get('max'))) - def name(self): return self._name @@ -469,7 +477,8 @@ class SingleParamNode(ParamNode): def __init__(self, parent=None, param=None): ParamNode.__init__(self, parent, param) - if param is None: return + if param is None: + return self.setType(str(param.get('type'))) self.setDefValue(str(param.get('default_value', ''))) if self.type() == "User": @@ -550,6 +559,7 @@ def fromList(self, v): raise ValueError("Too many elements in list value") self.setValue(v) + class RepeatParamNode(ParamNode, BranchNode): """Repeat parameter class.""" @@ -607,14 +617,15 @@ def isAboveMax(self): return len(self) > self.max() def insertChild(self, child, row=-1): - #this line was removed on purpose - #in case of importing sequences from plain text, it is possible that user introduced more repetitions than allowed - #in this case later validation will inform him about exceeding a limit - #if self.isReachedMax(): return + # this line was removed on purpose + # in case of importing sequences from plain text, it is possible that user introduced more repetitions than allowed + # in this case later validation will inform him about exceeding a limit + # if self.isReachedMax(): return return BranchNode.insertChild(self, child, row) def removeChild(self, child): - if self.isReachedMin(): return + if self.isReachedMin(): + return child.setParent(None) begin = self.children().index(child) + 1 for i in range(begin, len(self)): @@ -623,7 +634,8 @@ def removeChild(self, child): def upChild(self, child): i = self.children().index(child) - if i == 0: return + if i == 0: + return child.setIndex(child.index() - 1) self.child(i - 1).setIndex(self.child(i - 1).index() + 1) BranchNode.removeChild(self, child) @@ -631,7 +643,8 @@ def upChild(self, child): def downChild(self, child): i = self.children().index(child) - if i == len(self) - 1: return + if i == len(self) - 1: + return child.setIndex(child.index() + 1) self.child(i + 1).setIndex(self.child(i + 1).index() - 1) BranchNode.removeChild(self, child) @@ -698,7 +711,8 @@ class RepeatNode(BranchNode): def __init__(self, parent=None): BranchNode.__init__(self, parent) - if parent is None: return + if parent is None: + return self.setIndex(len(self.parent()) + 1) def __repr__(self): @@ -814,9 +828,9 @@ def __init__(self, parent=None, name=None, params_def=None): def id(self): """ Getter of macro's id property - + :return: (int) - + .. seealso: :meth:`MacroNode.setId`, assignId """ @@ -825,9 +839,9 @@ def id(self): def setId(self, id): """ Setter of macro's id property - + :param id: (int) new macro's id - + See Also: id, assignId """ @@ -837,13 +851,14 @@ def assignId(self): """ If macro didn't have an assigned id it assigns it and return macro's id. - + :return: (int) - + See Also: id, setId """ id = self.id() - if id is not None: return id + if id is not None: + return id MacroNode.count += 1 self.setId(MacroNode.count) return MacroNode.count @@ -942,11 +957,14 @@ def children(self): def insertChild(self, child, row=-1): child.setParent(self) if isinstance(child, MacroNode): - if row == -1: row = len(self._hooks) - else: row = row - len(self._params) + if row == -1: + row = len(self._hooks) + else: + row = row - len(self._params) self._hooks.insert(row, child) elif isinstance(child, ParamNode): - if row == -1: row = len(self._params) + if row == -1: + row = len(self._params) self._params.insert(row, child) return self.rowOfChild(child) @@ -971,7 +989,6 @@ def toSpockCommand(self): values = map(str, values) return "%s %s" % (self.name(), str.join(' ', values)) - def value(self): values, alerts = self.toRun() if len(values) == 0: @@ -1091,14 +1108,14 @@ def moveDown(self): def toXml(self, withId=True): """ Converts MacroNode obj to etree.Element obj. - + :param withId: (bool) if we want to export also macro id (default: True) - + See Also: fromXml """ macroElement = etree.Element("macro", name=self.name()) - if withId: + if withId: id_ = self.id() if not id_ is None: macroElement.set("id", str(self.id())) @@ -1116,9 +1133,9 @@ def toXml(self, withId=True): def fromXml(self, xmlElement): """ Fills properties of MacroNode obj from etree.Element obj passed as a parameter - + :param xmlElement: (etree.Element) - + See Also: toXml """ @@ -1214,7 +1231,7 @@ def fromXml(self, sequenceElement): def fromPlainText(self, plainText): plainMacros = plainText.split('\n') for plainMacro in plainMacros: - # stripping the whitespace characters + # stripping the whitespace characters plainMacro = plainMacro.strip() # ignoring the empty lines if len(plainMacro) == 0: @@ -1249,6 +1266,7 @@ def ParamFactory(paramInfo): param = SingleParamNode(param=paramInfo) return param + def createMacroNode(macro_name, params_def, macro_params): """The best effort creation of the macro XML object. It tries to convert flat list of string parameter values to the correct macro XML @@ -1287,7 +1305,7 @@ def createMacroNode(macro_name, params_def, macro_params): msg = "Repeat parameter must be the last one" raise Exception(msg) # If ParamRepeat only one and as last parameter - # this ignores raw_parameters which exceeds the param_def + # this ignores raw_parameters which exceeds the param_def for param_node, param_raw in zip(param_nodes, macro_params): if isinstance(param_node, SingleParamNode): param_node.setValue(param_raw) @@ -1295,12 +1313,13 @@ def createMacroNode(macro_name, params_def, macro_params): elif isinstance(param_node, RepeatParamNode): params_info = param_node.paramsInfo() params_info_len = len(params_info) - rep = 0; mem = 0 + rep = 0 + mem = 0 rest_raw = macro_params[i:] for member_raw in rest_raw: repeat_node = param_node.child(rep) # add a new repeat node (this is needed when the raw values - # fill more repeat nodes that the minimum number of + # fill more repeat nodes that the minimum number of # repetitions e.g. min=0 if repeat_node is None: repeat_node = param_node.addRepeat() @@ -1317,4 +1336,3 @@ def createMacroNode(macro_name, params_def, macro_params): else: macro_node.fromList(macro_params) return macro_node - diff --git a/src/sardana/taurus/core/tango/sardana/macroserver.py b/src/sardana/taurus/core/tango/sardana/macroserver.py index b88f951bf6..ea59295f7c 100755 --- a/src/sardana/taurus/core/tango/sardana/macroserver.py +++ b/src/sardana/taurus/core/tango/sardana/macroserver.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -60,6 +60,7 @@ CHANGE_EVT_TYPES = TaurusEventType.Change, TaurusEventType.Periodic + def recur_map(fun, data, keep_none=False): """Recursive map. Similar to map, but maintains the list objects structure @@ -75,6 +76,7 @@ def recur_map(fun, data, keep_none=False): else: return fun(data) + class Attr(Logger, EventGenerator): def __init__(self, dev, name, obj_class, attr): @@ -161,7 +163,8 @@ class MacroServerDevice(TangoDevice): def _getEventWait(self): if not hasattr(self, '_evt_wait'): # create an object that waits for attribute events. - # each time we use it we have to connect and disconnect to an attribute + # each time we use it we have to connect and disconnect to an + # attribute self._evt_wait = AttributeEventWait() return self._evt_wait @@ -206,11 +209,12 @@ def get(self, cache=False): for mnt_grp, reply in zip(mnt_grps, replies): try: mnt_grp_configs[mnt_grp] = \ - codec.decode(('json', reply.get_data().value), - ensure_ascii=True)[1] + codec.decode(('json', reply.get_data().value), + ensure_ascii=True)[1] except Exception, e: from taurus.core.util.log import warning - warning('Cannot load Measurement group "%s": %s', repr(mnt_grp), repr(e)) + warning('Cannot load Measurement group "%s": %s', + repr(mnt_grp), repr(e)) return ret def set(self, conf, mnt_grps=None): @@ -228,16 +232,18 @@ def set(self, conf, mnt_grps=None): for mnt_grp in mnt_grps: try: mnt_grp_cfg = conf['MntGrpConfigs'][mnt_grp] - if mnt_grp_cfg is None: #a mntGrp to be deleted + if mnt_grp_cfg is None: # a mntGrp to be deleted pool = self._getPoolOfElement(mnt_grp) pool.DeleteElement(mnt_grp) else: try: mnt_grp_dev = Device(mnt_grp) - except: #if the mnt_grp did not already exist, create it now + except: # if the mnt_grp did not already exist, create it now chconfigs = getChannelConfigs(mnt_grp_cfg) - chnames, chinfos = zip(*chconfigs) #unzipping - pool = self._getPoolOfElement(chnames[0]) #We assume that all the channels belong to the same pool! + chnames, chinfos = zip(*chconfigs) # unzipping + # We assume that all the channels belong to the same + # pool! + pool = self._getPoolOfElement(chnames[0]) pool.createMeasurementGroup([mnt_grp] + list(chnames)) mnt_grp_dev = Device(mnt_grp) @@ -248,7 +254,8 @@ def set(self, conf, mnt_grps=None): mnt_grp_dev.write_attribute('configuration', data) except Exception, e: from taurus.core.util.log import error - error('Could not create/delete/modify Measurement group "%s": %s', mnt_grp, repr(e)) + error( + 'Could not create/delete/modify Measurement group "%s": %s', mnt_grp, repr(e)) def _getPoolOfElement(self, elementname): ms = self._door.macro_server @@ -291,7 +298,6 @@ class BaseDoor(MacroServerDevice): # maximum execution time without user interruption InteractiveTimeout = 0.1 - def __init__(self, name, **kw): self._log_attr = CaselessDict() self._block_lines = 0 @@ -314,9 +320,9 @@ def __init__(self, name, **kw): try: self._old_sw_door_state = TaurusSWDevState.Uninitialized except RuntimeError: - #TODO: For Taurus 4 compatibility + # TODO: For Taurus 4 compatibility from taurus.core import TaurusDevState - self._old_sw_door_state = TaurusDevState.Undefined + self._old_sw_door_state = TaurusDevState.Undefined self.getStateObj().addListener(self.stateChanged) @@ -349,7 +355,7 @@ def get_input_handler(self): def get_color_mode(self): return "NoColor" - #def macrosChanged(self, s, v, t): + # def macrosChanged(self, s, v, t): # pass @property @@ -360,13 +366,13 @@ def log_start(self): kls = taurus.core.util.console.NoColors else: kls = taurus.core.util.console.TermColors - self._log_start = { BaseDoor.Critical : kls.LightRed, - BaseDoor.Error : kls.Red, - BaseDoor.Info : kls.LightBlue, - BaseDoor.Warning : kls.Brown, - BaseDoor.Output : kls.Normal, - BaseDoor.Debug : kls.DarkGray, - BaseDoor.Result : kls.LightGreen } + self._log_start = {BaseDoor.Critical: kls.LightRed, + BaseDoor.Error: kls.Red, + BaseDoor.Info: kls.LightBlue, + BaseDoor.Warning: kls.Brown, + BaseDoor.Output: kls.Normal, + BaseDoor.Debug: kls.DarkGray, + BaseDoor.Result: kls.LightGreen} return self._log_start @property @@ -377,13 +383,13 @@ def log_stop(self): kls = taurus.core.util.console.NoColors else: kls = taurus.core.util.console.TermColors - self._log_stop = { BaseDoor.Critical : kls.Normal, - BaseDoor.Error : kls.Normal, - BaseDoor.Info : kls.Normal, - BaseDoor.Warning : kls.Normal, - BaseDoor.Output : kls.Normal, - BaseDoor.Debug : kls.Normal, - BaseDoor.Result : kls.Normal } + self._log_stop = {BaseDoor.Critical: kls.Normal, + BaseDoor.Error: kls.Normal, + BaseDoor.Info: kls.Normal, + BaseDoor.Warning: kls.Normal, + BaseDoor.Output: kls.Normal, + BaseDoor.Debug: kls.Normal, + BaseDoor.Result: kls.Normal} return self._log_stop def getStateAttr(self): @@ -500,7 +506,7 @@ def preRunMacro(self, obj, parameters): self._clearRunMacro() xml_root = None - if isinstance(obj , (str, unicode)): + if isinstance(obj, (str, unicode)): if obj.startswith('<') and not parameters: xml_root = etree.fromstring(obj) else: @@ -610,17 +616,20 @@ def _processInput(self, input_data): self._input_handler.input_timeout(input_data) def recordDataReceived(self, s, t, v): - if t not in CHANGE_EVT_TYPES: return + if t not in CHANGE_EVT_TYPES: + return return self._processRecordData(v) def _processRecordData(self, data): - if data is None or data.value is None: return + if data is None or data.value is None: + return # make sure we get it as string since PyTango 7.1.4 returns a buffer # object and json.loads doesn't support buffer objects (only str) data = map(str, data.value) size = len(data[1]) - if size == 0: return + if size == 0: + return format = data[0] codec = CodecFactory().getCodec(format) data = codec.decode(data) @@ -632,7 +641,8 @@ def processRecordData(self, data): def macroStatusReceived(self, s, t, v): if v is None or self._running_macros is None: return - if t not in CHANGE_EVT_TYPES: return + if t not in CHANGE_EVT_TYPES: + return # make sure we get it as string since PyTango 7.1.4 returns a buffer # object and json.loads doesn't support buffer objects (only str) @@ -670,7 +680,8 @@ def logReceived(self, log_name, output): if line == self.BlockStart: self._in_block = True for i in xrange(self._block_lines): - o += '\x1b[2K\x1b[1A\x1b[2K' #erase current line, up one line, erase current line + # erase current line, up one line, erase current line + o += '\x1b[2K\x1b[1A\x1b[2K' self._block_lines = 0 continue elif line == self.BlockFinish: @@ -727,10 +738,10 @@ def __init__(self, ms): self.refresh() def refresh(self): - self.macro_path = mp = self._ms().get_property("MacroPath")["MacroPath"] + self.macro_path = mp = self._ms().get_property("MacroPath")[ + "MacroPath"] self.base_macro_path = osp.commonprefix(self.macro_path) - self.rel_macro_path = [ osp.relpath for p in mp, self.base_macro_path ] - + self.rel_macro_path = [osp.relpath for p in mp, self.base_macro_path] class Environment(dict): @@ -752,7 +763,7 @@ def __delattr__(self, key): ms.removeEnvironment(key) def __dir__(self): - return [ key for key in self.keys() if not key.startswith("_") ] + return [key for key in self.keys() if not key.startswith("_")] class BaseMacroServer(MacroServerDevice): @@ -813,7 +824,7 @@ def _removeEnvironment(self, key): pass def putEnvironment(self, name, value): - self.putEnvironments({ name : value }) + self.putEnvironments({name: value}) def putEnvironments(self, obj): obj = dict(new=obj) @@ -834,7 +845,7 @@ def removeEnvironment(self, key): return self.removeEnvironments(keys) def removeEnvironments(self, keys): - obj = { 'del' : keys } + obj = {'del': keys} codec = CodecFactory().getCodec('pickle') self.write_attribute('Environment', codec.encode(('', obj))) @@ -966,7 +977,8 @@ def getMacroNodeObj(self, macro_name): macroNode = MacroNode(name=macro_name) macroInfoObj = self.getMacroInfoObj(macro_name) - if macroInfoObj is None: return + if macroInfoObj is None: + return allowedHookPlaces = [] hints = macroInfoObj.hints if hints is not None: @@ -984,7 +996,8 @@ def getMacroNodeObj(self, macro_name): def validateMacroName(self, macroName): macroInfo = self.getElementInfo(macroName) if macroInfo is None: - raise Exception("%s macro does not exist in this sardana system." % macroName) + raise Exception( + "%s macro does not exist in this sardana system." % macroName) elif macroInfo.type != 'MacroClass': raise Exception("%s element is not a macro." % macroName) return True @@ -1029,32 +1042,40 @@ def validateSingleParam(self, singleParamNode): min = singleParamNode.min() max = singleParamNode.max() if min != None and value < min: - raise Exception("%s parameter value: %s is below minimum allowed value." % (name, value)) + raise Exception( + "%s parameter value: %s is below minimum allowed value." % (name, value)) if max != None and value > max: - raise Exception("%s parameter value: %s is above maximum allowed value." % (name, value)) + raise Exception( + "%s parameter value: %s is above maximum allowed value." % (name, value)) elif type == "Float": float(value) min = singleParamNode.min() max = singleParamNode.max() if min != None and value < min: - raise Exception("%s parameter value: %s is below minimum allowed value." % (name, value)) + raise Exception( + "%s parameter value: %s is below minimum allowed value." % (name, value)) if max != None and value > max: - raise Exception("%s parameter value: %s is above maximum allowed value." % (name, value)) + raise Exception( + "%s parameter value: %s is above maximum allowed value." % (name, value)) else: allowedInterfaces = self.getInterfaces().keys() if not type in allowedInterfaces: - raise Exception("No element with %s interface exist in this sardana system." % type) + raise Exception( + "No element with %s interface exist in this sardana system." % type) allowedValues = self.getElementNamesWithInterface(type) if not value in allowedValues: - raise Exception("%s element with %s interface does not exist in this sardana system." % (value, type)) + raise Exception( + "%s element with %s interface does not exist in this sardana system." % (value, type)) return True def validateRepeatParam(self, repeatParamNode): paramName = repeatParamNode.name() if repeatParamNode.isBelowMin(): - raise Exception("%s param repeats has not enough repeats." % (paramName)) + raise Exception( + "%s param repeats has not enough repeats." % (paramName)) if repeatParamNode.isAboveMax(): - raise Exception("%s param repeat has too many repeats." % (paramName)) + raise Exception( + "%s param repeat has too many repeats." % (paramName)) repetitions = repeatParamNode.children() for repeat in repetitions: params = repeat.children() @@ -1065,7 +1086,6 @@ def validateRepeatParam(self, repeatParamNode): self.validateRepeatParam(param) return True - def fillMacroNodeAdditionalInfos(self, macroNode): """ This method fills macroNode information which couldn't be stored @@ -1078,7 +1098,8 @@ def fillMacroNodeAdditionalInfos(self, macroNode): macroName = macroNode.name() macroInfoObj = self.getMacroInfoObj(macroName) if macroInfoObj is None: - raise Exception("It was not possible to get information about %s macro.\nCheck if MacroServer is alive and if this macro exist." % macroName) + raise Exception( + "It was not possible to get information about %s macro.\nCheck if MacroServer is alive and if this macro exist." % macroName) allowedHookPlaces = [] hints = macroInfoObj.hints or {} for hook in hints.get("allowsHooks", []): @@ -1105,7 +1126,8 @@ def __fillParamNodeAdditionalInfos(self, paramNode, paramInfo): paramNode.setParamsInfo(type) for repeatNode in paramNode.children(): for internalParamNode, internalParamInfo in zip(repeatNode.children(), type): - self.__fillParamNodeAdditionalInfos(internalParamNode, internalParamInfo) + self.__fillParamNodeAdditionalInfos( + internalParamNode, internalParamInfo) else: paramNode.setType(str(type)) paramNode.setDefValue(str(paramInfo.get("default_value"))) @@ -1123,7 +1145,8 @@ def recreateMacroNodeAndFillAdditionalInfos(self, macroNode): self.validateMacroName(macroName) macroInfoObj = self.getMacroInfoObj(macroName) if macroInfoObj is None: - raise Exception("It was not possible to get information about %s macro.\nCheck if MacroServer is alive and if this macro exist." % macroName) + raise Exception( + "It was not possible to get information about %s macro.\nCheck if MacroServer is alive and if this macro exist." % macroName) allowedHookPlaces = [] hints = macroInfoObj.hints or {} for hook in hints.get("allowsHooks", []): @@ -1139,7 +1162,8 @@ def recreateMacroNodeAndFillAdditionalInfos(self, macroNode): for paramNode, paramInfo in zip(paramNodes, paramInfosList): paramType = paramInfo.get('type') if isinstance(paramType, list): - paramNode = self.__recreateParamRepeatNodes(macroNode, paramIndex, paramInfo) + paramNode = self.__recreateParamRepeatNodes( + macroNode, paramIndex, paramInfo) else: paramNode.setName(paramInfo.get("name")) self.__recreateParamNodeAdditionalInfos(paramNode, paramInfo) @@ -1147,7 +1171,8 @@ def recreateMacroNodeAndFillAdditionalInfos(self, macroNode): self.validateMacroNode(macroNode) def __recreateParamRepeatNodes(self, macroNode, indexToStart, repeatParamInfo): - #extracting rest of the single params which have to be adopted to param repeats + # extracting rest of the single params which have to be adopted to + # param repeats paramNodes = [] while len(macroNode.params()) > indexToStart: lastParam = macroNode.popParam() @@ -1161,7 +1186,8 @@ def __recreateParamRepeatNodes(self, macroNode, indexToStart, repeatParamInfo): repeatParamChildrenInfos = repeatParamInfo.get("type") if nrOfSingleParams % len(repeatParamChildrenInfos): - raise Exception("Param repeat %s doesn't have correct number of repetitions" % paramName) + raise Exception( + "Param repeat %s doesn't have correct number of repetitions" % paramName) nrOfRepeats = nrOfSingleParams / len(repeatParamChildrenInfos) repeatParamNode = RepeatParamNode(macroNode, repeatParamInfo) for repeatIdx in range(nrOfRepeats): @@ -1190,12 +1216,12 @@ def __recreateParamNodeAdditionalInfos(self, paramNode, paramInfo): paramNode.setParamsInfo(paramType) for repeatNode in paramNode.children(): for internalParamNode, internalParamInfo in zip(repeatNode.children(), paramType): - self.__recreateParamNodeAdditionalInfos(internalParamNode, internalParamInfo) + self.__recreateParamNodeAdditionalInfos( + internalParamNode, internalParamInfo) else: paramNode.setType(paramType) paramNode.setDefValue(str(paramInfo.get("default_value"))) - def getMacroPathObj(self, cache=False): if not hasattr(self, "_macro_path"): self._macro_path = MacroPath(self) @@ -1210,6 +1236,7 @@ def registerExtensions(): factory.registerDeviceClass('MacroServer', BaseMacroServer) factory.registerDeviceClass('Door', BaseDoor) + def unregisterExtensions(): """Registers the macroserver extensions in the :class:`taurus.core.tango.TangoFactory`""" factory = Factory('tango') diff --git a/src/sardana/taurus/core/tango/sardana/motion.py b/src/sardana/taurus/core/tango/sardana/motion.py index 9183904c9f..72019b8980 100644 --- a/src/sardana/taurus/core/tango/sardana/motion.py +++ b/src/sardana/taurus/core/tango/sardana/motion.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -33,6 +33,7 @@ from taurus.core.util.containers import CaselessDict + class Moveable: """ An item that can 'move'. In order to move it you need to provide a list of values (normally interpreted as motor positions). @@ -43,23 +44,23 @@ def __init__(self): def startMove(self, new_pos, timeout=None): """ startMove(sequence new_pos, double timeout=None) -> sequence - + Calling this method will trigger a movement off all components of the movement.""" pass def waitMove(self, timeout=None, id=None): """ waitMove(float timeout=None, sequence id=None) -> None - + Waits for the movement to end. If no movement is active the method returns immediately.""" pass def move(self, new_pos, timeout=None): """ move(list new_pos, timeout=None) -> None - + Triggers a movement and waits for it to end. - + """ self.waitMove(id=self.startMove(new_pos, timeout=timeout)) @@ -143,12 +144,13 @@ def init_by_movables(self, elements, moveable_srcs, allow_repeat, allow_unknown) self.moveable_list = elements def init_by_names(self, names, moveable_srcs, allow_repeat, allow_unknown): - moveables = [ self.getMoveable(moveable_srcs, name) for name in names ] + moveables = [self.getMoveable(moveable_srcs, name) for name in names] self.init_by_movables(moveables, moveable_srcs, allow_repeat, allow_unknown) def getLastMotionTime(self): - times = [ moveable.getLastMotionTime() for moveable in self.moveable_list ] + times = [moveable.getLastMotionTime() + for moveable in self.moveable_list] return max(times) def getTotalLastMotionTime(self): @@ -197,22 +199,22 @@ def iterMove(self, new_pos, timeout=None): raise NotImplementedError def getStatus(self): -# res = [] -# for moveable in self.moveable_list: -# status = moveable.status.split('\n') -# res.append(moveable.getName() + ":") -# for st in status: -# res.append(" " + st) -# return "\n".join(res) - return "\n".join([ m.status() for m in self.moveable_list ]) + # res = [] + # for moveable in self.moveable_list: + # status = moveable.status.split('\n') + # res.append(moveable.getName() + ":") + # for st in status: + # res.append(" " + st) + # return "\n".join(res) + return "\n".join([m.status() for m in self.moveable_list]) def readState(self, force=False): if len(self.moveable_list) == 1: return self.moveable_list[0].getState() - return [ m.getState() for m in self.moveable_list ] + return [m.getState() for m in self.moveable_list] def readPosition(self, force=False): - return [ m.readPosition(force=force) for m in self.moveable_list ] + return [m.readPosition(force=force) for m in self.moveable_list] def abort(self, wait_ready=True, timeout=None): for moveable in self.moveable_list: @@ -245,13 +247,13 @@ def __init__(self, elements, moveable_srcs, allow_repeat=False, def init_by_movables(self, elements, moveable_srcs, allow_repeat, allow_unknown): # TODO: Optimize this. Dont call init_by_names. It its possible to do it # manually with some performance gain - names = [ elem.getName() for elem in elements] + names = [elem.getName() for elem in elements] self.init_by_names(names, moveable_srcs, allow_repeat, allow_unknown) def init_by_names(self, names, moveable_srcs, allow_repeat, allow_unknown): ms_elem_names = self.getElemNamesByMoveableSource(names, moveable_srcs, - allow_repeat=allow_repeat, allow_unknown=allow_unknown) + allow_repeat=allow_repeat, allow_unknown=allow_unknown) # map ms_moveables = {} @@ -289,8 +291,8 @@ def init_by_names(self, names, moveable_srcs, allow_repeat, allow_unknown): self.ms_moveables = ms_moveables # a buffer for positions for performance reasons - #list> index of outer list is the moveable index. The - #contents of the list are the ordered positions for that moveable + # list> index of outer list is the moveable index. The + # contents of the list are the ordered positions for that moveable pos_buff = [] total_count = 0 for m in moveable_list: @@ -303,12 +305,12 @@ def init_by_names(self, names, moveable_srcs, allow_repeat, allow_unknown): assert(total_count == len(self.names)) def getElemNamesByMoveableSource(self, names, moveable_sources, - allow_repeat, - allow_unknown): + allow_repeat, + allow_unknown): """ getElemNamesByMoveableSource(listnames, list moveable_sources, bool allow_repeat, bool allow_unknown) - + Organizes the elements by moveable source. The result is a dictionary with key being the MoveableSource and data a list of the names that belong to the that motion source. @@ -320,24 +322,25 @@ def getElemNamesByMoveableSource(self, names, moveable_sources, moveable = None for moveable_source in moveable_sources: - moveable = moveable_source.getMoveable([name]) - if not moveable is None: - if not ms_elems.has_key(moveable_source): - ms_elems[moveable_source] = [] - moveable_source_moveables = ms_elems.get(moveable_source) - present = name in moveable_source_moveables - if not present or (present and allow_repeat): - moveable_source_moveables.append(name) - break - elif present and not allow_repeat: - raise Exception("Moveable item %s appears more " - "than once" % name) + moveable = moveable_source.getMoveable([name]) + if not moveable is None: + if not ms_elems.has_key(moveable_source): + ms_elems[moveable_source] = [] + moveable_source_moveables = ms_elems.get(moveable_source) + present = name in moveable_source_moveables + if not present or (present and allow_repeat): + moveable_source_moveables.append(name) + break + elif present and not allow_repeat: + raise Exception("Moveable item %s appears more " + "than once" % name) if moveable is None and not allow_unknown: - raise Exception("Moveable item %s not found" % name) + raise Exception("Moveable item %s not found" % name) return ms_elems def getLastMotionTime(self): - times = [ moveable.getLastMotionTime() for moveable in self.moveable_list ] + times = [moveable.getLastMotionTime() + for moveable in self.moveable_list] return max(times) def getTotalLastMotionTime(): @@ -398,23 +401,26 @@ def move(self, new_pos, timeout=None): def iterMove(self, new_pos, timeout=None): """ generator for motor positions""" - assert len(self.moveable_list) == 1, "for now we support only 'simple' motions!!!!" + assert len( + self.moveable_list) == 1, "for now we support only 'simple' motions!!!!" moveable = self.moveable_list[0] for p in moveable.iterMove(new_pos, timeout=timeout): yield p def getStatus(self): - return "\n".join([ m.status() for m in self.moveable_list ]) + return "\n".join([m.status() for m in self.moveable_list]) def readState(self, force=False): if len(self.moveable_list) == 1: return self.moveable_list[0].getState() - return [ m.getState() for m in self.moveable_list ] + return [m.getState() for m in self.moveable_list] def readPosition(self, force=False): - moveable_pos_list = [ m.readPosition(force=force) for m in self.moveable_list ] - pos = [ moveable_pos_list[pair[0]][pair[1]] for pair in self.pos_to_moveable ] + moveable_pos_list = [m.readPosition( + force=force) for m in self.moveable_list] + pos = [moveable_pos_list[pair[0]][pair[1]] + for pair in self.pos_to_moveable] return pos def abort(self, wait_ready=True, timeout=None): @@ -428,11 +434,13 @@ def stop(self, wait_ready=True, timeout=None): def read(self): pass -#------------------------------------------------------------------------------- +#------------------------------------------------------------------------- # Small test framework -#------------------------------------------------------------------------------- +#------------------------------------------------------------------------- + class PoolMoveableTest(Moveable): + def __init__(self, name, elems, moveable_src, mov_items=None): self.name = name self.elem_names = elems @@ -465,6 +473,7 @@ def getIndex(self, name): except: return -1 + class PoolMSTest(MoveableSource): def __init__(self, initial_elems): @@ -474,17 +483,20 @@ def __init__(self, initial_elems): self.motors = CaselessDict() for elem_name in initial_elems: - self.motors[elem_name] = PoolMoveableTest(elem_name, [elem_name], self) + self.motors[elem_name] = PoolMoveableTest( + elem_name, [elem_name], self) self.motor_group = None def getMoveable(self, names): if len(names) == 1: return self.motors.get(names[0]) l = [name for name in self.elem_names if name in names] - self.motor_group = PoolMoveableTest("moveable %d" % self.moveable_inc, l, self) + self.motor_group = PoolMoveableTest( + "moveable %d" % self.moveable_inc, l, self) self.moveable_inc += 1 return self.motor_group + def test(): ms1 = PoolMSTest(["m1", "m2", "m3", "m4"]) ms2 = PoolMSTest(["m5", "m6", "m7", "m8"]) @@ -563,5 +575,3 @@ def test(): if __name__ == "__main__": test() - - diff --git a/src/sardana/taurus/core/tango/sardana/pool.py b/src/sardana/taurus/core/tango/sardana/pool.py index 0cc8a3c39f..9697de74f1 100644 --- a/src/sardana/taurus/core/tango/sardana/pool.py +++ b/src/sardana/taurus/core/tango/sardana/pool.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -53,7 +53,7 @@ from taurus.core.taurusvalidator import AttributeNameValidator as\ TangoAttributeNameValidator except ImportError: - #TODO: For Taurus 4 compatibility + # TODO: For Taurus 4 compatibility from taurus.core.tango.tangovalidator import TangoAttributeNameValidator from taurus.core.util.log import Logger from taurus.core.util.singleton import Singleton @@ -76,23 +76,27 @@ MOVEABLE_TYPES = 'Motor', 'PseudoMotor', 'MotorGroup' QUALITY = { - AttrQuality.ATTR_VALID : 'VALID', - AttrQuality.ATTR_INVALID : 'INVALID', - AttrQuality.ATTR_CHANGING : 'CHANGING', - AttrQuality.ATTR_WARNING : 'WARNING', - AttrQuality.ATTR_ALARM : 'ALARM', - None : 'UNKNOWN' + AttrQuality.ATTR_VALID: 'VALID', + AttrQuality.ATTR_INVALID: 'INVALID', + AttrQuality.ATTR_CHANGING: 'CHANGING', + AttrQuality.ATTR_WARNING: 'WARNING', + AttrQuality.ATTR_ALARM: 'ALARM', + None: 'UNKNOWN' } + class InterruptException(Exception): pass + class StopException(InterruptException): pass + class AbortException(InterruptException): pass + class BaseElement(object): """ The base class for elements in the Pool (Pool itself, Motor, ControllerClass, ExpChannel all should inherit from this class directly or @@ -175,9 +179,11 @@ def getOrganization(self): def __cmp__(self, o): t = cmp(self.getType(), o.getType()) - if t != 0: return t + if t != 0: + return t t = cmp(self.getGender(), o.getGender()) - if t != 0: return t + if t != 0: + return t return cmp(self.getClassName(), o.getClassName()) @@ -325,7 +331,8 @@ def getReservedWR(self): return self._reserved def getReserved(self): - if self._reserved is None: return None + if self._reserved is None: + return None return self._reserved() def dump_attributes(self): @@ -335,7 +342,8 @@ def dump_attributes(self): def _getAttrValue(self, name, force=False): attrEG = self._getAttrEG(name) - if attrEG is None: return None + if attrEG is None: + return None return attrEG.readValue(force=force) def _getAttrEG(self, name): @@ -356,7 +364,8 @@ def _createAttribute(self, name): def _getEventWait(self): if self._evt_wait is None: # create an object that waits for attribute events. - # each time we use it we have to connect and disconnect to an attribute + # each time we use it we have to connect and disconnect to an + # attribute self._evt_wait = AttributeEventWait() return self._evt_wait @@ -401,13 +410,15 @@ def getInstrumentObj(self): def getInstrumentName(self, force=False): instr_name = self._getAttrValue('instrument', force=force) - if not instr_name: return '' + if not instr_name: + return '' #instr_name = instr_name[:instr_name.index('(')] return instr_name def getInstrument(self): instr_name = self.getInstrumentName() - if not instr_name: return None + if not instr_name: + return None return self.getPoolObj().getObj("Instrument", instr_name) @reservedOperation @@ -487,7 +498,7 @@ def information(self, tab=' '): def _information(self, tab=' '): indent = "\n" + tab + 10 * ' ' - msg = [ self.getName() + ":" ] + msg = [self.getName() + ":"] try: state = str(self.state()).capitalize() except DevFailed, df: @@ -618,6 +629,7 @@ class TriggerGate(PoolElement): """ Class encapsulating TriggerGate functionality.""" pass + class Motor(PoolElement, Moveable): """ Class encapsulating Motor functionality.""" @@ -726,7 +738,7 @@ def setSign(self, value): def _start(self, *args, **kwargs): new_pos = args[0] if operator.isSequenceType(new_pos): - new_pos = new_pos[0] + new_pos = new_pos[0] try: self.write_attribute('position', new_pos) except DevFailed, df: @@ -772,8 +784,10 @@ def iterMove(self, new_pos, timeout=None): raise self.final_pos = new_pos # putting timeout=0.1 and retries=1 is a patch for the case the when the initial - # moving event doesn't arrive do to an unknow tango/pytango error at the time - evt_wait.waitEvent(DevState.MOVING, time_stamp, timeout=0.1, retries=1) + # moving event doesn't arrive do to an unknow tango/pytango error + # at the time + evt_wait.waitEvent(DevState.MOVING, time_stamp, + timeout=0.1, retries=1) finally: evt_wait.unlock() evt_wait.disconnect() @@ -791,7 +805,7 @@ def iterMove(self, new_pos, timeout=None): evt_iter_wait.disconnect() def readPosition(self, force=False): - return [ self.getPosition(force=force) ] + return [self.getPosition(force=force)] def getMoveableSource(self): return self.getPoolObj() @@ -855,7 +869,7 @@ def getDialPositionObj(self): def _start(self, *args, **kwargs): new_pos = args[0] if operator.isSequenceType(new_pos): - new_pos = new_pos[0] + new_pos = new_pos[0] try: self.write_attribute('position', new_pos) except DevFailed, df: @@ -880,7 +894,7 @@ def go(self, *args, **kwargs): getTotalLastMotionTime = PoolElement.getTotalLastGoTime def readPosition(self, force=False): - return [ self.getPosition(force=force) ] + return [self.getPosition(force=force)] def getMoveableSource(self): return self.getPoolObj() @@ -1074,16 +1088,20 @@ def getChannelConfigs(mgconfig, ctrls=None, sort=True): :return: (list) A list of channelname,channeldata pairs. ''' chconfigs = [] - if not mgconfig: return [] + if not mgconfig: + return [] for ctrl_name, ctrl_data in mgconfig['controllers'].items(): if ctrls is None or ctrl_name in ctrls: for ch_name, ch_data in ctrl_data['channels'].items(): - ch_data.update({'_controller_name': ctrl_name}) - chconfigs.append((ch_name, ch_data)) + ch_data.update({'_controller_name': ctrl_name}) + chconfigs.append((ch_name, ch_data)) if sort: - #sort the channel configs by index (primary sort) and then by channel name. - chconfigs = sorted(chconfigs, key=lambda c:c[0]) #sort by channel_name - chconfigs = sorted(chconfigs, key=lambda c:c[1].get('index', 1e16)) #sort by index (give a very large index for those which don't have it) + # sort the channel configs by index (primary sort) and then by channel + # name. + chconfigs = sorted(chconfigs, key=lambda c: c[ + 0]) # sort by channel_name + # sort by index (give a very large index for those which don't have it) + chconfigs = sorted(chconfigs, key=lambda c: c[1].get('index', 1e16)) return chconfigs @@ -1171,7 +1189,8 @@ def _build(self): # NON tango channel. params = tg_attr_validator.getParams(data_source) if params is None: - params = tg_attr_validator.getParams("tango://%s" % data_source) + params = tg_attr_validator.getParams( + "tango://%s" % data_source) if params is None: # Handle NON tango channel n_tg_chs[channel_name] = channel_data @@ -1191,7 +1210,7 @@ def _build(self): dev = DeviceProxy(dev_name) except: self.tango_dev_channels_in_error += 1 - tg_dev_chs[dev_name] = dev_data = [ dev, CaselessDict() ] + tg_dev_chs[dev_name] = dev_data = [dev, CaselessDict()] dev, attr_data = dev_data attr_data[attr_name] = channel_data @@ -1201,7 +1220,8 @@ def _build(self): self.tango_channels_info_in_error += 1 else: try: - tg_attr_info = dev.get_attribute_config_ex(attr_name)[0] + tg_attr_info = dev.get_attribute_config_ex(attr_name)[ + 0] except: tg_attr_info = \ self._build_empty_tango_attr_info(channel_data) @@ -1295,7 +1315,7 @@ def getChannelsInfoList(self, only_enabled=False): ret = [] for _, (_, _, ch_info) in channels_info.items(): ret.append(ch_info) - ret = sorted(ret, lambda x,y: cmp(x.index, y.index)) + ret = sorted(ret, lambda x, y: cmp(x.index, y.index)) return ret def getCountersInfoList(self): @@ -1349,7 +1369,8 @@ def _read_parallel(self): if dev is None: continue try: - dev_replies[dev] = dev.read_attributes_asynch(attrs.keys()), attrs + dev_replies[dev] = dev.read_attributes_asynch( + attrs.keys()), attrs except: dev_replies[dev] = None, attrs @@ -1391,6 +1412,7 @@ def _read(self): ret[channel_data['full_name']] = None return ret + class MeasurementGroup(PoolElement): """ Class encapsulating MeasurementGroup functionality.""" @@ -1463,19 +1485,19 @@ def getChannels(self): def getCounters(self): cfg = self.getConfiguration() - return [ ch for ch in self.getChannels() if ch['full_name'] != cfg.timer ] + return [ch for ch in self.getChannels() if ch['full_name'] != cfg.timer] def getChannelNames(self): - return [ ch['name'] for ch in self.getChannels() ] + return [ch['name'] for ch in self.getChannels()] def getCounterNames(self): - return [ ch['name'] for ch in self.getCounters() ] + return [ch['name'] for ch in self.getCounters()] def getChannelLabels(self): - return [ ch['label'] for ch in self.getChannels() ] + return [ch['label'] for ch in self.getChannels()] def getCounterLabels(self): - return [ ch['label'] for ch in self.getCounters() ] + return [ch['label'] for ch in self.getCounters()] def getChannel(self, name): return self.getConfiguration().channels[name] @@ -1552,7 +1574,7 @@ def getLatencyTime(self): def setMoveable(self, moveable=None): if moveable is None: - moveable = 'None' # Tango attribute is of type DevString + moveable = 'None' # Tango attribute is of type DevString self.getMoveableObj().write(moveable) def addOnDataChangedListeners(self, listener): @@ -1560,21 +1582,21 @@ def addOnDataChangedListeners(self, listener): collection while acquiring.''' for channel in self.getChannels(): attrName = '%s/%s' % (channel['full_name'], "data") - self.addAttrListener(attrName, listener) + self.addAttrListener(attrName, listener) def removeOnDataChangedListeners(self, listener): '''Removes listener which receives data events. Used in online data collection while acquiring.''' for channel in self.getChannels(): attrName = '%s/%s' % (channel['full_name'], "data") - self.removeAttrListener(attrName, listener) + self.removeAttrListener(attrName, listener) def addAttrListener(self, attrName, listener): attr = Attribute(attrName) attr.addListener(listener) def removeAttrListener(self, attrName, listener): - attr = Attribute(attrName) + attr = Attribute(attrName) attr.removeListener(listener) def enableChannels(self, channels): @@ -1609,11 +1631,10 @@ def _enableChannels(self, channels, state): wrong_channels.append(ch) if len(wrong_channels) > 0: msg = 'channels: %s are not present in measurement group' % \ - wrong_channels + wrong_channels raise Exception(msg) self.setConfiguration(cfg.raw_data) - def _start(self, *args, **kwargs): self.Start() @@ -1944,7 +1965,6 @@ def renameElement(self, old_name, new_name): return self._wait_for_element_in_container(elements_info, new_name, contains=True) - def deleteElement(self, name): self.debug('trying to delete element: %s', name) self.command_inout('DeleteElement', name) @@ -1977,11 +1997,12 @@ def registerExtensions(): 'CTExpChannel', 'ZeroDExpChannel', 'OneDExpChannel', 'TwoDExpChannel', 'PseudoCounter', 'IORegister', 'MotorGroup', 'MeasurementGroup'] - hw_type_map = [ (name, globals()[name]) for name in hw_type_names ] + hw_type_map = [(name, globals()[name]) for name in hw_type_names] for klass_name, klass in hw_type_map: factory.registerDeviceClass(klass_name, klass) + def unregisterExtensions(): factory = Factory() factory.unregisterDeviceClass("Pool") diff --git a/src/sardana/taurus/core/tango/sardana/sardana.py b/src/sardana/taurus/core/tango/sardana/sardana.py index c119d37dfc..b3f49ad4e8 100644 --- a/src/sardana/taurus/core/tango/sardana/sardana.py +++ b/src/sardana/taurus/core/tango/sardana/sardana.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -48,31 +48,31 @@ from taurus.core.util.codecs import CodecFactory PoolElementType = Enumeration("PoolElementType", - ("0D", "1D", "2D", "Communication", "CounterTimer", "IORegister", - "Motor", "PseudoCounter", "PseudoMotor", "TriggerGate")) + ("0D", "1D", "2D", "Communication", "CounterTimer", "IORegister", + "Motor", "PseudoCounter", "PseudoMotor", "TriggerGate")) ChannelView = Enumeration("ChannelView", - ("Channel", "Enabled", "Output", "PlotType", "PlotAxes", "Timer", - "Monitor", "Synchronization", "Conditioning", "Normalization", "NXPath", - "Shape", "DataType", - "Unknown", "Synchronizer")) + ("Channel", "Enabled", "Output", "PlotType", "PlotAxes", "Timer", + "Monitor", "Synchronization", "Conditioning", "Normalization", "NXPath", + "Shape", "DataType", + "Unknown", "Synchronizer")) PlotType = Enumeration("PlotType", ("No", "Spectrum", "Image")) Normalization = Enumeration("Normalization", ("No", "Avg", "Integ")) #: an enumeration describing all possible acquisition trigger types -AcqTriggerType = Enumeration("AcqTriggerType", (\ +AcqTriggerType = Enumeration("AcqTriggerType", ( "Software", # channel triggered by software - start and stop by software - "Trigger", # channel triggered by HW - start by external + "Trigger", # channel triggered by HW - start by external "Gate", # channel triggered by HW - start and stop by external "Unknown")) #: an enumeration describing all possible acquisition mode types -AcqMode = Enumeration("AcqMode", ( \ +AcqMode = Enumeration("AcqMode", ( "Timer", "Monitor", - "Unknown") ) + "Unknown")) class BaseSardanaElement(object): @@ -119,8 +119,8 @@ def serialize(self, *args, **kwargs): return kwargs def str(self, *args, **kwargs): - #TODO change and check which is the active protocol to serialize - #acordingly + # TODO change and check which is the active protocol to serialize + # acordingly return CodecFactory().encode(('json', self.serialize(*args, **kwargs))) def getObj(self): @@ -130,7 +130,6 @@ def getObj(self): return obj - class BaseSardanaElementContainer: def __init__(self): @@ -147,7 +146,7 @@ def addElement(self, elem): elem_type = elem.getType() elem_full_name = elem.full_name - #update type_elems + # update type_elems type_elems = self._type_elems_dict.get(elem_type) if type_elems is None: self._type_elems_dict[elem_type] = type_elems = CaselessDict() @@ -157,7 +156,8 @@ def addElement(self, elem): for interface in elem.interfaces: interface_elems = self._interfaces_dict.get(interface) if interface_elems is None: - self._interfaces_dict[interface] = interface_elems = CaselessDict() + self._interfaces_dict[ + interface] = interface_elems = CaselessDict() interface_elems[elem_full_name] = elem def removeElement(self, e): @@ -236,7 +236,10 @@ def getTypes(self): # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + + class PropertyInfo(): + def __init__(self, name, type, format, default_value=None): self._name = name self._type = type @@ -303,22 +306,32 @@ def get_family(self): def get_properties(self): properties = [] # fake data ###################### - properties.append(PropertyInfo("my parameter", "string", "0D", "deviceName")) + properties.append(PropertyInfo( + "my parameter", "string", "0D", "deviceName")) properties.append(PropertyInfo("asdsadasd", "integer", "0D", 5)) properties.append(PropertyInfo("boollll0", "boolean", "0D", False)) properties.append(PropertyInfo("boollll0", "boolean", "0D", True)) properties.append(PropertyInfo("boollll0", "boolean", "0D", False)) properties.append(PropertyInfo("number1", "float", "0D", 3.5)) properties.append(PropertyInfo("string2", "string", "0D", "hehe")) - properties.append(PropertyInfo("tableIntegerD1", "integer", "1D", [1, 2, 3])) - properties.append(PropertyInfo("tablestringD1", "string", "1D", ["aaaa", "bbb", "ccc"])) - properties.append(PropertyInfo("tablefloatD1", "float", "1D", [1.0, 2.5, 3.6])) - properties.append(PropertyInfo("tablebooleanD1", "boolean", "1D", [True, False, True, False])) - properties.append(PropertyInfo("tablebleintegerD1", "integer", "1D", [1, 2, 3])) - properties.append(PropertyInfo("tablebooleanD2", "boolean", "2D", [ [True, False, True], [True, True, True], [False, False, False] ])) - properties.append(PropertyInfo("tableinteger2", "integer", "2D", [ [1, 2, 3], [11, 22, 33], [-10, -20, -30] ])) - properties.append(PropertyInfo("tablefloatD2", "float", "2D", [ [0.5, 0.6, 0.8], [0.4, 0.0, 0.333333], [-0.1111, 1, 123123.6] ])) - properties.append(PropertyInfo("tablestringD2", "string", "2D", [ ["aaaa", "bbb", "ccc"], ["aaaa2", "bbb2", "ccc2"], ["aaaa3", "bbb3", "ccc3"] ])) + properties.append(PropertyInfo( + "tableIntegerD1", "integer", "1D", [1, 2, 3])) + properties.append(PropertyInfo( + "tablestringD1", "string", "1D", ["aaaa", "bbb", "ccc"])) + properties.append(PropertyInfo( + "tablefloatD1", "float", "1D", [1.0, 2.5, 3.6])) + properties.append(PropertyInfo("tablebooleanD1", + "boolean", "1D", [True, False, True, False])) + properties.append(PropertyInfo( + "tablebleintegerD1", "integer", "1D", [1, 2, 3])) + properties.append(PropertyInfo("tablebooleanD2", "boolean", "2D", [ + [True, False, True], [True, True, True], [False, False, False]])) + properties.append(PropertyInfo("tableinteger2", "integer", "2D", [ + [1, 2, 3], [11, 22, 33], [-10, -20, -30]])) + properties.append(PropertyInfo("tablefloatD2", "float", "2D", [ + [0.5, 0.6, 0.8], [0.4, 0.0, 0.333333], [-0.1111, 1, 123123.6]])) + properties.append(PropertyInfo("tablestringD2", "string", "2D", [ + ["aaaa", "bbb", "ccc"], ["aaaa2", "bbb2", "ccc2"], ["aaaa3", "bbb3", "ccc3"]])) return properties @@ -350,14 +363,14 @@ def get_max_elements(self): return self._ctrl_class_info.get_max_elements() def is_axis_free(self, axis): - #fake data + # fake data if axis == 3: return False else: return True def is_name_free(self, name): - #fake data + # fake data if name == "asd": return False else: @@ -371,6 +384,8 @@ def get_icon(self): # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + + class Pool(object): def __init__(self, sardana, name, poolpath, version, alias=None, device_name=None): @@ -397,9 +412,11 @@ def get_controller_class_infos(self): #fake data ######################## data = [] for i in range(5): - data.append(ControllerClassInfo("motorController" + str(i), PoolElementType.Motor, None)) + data.append(ControllerClassInfo("motorController" + + str(i), PoolElementType.Motor, None)) for i in range(5): - data.append(ControllerClassInfo("counterTimerController" + str(i), PoolElementType.CounterTimer, None)) + data.append(ControllerClassInfo( + "counterTimerController" + str(i), PoolElementType.CounterTimer, None)) return data @@ -407,9 +424,11 @@ def get_controller_infos(self): ctrl_classes = self.get_controller_class_infos() data = [] for i in range(2): - data.append(ControllerInfo("My_motor_ctrl_" + str(i), ctrl_classes[i])) + data.append(ControllerInfo( + "My_motor_ctrl_" + str(i), ctrl_classes[i])) for i in range(2): - data.append(ControllerInfo("My_ct_ctrl_" + str(i), ctrl_classes[i + 5])) + data.append(ControllerInfo( + "My_ct_ctrl_" + str(i), ctrl_classes[i + 5])) return data def create_controller(self, controller_class_info, name, properties): @@ -474,6 +493,8 @@ def get_database(self): # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + + class Door(object): def __init__(self, alias=None, device_name=None): @@ -488,7 +509,7 @@ def __init__(self, alias=None, device_name=None): #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- class Sardana(object): - def __init__(self, sardana_db , name, device_name=None): + def __init__(self, sardana_db, name, device_name=None): self._sardana_db = sardana_db self._name = name self._device_name = device_name @@ -510,7 +531,8 @@ def _init(self): pass elif dev_class_name == "MacroServer": ms_dev_name = dev_name - ms_prop_list = map(str.lower, db.get_device_property_list(ms_dev_name, "*")) + ms_prop_list = map( + str.lower, db.get_device_property_list(ms_dev_name, "*")) ms_props = db.get_device_property(ms_dev_name, ms_prop_list) ms_name = dev_info.server().serverInstance() ms_alias = dev_info.alias() @@ -518,12 +540,15 @@ def _init(self): ms_props.get("version"), ms_alias, ms_dev_name) self._macroservers.append(ms) for pool_dev_name in ms_props.get("poolnames", ()): - pool_prop_list = map(str.lower, db.get_device_property_list(pool_dev_name, "*")) - pool_props = db.get_device_property(pool_dev_name, pool_prop_list) + pool_prop_list = map( + str.lower, db.get_device_property_list(pool_dev_name, "*")) + pool_props = db.get_device_property( + pool_dev_name, pool_prop_list) pool_dev_info = cache.devices()[pool_dev_name] pool_name = pool_dev_info.server().serverInstance() pool_alias = pool_dev_info.alias() - pool = Pool(self, pool_name, pool_props.get("poolpath"), pool_props.get("version"), pool_alias, pool_dev_name) + pool = Pool(self, pool_name, pool_props.get( + "poolpath"), pool_props.get("version"), pool_alias, pool_dev_name) self._pools.append(pool) def get_name(self): @@ -560,8 +585,10 @@ def _create_pool(self, name, poolpath, version, alias=None, device_name=None): if alias: db.put_device_alias(device_name, alias) - db.put_device_property(device_name, {"PoolPath" : poolpath, "Version": version}) - pool = Pool(self, name, poolpath, version, alias=alias, device_name=device_name) + db.put_device_property( + device_name, {"PoolPath": poolpath, "Version": version}) + pool = Pool(self, name, poolpath, version, + alias=alias, device_name=device_name) self._pools.append(pool) db.cache().refresh() return pool @@ -584,8 +611,10 @@ def _create_macroserver(self, name, macropath, pool_names, version, alias=None, if alias: db.put_device_alias(device_name, alias) - db.put_device_property(device_name, {"MacroPath" : macropath, "Version": version, "PoolNames":pool_names}) - ms = MacroServer(self, name, macropath, pool_names, version, alias=alias, device_name=device_name) + db.put_device_property(device_name, { + "MacroPath": macropath, "Version": version, "PoolNames": pool_names}) + ms = MacroServer(self, name, macropath, pool_names, + version, alias=alias, device_name=device_name) self._macroservers.append(ms) db.cache().refresh() return ms @@ -604,6 +633,8 @@ def get_database(self): # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + + class DatabaseSardana(object): """A class containning all sardanas for a single database""" @@ -618,7 +649,8 @@ def refresh(self): for service, dev in services.items(): service_type, service_instance = service.split("/", 1) try: - sardanas[service_instance] = Sardana(self, service_instance, dev) + sardanas[service_instance] = Sardana( + self, service_instance, dev) except: pass @@ -651,6 +683,8 @@ def get_database(self): # # THIS IS USED FOR TEST PURPOSES ONLY. DO NOT USE IT OUTSIDE SARDANA TESTS #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- + + class SardanaManager(Singleton, Logger): def __init__(self): @@ -699,16 +733,13 @@ def has_localhost_starter(self): def get_default_pool_path(cls): pathList = [] pathList.append("/homelocal/sicilia/lib/poolcontrollers") - pathList.append("/homelocal/sicilia/lib/python/site-packages/poolcontrollers") + pathList.append( + "/homelocal/sicilia/lib/python/site-packages/poolcontrollers") return pathList @classmethod def get_default_ms_path(cls): pathList = [] - pathList.append("/homelocal/sicilia/lib/python/site-packages/macroserver/macros") + pathList.append( + "/homelocal/sicilia/lib/python/site-packages/macroserver/macros") return pathList - - - - - diff --git a/src/sardana/taurus/core/tango/sardana/test/__init__.py b/src/sardana/taurus/core/tango/sardana/test/__init__.py index 2fff56e819..fed42ac10f 100755 --- a/src/sardana/taurus/core/tango/sardana/test/__init__.py +++ b/src/sardana/taurus/core/tango/sardana/test/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/core/tango/sardana/test/paramdef.py b/src/sardana/taurus/core/tango/sardana/test/paramdef.py index 77b81191a3..7a7e420e67 100755 --- a/src/sardana/taurus/core/tango/sardana/test/paramdef.py +++ b/src/sardana/taurus/core/tango/sardana/test/paramdef.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -38,7 +38,7 @@ 'default_value': 100 } ]} - ] +] # pt5 like parameter definition, using default values. @@ -49,11 +49,11 @@ {'name': 'float_list', 'default_value': None, 'type': [ - {'name': 'float', - 'default_value': 100 - } - ]} - ] + {'name': 'float', + 'default_value': 100 + } + ]} +] # pt7 like parameter definition, using default values. @@ -61,14 +61,14 @@ {'name': 'motor_pos_list', 'default_value': ["mot01", 50], 'type': [ - {'name': 'motor', - 'default_value': "mot99" - }, - {'name': 'pos', - 'default_value': 100 - } - ]} - ] + {'name': 'motor', + 'default_value': "mot99" + }, + {'name': 'pos', + 'default_value': 100 + } + ]} +] # pt10 like parameter definition, using default values. @@ -76,14 +76,14 @@ {'name': 'float_list', 'default_value': None, 'type': [ - {'name': 'float', - 'default_value': 100 - }] + {'name': 'float', + 'default_value': 100 + }] }, {'name': 'motor', 'default_value': "mot99" } - ] +] # pt12 like parameter definition, using default values. @@ -91,18 +91,18 @@ {'name': 'numb_list', 'default_value': None, 'type': [ - {'name': 'float', - 'default_value': 100 - }] + {'name': 'float', + 'default_value': 100 + }] }, {'name': 'motors_list', 'default_value': None, 'type': [ - {'name': 'motor', - 'default_value': 'mot99' - }] + {'name': 'motor', + 'default_value': 'mot99' + }] } - ] +] # pt13 like parameter definition, using default values. @@ -113,7 +113,7 @@ {'name': 'motor_list', 'default_value': None, 'type': [{'name': 'motor', - 'default_value': 'mot99'}] + 'default_value': 'mot99'}] }] }] @@ -126,10 +126,9 @@ {'name': 'motor_list', 'default_value': None, 'type': [{'name': 'motor', - 'default_value': 'mot99'}] + 'default_value': 'mot99'}] }, {'name': 'numb', 'default_value': 100} ] }] - diff --git a/src/sardana/taurus/core/tango/sardana/test/test_macro.py b/src/sardana/taurus/core/tango/sardana/test/test_macro.py index 5d78708a62..65ba237852 100755 --- a/src/sardana/taurus/core/tango/sardana/test/test_macro.py +++ b/src/sardana/taurus/core/tango/sardana/test/test_macro.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -41,6 +41,8 @@ pt14d_param_def) # TODO: Use unittest.mock instead of this fake class. from sardana.macroserver.mstypemanager import TypeManager + + class FakeMacroServer(object): name = "FakeMacroServer" @@ -50,7 +52,7 @@ class FakeMacroServer(object): # TODO: Move the parameter definition to res/paramdef.py module pt8_params_def = [ { - "name" : "m_p_pair", + "name": "m_p_pair", "type": [ { "name": "motor", @@ -74,7 +76,7 @@ class FakeMacroServer(object): # pt8_xml = \ -''' + ''' @@ -87,6 +89,7 @@ class FakeMacroServer(object): ''' + @insertTest(helper_name='verifyXML', macro_name="pt8", param_def=pt8_params_def, param_value=pt8_params_value, expected_xml_rep=pt8_xml) class MacroNodeTestCase(unittest.TestCase): @@ -99,7 +102,7 @@ def _validateXML(self, macronode_xml, expected_xml): expected_str = etree.tostring(expected_xml) macronode_str = etree.tostring(macronode_xml, pretty_print=True) msg = "XML encodings are not equal" - # TODO: check why macronode_str has an extra whitespace charactger + # TODO: check why macronode_str has an extra whitespace charactger # at the end. strips should not be necessary self.assertEquals(expected_str.strip(), macronode_str.strip(), msg) @@ -123,7 +126,6 @@ def verifyXML(self, macro_name, param_def, param_value, expected_xml_rep): self._validateXML(macronode_xml, expected_xml) - #### Testing a list of elements (floats) #### @insertTest(helper_name='verifyEncoding', param_def=pt3d_param_def, @@ -140,10 +142,8 @@ def verifyXML(self, macro_name, param_def, param_value, expected_xml_rep): macro_params=[[[], [], []]], expected_params_list=[["100", "100", "100"]] ) - #### Testing one element (moveable) followed by a #### ############ list of elements (floats). ############## - @insertTest(helper_name='verifyEncoding', param_def=pt5d_param_def, macro_params=["mot01", ["1", "3", "15"]], @@ -164,7 +164,6 @@ def verifyXML(self, macro_name, param_def, param_value, expected_xml_rep): macro_params=[[], ["1", [], "15"]], expected_params_list=["mot99", ["1", "100", "15"]] ) - #### Testing a list of pairs of elements (moveable, float). #### @insertTest(helper_name='verifyEncoding', param_def=pt7d_param_def, @@ -203,15 +202,14 @@ def verifyXML(self, macro_name, param_def, param_value, expected_xml_rep): expected_params_list=[[["mot01", "0"], ["mot99", "100"], ["mot03", "100"]]] ) -## Testing the outer default parameters for the whole repetition. -## This test is commented because this option is not functional at the moment. -## See ticket #427 referring to this bug. +# Testing the outer default parameters for the whole repetition. +# This test is commented because this option is not functional at the moment. +# See ticket #427 referring to this bug. #@insertTest(helper_name='verifyEncoding', # param_def=pt7d_param_def, # macro_params=[[[]]], # expected_params_list=[[['mot01', "50"]]], # ) - #### Testing list of elements (moveables) followed by a #### ################# single parameter (float). ################ @insertTest(helper_name='verifyEncoding', @@ -234,7 +232,6 @@ def verifyXML(self, macro_name, param_def, param_value, expected_xml_rep): macro_params=[["1", [], "15"], []], expected_params_list=[["1", "100", "15"], "mot99"], ) - #### Testing lists of elements (floats), followed by another list of #### ######################### elements (moveables). ######################### @insertTest(helper_name='verifyEncoding', @@ -247,17 +244,15 @@ def verifyXML(self, macro_name, param_def, param_value, expected_xml_rep): macro_params=[["1", [], "4"], [[], "mot2"]], expected_params_list=[["1", "100", "4"], ["mot99", "mot2"]] ) - -########################### Testing nested paramRepeats ######################## -############## Groups of motors, where each group is a motor list ############## +########################### Testing nested paramRepeats ################## +############## Groups of motors, where each group is a motor list ######## @insertTest(helper_name='verifyEncoding', param_def=pt13d_param_def, macro_params=[[["mot2", "mot3"], ["mot4", "mot5", "mot6"]]], expected_params_list=[[["mot2", "mot3"], ["mot4", "mot5", "mot6"]]] ) - -########################### Testing nested paramRepeats ######################## -## Groups of motors, where each group is a motor list followed by a number ##### +########################### Testing nested paramRepeats ################## +## Groups of motors, where each group is a motor list followed by a number @insertTest(helper_name='verifyEncoding', param_def=pt14d_param_def, macro_params=[[[["mot2", "mot3"], 4], @@ -265,7 +260,6 @@ def verifyXML(self, macro_name, param_def, param_value, expected_xml_rep): expected_params_list=[[[["mot2", "mot3"], 4], [["mot4", "mot5", "mot6"], 5]]] ) - class ParamsTestCase(unittest.TestCase): def verifyEncoding(self, param_def, macro_params, expected_params_list): @@ -292,7 +286,6 @@ def verifyEncoding(self, param_def, macro_params, expected_params_list): self.assertEqual(output_params_list, expected_params_list, msg) - class DuplicateTestCase(unittest.TestCase): """ @@ -303,7 +296,7 @@ def testDuplication(self): """ Helper to verify the correct duplication of a RepeatNode. Duplication of parameters. - + ..todo:: To be more unit test the use of MacroNode class should be avoided. Use of RepeatParamNode and its children should be enough. """ @@ -340,13 +333,13 @@ def testDuplication(self): self.assertEqual(num_final_nodes, expected_number_of_nodes, msg) for i in range(expected_number_of_nodes): - node_num = i+1 + node_num = i + 1 expected_name = '#' + str(node_num) new_node_name = node.child(0).child(i).name() msg = ("Name of node %d is not correct\n" "expected name: %s \n" "received name: %s" % (node_num, - expected_name, - new_node_name)) + expected_name, + new_node_name)) self.assertEqual(new_node_name, expected_name, msg) diff --git a/src/sardana/taurus/qt/__init__.py b/src/sardana/taurus/qt/__init__.py index ca50553e78..01148f6839 100644 --- a/src/sardana/taurus/qt/__init__.py +++ b/src/sardana/taurus/qt/__init__.py @@ -2,25 +2,25 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## -"""""" \ No newline at end of file +"""""" diff --git a/src/sardana/taurus/qt/qtcore/__init__.py b/src/sardana/taurus/qt/qtcore/__init__.py index ca50553e78..01148f6839 100644 --- a/src/sardana/taurus/qt/qtcore/__init__.py +++ b/src/sardana/taurus/qt/qtcore/__init__.py @@ -2,25 +2,25 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## -"""""" \ No newline at end of file +"""""" diff --git a/src/sardana/taurus/qt/qtcore/tango/__init__.py b/src/sardana/taurus/qt/qtcore/tango/__init__.py index ca50553e78..01148f6839 100644 --- a/src/sardana/taurus/qt/qtcore/tango/__init__.py +++ b/src/sardana/taurus/qt/qtcore/tango/__init__.py @@ -2,25 +2,25 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## -"""""" \ No newline at end of file +"""""" diff --git a/src/sardana/taurus/qt/qtcore/tango/sardana/__init__.py b/src/sardana/taurus/qt/qtcore/tango/sardana/__init__.py index dea81f3fda..5fe1959e5e 100644 --- a/src/sardana/taurus/qt/qtcore/tango/sardana/__init__.py +++ b/src/sardana/taurus/qt/qtcore/tango/sardana/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtcore/tango/sardana/macroserver.py b/src/sardana/taurus/qt/qtcore/tango/sardana/macroserver.py index fbcb0bba3e..5907fa046b 100644 --- a/src/sardana/taurus/qt/qtcore/tango/sardana/macroserver.py +++ b/src/sardana/taurus/qt/qtcore/tango/sardana/macroserver.py @@ -2,30 +2,31 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """MacroServer extension for taurus Qt""" -__all__ = ["QDoor", "QMacroServer", "MacroServerMessageErrorHandler", "registerExtensions"] +__all__ = ["QDoor", "QMacroServer", + "MacroServerMessageErrorHandler", "registerExtensions"] from taurus.core.taurusbasetypes import TaurusEventType from taurus.external.qt import Qt @@ -37,8 +38,9 @@ class QDoor(BaseDoor, Qt.QObject): - __pyqtSignals__ = ["resultUpdated", "recordDataUpdated", "macroStatusUpdated"] - __pyqtSignals__ += [ "%sUpdated" % l.lower() for l in BaseDoor.log_streams ] + __pyqtSignals__ = ["resultUpdated", + "recordDataUpdated", "macroStatusUpdated"] + __pyqtSignals__ += ["%sUpdated" % l.lower() for l in BaseDoor.log_streams] # TODO: For Taurus 4 compatibility try: # sometimes we emit None hence the type is object @@ -66,7 +68,8 @@ def resultReceived(self, log_name, result): return res def recordDataReceived(self, s, t, v): - if t not in CHANGE_EVTS: return + if t not in CHANGE_EVTS: + return res = BaseDoor.recordDataReceived(self, s, t, v) self.emit(Qt.SIGNAL("recordDataUpdated"), res) # TODO: For Taurus 4 compatibility @@ -80,7 +83,8 @@ def macroStatusReceived(self, s, t, v): macro = None else: macro = self.getRunningMacro() - if macro is None: return + if macro is None: + return self.emit(Qt.SIGNAL("macroStatusUpdated"), (macro, res)) # TODO: For Taurus 4 compatibility if hasattr(self, "macroStatusUpdated"): @@ -152,12 +156,13 @@ def on_environment_changed(self, s, t, v): from taurus.qt.qtgui.panel import TaurusMessageErrorHandler + class MacroServerMessageErrorHandler(TaurusMessageErrorHandler): def setError(self, err_type=None, err_value=None, err_traceback=None): """Translates the given error object into an HTML string and places it in the message panel - + :param error: an error object (typically an exception object) :type error: object""" @@ -182,7 +187,8 @@ def setError(self, err_type=None, err_value=None, err_traceback=None): html += "
%s
" % exc_info else: formatter = pygments.formatters.HtmlFormatter() - html += pygments.highlight(exc_info, pygments.lexers.PythonTracebackLexer(), formatter) + html += pygments.highlight(exc_info, + pygments.lexers.PythonTracebackLexer(), formatter) html += "" msgbox.setOriginHtml(html) @@ -201,4 +207,5 @@ def registerExtensions(): MacroRunException = sardana.taurus.core.tango.sardana.macro.MacroRunException TaurusMessagePanel = taurus.qt.qtgui.panel.TaurusMessagePanel - TaurusMessagePanel.registerErrorHandler(MacroRunException, MacroServerMessageErrorHandler) + TaurusMessagePanel.registerErrorHandler( + MacroRunException, MacroServerMessageErrorHandler) diff --git a/src/sardana/taurus/qt/qtcore/tango/sardana/model.py b/src/sardana/taurus/qt/qtcore/tango/sardana/model.py index 376f44ee1a..0e3a529db0 100644 --- a/src/sardana/taurus/qt/qtcore/tango/sardana/model.py +++ b/src/sardana/taurus/qt/qtcore/tango/sardana/model.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -53,28 +53,30 @@ _MOD, _CLS, _FNC, _TNG = ":/python-module.png", ":/class.png", ":/function.png", ":/tango.png" TYPE_MAP = { - "ControllerLibrary" : ("Controller libraries", _MOD, "Controller library",), - "ControllerClass" : ("Controller classes", _CLS, "Controller class",), - "Controller" : ("Controllers", _TNG, "Controller",), - "Motor" : ("Motors", _TNG, "Motor",), - "PseudoMotor" : ("Pseudo motors", _TNG, "Pseudo Motor",), - "CTExpChannel" : ("Counter/Timers", _TNG, "Counter/Timer experiment channel",), - "CounterTimer" : ("Counter/Timers", _TNG, "Counter/Timer experiment channel",), - "ZeroDExpChannel" : ("0D channels", _TNG, "0D experiment channel",), - "OneDExpChannel" : ("1D channels", _TNG, "1D experiment channel",), - "TwoDExpChannel" : ("2D channels", _TNG, "2D experiment channel",), - "MotorGroup" : ("Motor groups", _TNG, "Motor group",), - "MeasurementGroup" : ("Measurement groups", _TNG, "Measurement group",), - "CommunicationChannel" : ("Communication channels", _TNG, "Communication channel",), - "MacroLibrary" : ("Macro libraries", _MOD, "Macro library",), - "MacroClass" : ("Macro classes", _CLS, "Macro class",), - "Instrument" : ("Instruments", _TNG, "Instrument",), - "MacroFunction" : ("Macro functions", _FNC, "Macro function",), + "ControllerLibrary": ("Controller libraries", _MOD, "Controller library",), + "ControllerClass": ("Controller classes", _CLS, "Controller class",), + "Controller": ("Controllers", _TNG, "Controller",), + "Motor": ("Motors", _TNG, "Motor",), + "PseudoMotor": ("Pseudo motors", _TNG, "Pseudo Motor",), + "CTExpChannel": ("Counter/Timers", _TNG, "Counter/Timer experiment channel",), + "CounterTimer": ("Counter/Timers", _TNG, "Counter/Timer experiment channel",), + "ZeroDExpChannel": ("0D channels", _TNG, "0D experiment channel",), + "OneDExpChannel": ("1D channels", _TNG, "1D experiment channel",), + "TwoDExpChannel": ("2D channels", _TNG, "2D experiment channel",), + "MotorGroup": ("Motor groups", _TNG, "Motor group",), + "MeasurementGroup": ("Measurement groups", _TNG, "Measurement group",), + "CommunicationChannel": ("Communication channels", _TNG, "Communication channel",), + "MacroLibrary": ("Macro libraries", _MOD, "Macro library",), + "MacroClass": ("Macro classes", _CLS, "Macro class",), + "Instrument": ("Instruments", _TNG, "Instrument",), + "MacroFunction": ("Macro functions", _FNC, "Macro function",), } + def getElementTypeLabel(t): return TYPE_MAP.get(t, (t,))[0] + def getElementTypeIcon(t): import taurus.qt.qtgui.resource try: @@ -82,9 +84,11 @@ def getElementTypeIcon(t): except: return None + def getElementTypeSize(t): return Qt.QSize(200, 24) + def getElementTypeToolTip(t): return TYPE_MAP.get(t, (None, None, 'no information'))[2] @@ -94,7 +98,7 @@ class SardanaBaseTreeItem(TaurusBaseTreeItem): def data(self, index): """Returns the data of this node for the given index - + :return: (object) the data for the given index """ if index.column() > 0: @@ -104,10 +108,10 @@ def data(self, index): def role(self): """Returns the prefered role for the item. This implementation returns taurus.core.taurusbasetypes.TaurusElementType.Unknown - + This method should be able to return any kind of python object as long as the model that is used is compatible. - + :return: the role in form of element type""" return 'type' @@ -221,7 +225,8 @@ def mimeData(self, indexes): ret = Qt.QMimeData() data = [] for index in indexes: - if not index.isValid(): continue + if not index.isValid(): + continue tree_item = index.internalPointer() mime_data_item = tree_item.mimeData(index) if mime_data_item is None: @@ -401,7 +406,7 @@ def roleIcon(self, role): return ":/tango.png" # return getElementTypeIcon(role) - #def columnIcon(self, column): + # def columnIcon(self, column): # return self.roleIcon(self.role(column)) def roleToolTip(self, role): @@ -413,7 +418,7 @@ def roleToolTip(self, role): elif role == cr[2]: return "Environment value data type" - #def columnToolTip(self, column): + # def columnToolTip(self, column): # return self.roleToolTip(self.role(column)) def roleSize(self, role): @@ -431,7 +436,8 @@ def mimeData(self, indexes): ret = Qt.QMimeData() data = [] for index in indexes: - if not index.isValid(): continue + if not index.isValid(): + continue tree_item = index.internalPointer() mime_data_item = tree_item.mimeData(index) if mime_data_item is None: diff --git a/src/sardana/taurus/qt/qtcore/tango/sardana/pool.py b/src/sardana/taurus/qt/qtcore/tango/sardana/pool.py index f53bab1d9a..9b0ca17fc4 100644 --- a/src/sardana/taurus/qt/qtcore/tango/sardana/pool.py +++ b/src/sardana/taurus/qt/qtcore/tango/sardana/pool.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -87,7 +87,7 @@ def registerExtensions(): """Registers the pool extensions in the :class:`taurus.core.tango.TangoFactory`""" import taurus #import sardana.taurus.core.tango.sardana.pool - #sardana.taurus.core.tango.sardana.pool.registerExtensions() + # sardana.taurus.core.tango.sardana.pool.registerExtensions() factory = taurus.Factory() #factory.registerDeviceClass('Pool', QPool) factory.registerDeviceClass('MeasurementGroup', QMeasurementGroup) diff --git a/src/sardana/taurus/qt/qtgui/__init__.py b/src/sardana/taurus/qt/qtgui/__init__.py index ca50553e78..01148f6839 100644 --- a/src/sardana/taurus/qt/qtgui/__init__.py +++ b/src/sardana/taurus/qt/qtgui/__init__.py @@ -2,25 +2,25 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## -"""""" \ No newline at end of file +"""""" diff --git a/src/sardana/taurus/qt/qtgui/extra_hkl/__init__.py b/src/sardana/taurus/qt/qtgui/extra_hkl/__init__.py index 051b0298f8..c8cc95e91b 100644 --- a/src/sardana/taurus/qt/qtgui/extra_hkl/__init__.py +++ b/src/sardana/taurus/qt/qtgui/extra_hkl/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_hkl/computeu.py b/src/sardana/taurus/qt/qtgui/extra_hkl/computeu.py index 20d13e5099..a3bd44faeb 100644 --- a/src/sardana/taurus/qt/qtgui/extra_hkl/computeu.py +++ b/src/sardana/taurus/qt/qtgui/extra_hkl/computeu.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_hkl/diffractometeralignment.py b/src/sardana/taurus/qt/qtgui/extra_hkl/diffractometeralignment.py index e0e7ba4b06..b00a837f5a 100644 --- a/src/sardana/taurus/qt/qtgui/extra_hkl/diffractometeralignment.py +++ b/src/sardana/taurus/qt/qtgui/extra_hkl/diffractometeralignment.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -366,7 +366,7 @@ def main(): parser.set_description(desc) app = taurus.qt.qtgui.application.TaurusApplication(cmd_line_parser=parser, - app_version=sardana.Release.version) + app_version=sardana.Release.version) app.setApplicationName("diffractometeralignment") args = app.get_command_line_args() if len(args) < 1: diff --git a/src/sardana/taurus/qt/qtgui/extra_hkl/displayscanangles.py b/src/sardana/taurus/qt/qtgui/extra_hkl/displayscanangles.py index 860f7e68b9..8bbb738595 100644 --- a/src/sardana/taurus/qt/qtgui/extra_hkl/displayscanangles.py +++ b/src/sardana/taurus/qt/qtgui/extra_hkl/displayscanangles.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_hkl/hklscan.py b/src/sardana/taurus/qt/qtgui/extra_hkl/hklscan.py index 7b74e96473..48ce7dc163 100644 --- a/src/sardana/taurus/qt/qtgui/extra_hkl/hklscan.py +++ b/src/sardana/taurus/qt/qtgui/extra_hkl/hklscan.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -322,7 +322,7 @@ def display_angles(self): taurusValueAngle[i].setObjectName(tva_name) taurusValueAngle[i].setValue( "... No angle solution for hkl values ...") - # TODO: not all dimensions (H & K & L) are obligatory. One could try + # TODO: not all dimensions (H & K & L) are obligatory. One could try # to display angles of just 1 or 2 dimensional scan. if nb_points == -1: nb_points = 0 @@ -364,7 +364,7 @@ def main(): parser.set_description("a taurus application for performing hkl scans") app = taurus.qt.qtgui.application.TaurusApplication(cmd_line_parser=parser, - app_version=sardana.Release.version) + app_version=sardana.Release.version) app.setApplicationName("hklscan") args = app.get_command_line_args() if len(args) < 1: diff --git a/src/sardana/taurus/qt/qtgui/extra_hkl/reflectionseditor.py b/src/sardana/taurus/qt/qtgui/extra_hkl/reflectionseditor.py index cbfa37d4b6..66904ef2c6 100644 --- a/src/sardana/taurus/qt/qtgui/extra_hkl/reflectionseditor.py +++ b/src/sardana/taurus/qt/qtgui/extra_hkl/reflectionseditor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_hkl/reflectionslist.py b/src/sardana/taurus/qt/qtgui/extra_hkl/reflectionslist.py index 8463e7d542..4f487b29ee 100644 --- a/src/sardana/taurus/qt/qtgui/extra_hkl/reflectionslist.py +++ b/src/sardana/taurus/qt/qtgui/extra_hkl/reflectionslist.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_hkl/selectsignal.py b/src/sardana/taurus/qt/qtgui/extra_hkl/selectsignal.py index 76cb978345..42a3db81e1 100644 --- a/src/sardana/taurus/qt/qtgui/extra_hkl/selectsignal.py +++ b/src/sardana/taurus/qt/qtgui/extra_hkl/selectsignal.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -40,6 +40,7 @@ from sardana.taurus.core.tango.sardana.macroserver import registerExtensions + class SignalComboBox(Qt.QComboBox, TaurusBaseWidget): """ComboBox representing list of possible signals""" @@ -73,7 +74,7 @@ def __init__(self, parent=None, designMode=False): self.doorName = None self.door_device = None - + registerExtensions() @classmethod diff --git a/src/sardana/taurus/qt/qtgui/extra_hkl/ubmatrix.py b/src/sardana/taurus/qt/qtgui/extra_hkl/ubmatrix.py index 08e6e85800..6f05fda557 100644 --- a/src/sardana/taurus/qt/qtgui/extra_hkl/ubmatrix.py +++ b/src/sardana/taurus/qt/qtgui/extra_hkl/ubmatrix.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -47,6 +47,7 @@ global flag_update flag_update = 0 + class PrivateComboBox(Qt.QComboBox, TaurusBaseWidget): """ComboBox""" @@ -64,6 +65,7 @@ def loadItems(self, items): if crys not in all_items: self.addItem(crys) + @UILoadable(with_ui="_ui") class UBMatrixBase(TaurusWidget): @@ -104,7 +106,7 @@ def setModel(self, model): self.device = taurus.Device(model) self.update_values() - + uxmodel = model + "/ux" self._ui.taurusuxvalue.setModel(uxmodel) self._ui.taurusuxeditvalue.setModel(uxmodel) @@ -183,8 +185,7 @@ def setModel(self, model): self.connect(self.crystalscombobox, Qt.SIGNAL( "currentIndexChanged(QString)"), self.onCrystalChanged) - - + def onEngineChanged(self, enginename): self.device.write_attribute("engine", str(enginename)) @@ -195,7 +196,6 @@ def onCrystalChanged(self, crystalname): if str(crystalname) != "": self.device.write_attribute("crystal", str(crystalname)) - def update_values(self): ub_values = self.device.ubmatrix self._ui.taurusub11value.setValue(ub_values[0][0]) @@ -210,7 +210,8 @@ def update_values(self): global flag_update if flag_update: - all_items = [self.crystalscombobox.itemText(i) for i in range(self.crystalscombobox.count())] + all_items = [self.crystalscombobox.itemText( + i) for i in range(self.crystalscombobox.count())] for crys in self.device.crystallist: if crys not in all_items: self.crystalscombobox.addItem(crys) @@ -218,13 +219,13 @@ def update_values(self): if self.crystalscombobox.itemText(i) not in self.device.crystallist: self.crystalscombobox.removeItem(i) flag_update = 1 - + def compute_ub(self): index = [0, 1] self.device.write_attribute("computeub", index) self.update_values() - + def reflections_list_window(self): reflections = self.device.reflectionlist @@ -461,6 +462,7 @@ def add_select_crystal(self): def affine(self): self.device.write_attribute("affinecrystal", 1) + def main(): parser = taurus.core.util.argparse.get_taurus_parser() @@ -469,7 +471,7 @@ def main(): "a taurus application for setting diffractometer parameters: ubmatrix, lattice, reflections, ...") app = taurus.qt.qtgui.application.TaurusApplication(cmd_line_parser=parser, - app_version=sardana.Release.version) + app_version=sardana.Release.version) app.setApplicationName("ubmatrix") args = app.get_command_line_args() if len(args) < 1: diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/__init__.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/__init__.py index cea9d00bf3..fb4c17ae97 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/__init__.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/common.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/common.py index 133e83cf87..b32bc5fb30 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/common.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/common.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -37,6 +37,7 @@ def str2bool(text): return text in ("True", "1") + def standardPlotablesFilter(column_desc_dict): """This is a standard plotables filter emitted with "plotablesFilter" signal. Its purpose is to filterout point_nr columnf from scanline""" @@ -75,13 +76,13 @@ def getElementType(self): def resetElementType(self): self._elementType = MSAttrListComboBox._elementType - elementType = Qt.pyqtProperty("QString", getElementType, setElementType, resetElementType) + elementType = Qt.pyqtProperty( + "QString", getElementType, setElementType, resetElementType) class MacroComboBox(Qt.QComboBox, TaurusBaseWidget): """ComboBox representing list of macros""" - def __init__(self, parent=None): name = self.__class__.__name__ self.call__init__wo_kw(Qt.QComboBox, parent) @@ -106,11 +107,12 @@ def onMacrosUpdated(self): def __loadMacroNames(self): self.clear() ms = self.getModelObj() - if ms == None: return + if ms == None: + return macros = ms.getElementsWithInterface('MacroCode') macroNames = [macro.name for macro in macros.values()] macroNames.sort() - macroNames.insert(0, '') #adding blank item + macroNames.insert(0, '') # adding blank item self.addItems(macroNames) self.updateStyle() @@ -128,13 +130,18 @@ def __init__(self, parent=None, initMacroServer=None, initDoor=None): Qt.QDialog.__init__(self, parent) self.initMacroServer = initMacroServer self.initDoor = initDoor - configureAction = Qt.QAction(getThemeIcon("folder-open"), "Change custom macro editors paths", self) - self.connect(configureAction, Qt.SIGNAL("triggered()"), self.onReloadMacroServers) + configureAction = Qt.QAction(getThemeIcon( + "folder-open"), "Change custom macro editors paths", self) + self.connect(configureAction, Qt.SIGNAL( + "triggered()"), self.onReloadMacroServers) configureAction.setToolTip("Change custom macro editors paths") configureAction.setShortcut("F11") - self.refreshMacroServersAction = Qt.QAction(getThemeIcon("view-refresh"), "Reload macroservers", self) - self.connect(self.refreshMacroServersAction, Qt.SIGNAL("triggered()"), self.onReloadMacroServers) - self.refreshMacroServersAction.setToolTip("This will reload list of all macroservers from Tango DB") + self.refreshMacroServersAction = Qt.QAction( + getThemeIcon("view-refresh"), "Reload macroservers", self) + self.connect(self.refreshMacroServersAction, Qt.SIGNAL( + "triggered()"), self.onReloadMacroServers) + self.refreshMacroServersAction.setToolTip( + "This will reload list of all macroservers from Tango DB") self.refreshMacroServersAction.setShortcut("F5") self.initComponents() @@ -145,13 +152,15 @@ def initComponents(self): ms_stateIcons = self.__retriveMacroServersFromDB() self.__fillMacroServerComboBox(ms_stateIcons, self.macroServerComboBox) refreshMacroServersButton = Qt.QToolButton() - refreshMacroServersButton.setDefaultAction(self.refreshMacroServersAction) + refreshMacroServersButton.setDefaultAction( + self.refreshMacroServersAction) doorLabel = Qt.QLabel("Door:", self) self.doorComboBox = TaurusAttrListComboBox(self) - self.doorComboBox.setModel(self.macroServerComboBox.currentText() + "/doorList") + self.doorComboBox.setModel( + self.macroServerComboBox.currentText() + "/doorList") self.buttonBox = Qt.QDialogButtonBox(Qt.QDialogButtonBox.Ok | - Qt.QDialogButtonBox.Cancel) + Qt.QDialogButtonBox.Cancel) gridLayout = Qt.QGridLayout() gridLayout.addWidget(macroServerLabel, 0, 0) gridLayout.addWidget(self.macroServerComboBox, 0, 1) @@ -164,15 +173,20 @@ def initComponents(self): self.layout().addWidget(self.buttonBox) self.adjustSize() - self.connect(self.buttonBox, Qt.SIGNAL("accepted()"), self, Qt.SLOT("accept()")) - self.connect(self.buttonBox, Qt.SIGNAL("rejected()"), self, Qt.SLOT("reject()")) - self.connect(self.macroServerComboBox, Qt.SIGNAL("currentIndexChanged(const QString&)"), self.onMacroServerComboBoxChanged) + self.connect(self.buttonBox, Qt.SIGNAL( + "accepted()"), self, Qt.SLOT("accept()")) + self.connect(self.buttonBox, Qt.SIGNAL( + "rejected()"), self, Qt.SLOT("reject()")) + self.connect(self.macroServerComboBox, Qt.SIGNAL( + "currentIndexChanged(const QString&)"), self.onMacroServerComboBoxChanged) self.selectMacroServer(self.initMacroServer) self.selectDoor(self.initDoor) def accept(self): - self.emit(Qt.SIGNAL("macroserverNameChanged"), str(self.macroServerComboBox.currentText())) - self.emit(Qt.SIGNAL("doorNameChanged"), str(self.doorComboBox.currentText())) + self.emit(Qt.SIGNAL("macroserverNameChanged"), str( + self.macroServerComboBox.currentText())) + self.emit(Qt.SIGNAL("doorNameChanged"), str( + self.doorComboBox.currentText())) Qt.QDialog.accept(self) def __retriveMacroServersFromDB(self): @@ -203,7 +217,8 @@ def onReloadMacroServers(self): def onMacroServerComboBoxChanged(self, macroServerName): self.doorComboBox.setModel(macroServerName + "/doorList") - self.doorComboBox.fireEvent(self.doorComboBox, taurus.core.taurusbasetypes.TaurusEventType.Change, self.doorComboBox.getModelValueObj()) #fake event + self.doorComboBox.fireEvent(self.doorComboBox, taurus.core.taurusbasetypes.TaurusEventType.Change, + self.doorComboBox.getModelValueObj()) # fake event def onMacroServerNameChanged(self, macroServerName): self.__selectMacroServer(macroServerName) @@ -236,6 +251,7 @@ def selectMacroServer(self, macroServerName): if index != -1: self.macroServerComboBox.setCurrentIndex(index) + class MacroExecutionWindow(TaurusMainWindow): def __init__(self, parent=None, designMode=False): @@ -245,7 +261,8 @@ def __init__(self, parent=None, designMode=False): self._doorName = "" self.registerConfigProperty("doorName", "setDoorName", "doorName") self._customMacroEditorPaths = "" - self.registerConfigProperty("customMacroEditorPaths", "setCustomMacroEditorPaths", "customMacroEditorPaths") + self.registerConfigProperty( + "customMacroEditorPaths", "setCustomMacroEditorPaths", "customMacroEditorPaths") self._qDoor = None self.setWindowIcon(getIcon(":/apps/preferences-system-session.svg")) toolBar = self.basicTaurusToolbar() @@ -279,9 +296,9 @@ def setCustomMacroEditorPaths(self, customMacroEditorPaths): def onCustomMacroEditorPaths(self): paths = str(Qt.QInputDialog.getText(self, - "Edition of custom macro editors paths", - "Paths:", Qt.QLineEdit.Normal, - str(self.customMacroEditorPaths()))[0]) + "Edition of custom macro editors paths", + "Paths:", Qt.QLineEdit.Normal, + str(self.customMacroEditorPaths()))[0]) self.setCustomMacroEditorPaths(paths) def initComponents(self): @@ -293,15 +310,19 @@ def setModel(self, model): self.setWindowTitle(Qt.QApplication.applicationName() + ": " + model) def createConfigureAction(self): - configureAction = Qt.QAction(getThemeIcon("preferences-system-session"), "Change configuration", self) - self.connect(configureAction, Qt.SIGNAL("triggered()"), self.changeConfiguration) + configureAction = Qt.QAction(getThemeIcon( + "preferences-system-session"), "Change configuration", self) + self.connect(configureAction, Qt.SIGNAL( + "triggered()"), self.changeConfiguration) configureAction.setToolTip("Configuring MacroServer and Door") configureAction.setShortcut("F10") return configureAction def createCustomMacroEditorPathsAction(self): - configureAction = Qt.QAction(getThemeIcon("folder-open"), "Change custom macro editors paths", self) - self.connect(configureAction, Qt.SIGNAL("triggered()"), self.onCustomMacroEditorPaths) + configureAction = Qt.QAction(getThemeIcon( + "folder-open"), "Change custom macro editors paths", self) + self.connect(configureAction, Qt.SIGNAL( + "triggered()"), self.onCustomMacroEditorPaths) configureAction.setToolTip("Change custom macro editors paths") configureAction.setShortcut("F11") return configureAction @@ -310,21 +331,24 @@ def changeConfiguration(self): """This method is used to change macroserver as a model of application. It shows dialog with list of all macroservers on tango host, if the user Cancel dialog it doesn't do anything.""" - dialog = TaurusMacroConfigurationDialog(self, self.modelName, self.doorName()) + dialog = TaurusMacroConfigurationDialog( + self, self.modelName, self.doorName()) if dialog.exec_(): self.setModel(str(dialog.macroServerComboBox.currentText())) - self.emit(Qt.SIGNAL("doorChanged"), str(dialog.doorComboBox.currentText())) + self.emit(Qt.SIGNAL("doorChanged"), str( + dialog.doorComboBox.currentText())) else: return def onShortMessage(self, msg): ''' Slot to be called when there is a new short message. Currently, the only action taken when there is a new message is to display it in the main window status bar. - + :param msg: (str) the short descriptive message to be handled ''' self.statusBar().showMessage(msg) + def test_macrocombobox(ms_name): mcb = MacroComboBox() mcb.setModel(ms_name) @@ -338,4 +362,3 @@ def test_macrocombobox(ms_name): ms_name = args[0] test_macrocombobox(ms_name) sys.exit(app.exec_()) - diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/dooroutput.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/dooroutput.py index 81056d1cbc..74529b0aa4 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/dooroutput.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/dooroutput.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -105,12 +105,14 @@ def contextMenuEvent(self, event): clearAction.setEnabled(False) Qt.QObject.connect(clearAction, Qt.SIGNAL("triggered()"), self.clear) - Qt.QObject.connect(self.stopAction, Qt.SIGNAL("toggled(bool)"), self.stopScrolling) + Qt.QObject.connect(self.stopAction, Qt.SIGNAL( + "toggled(bool)"), self.stopScrolling) menu.exec_(event.globalPos()) def stopScrolling(self, stop): self._isStopped = stop + class DoorDebug(Qt.QPlainTextEdit): """Widget used for displaying changes of door's Debug attribute.""" @@ -142,12 +144,14 @@ def contextMenuEvent(self, event): clearAction.setEnabled(False) Qt.QObject.connect(clearAction, Qt.SIGNAL("triggered()"), self.clear) - Qt.QObject.connect(self.stopAction, Qt.SIGNAL("toggled(bool)"), self.stopScrolling) + Qt.QObject.connect(self.stopAction, Qt.SIGNAL( + "toggled(bool)"), self.stopScrolling) menu.exec_(event.globalPos()) def stopScrolling(self, stop): self._isStopped = stop + class DoorResult(Qt.QPlainTextEdit): """Widget used for displaying changes of door's Result attribute.""" @@ -175,7 +179,6 @@ def contextMenuEvent(self, event): menu.exec_(event.globalPos()) - #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- # Door attributes listeners #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- @@ -195,7 +198,7 @@ def setDoorName(self, doorName): def eventReceived(self, src, type, value): if (type == taurus.core.taurusbasetypes.TaurusEventType.Error or - type == taurus.core.taurusbasetypes.TaurusEventType.Config): + type == taurus.core.taurusbasetypes.TaurusEventType.Config): return self.emit(Qt.SIGNAL('door%sChanged' % self.attrName), value.value) @@ -210,10 +213,13 @@ def eventReceived(self, src, type, value): doorOutput = DoorOutput() if len(args) == 1: door = taurus.Device(args[0]) - Qt.QObject.connect(door, Qt.SIGNAL("outputUpdated"), doorOutput.onDoorOutputChanged) - Qt.QObject.connect(door, Qt.SIGNAL("infoUpdated"), doorOutput.onDoorInfoChanged) - Qt.QObject.connect(door, Qt.SIGNAL("warningUpdated"), doorOutput.onDoorWarningChanged) - Qt.QObject.connect(door, Qt.SIGNAL("errorUpdated"), doorOutput.onDoorErrorChanged) + Qt.QObject.connect(door, Qt.SIGNAL("outputUpdated"), + doorOutput.onDoorOutputChanged) + Qt.QObject.connect(door, Qt.SIGNAL("infoUpdated"), + doorOutput.onDoorInfoChanged) + Qt.QObject.connect(door, Qt.SIGNAL("warningUpdated"), + doorOutput.onDoorWarningChanged) + Qt.QObject.connect(door, Qt.SIGNAL("errorUpdated"), + doorOutput.onDoorErrorChanged) doorOutput.show() sys.exit(app.exec_()) - diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/__init__.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/__init__.py index c0a7c5cfed..5d88d0fcce 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/__init__.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/favouriteseditor.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/favouriteseditor.py index 074171fd8f..493462255f 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/favouriteseditor.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/favouriteseditor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -33,13 +33,15 @@ from taurus.qt.qtcore.configuration import BaseConfigurableClass from model import MacrosListModel + class FavouritesMacrosEditor(TaurusWidget): __pyqtSignals__ = ("modelChanged(const QString &)",) def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.setObjectName(self.__class__.__name__) - self.registerConfigProperty("toXmlString", "fromXmlString", "favourites") + self.registerConfigProperty( + "toXmlString", "fromXmlString", "favourites") self.initComponents() def initComponents(self): @@ -71,7 +73,8 @@ def createActionBar(self): moveDownButton = Qt.QToolButton() moveDownButton.setDefaultAction(self.list.moveDownAction) layout.addWidget(moveDownButton) - spacerItem = Qt.QSpacerItem(0, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) + spacerItem = Qt.QSpacerItem( + 0, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) layout.addItem(spacerItem) return layout @@ -104,21 +107,32 @@ def __init__(self, parent): self.setSelectionMode(Qt.QListView.ExtendedSelection) - self.removeAction = Qt.QAction(Qt.QIcon(":/actions/list-remove.svg"), "Remove from favourites", self) - self.connect(self.removeAction, Qt.SIGNAL("triggered()"), self.removeMacros) - self.removeAction.setToolTip("Clicking this button will remov selected macros from favourites.") - - self.removeAllAction = Qt.QAction(Qt.QIcon(":/places/user-trash.svg"), "Remove all from favourites", self) - self.connect(self.removeAllAction, Qt.SIGNAL("triggered()"), self.removeAllMacros) - self.removeAllAction.setToolTip("Clicking this button will remove all macros from favourites.") - - self.moveUpAction = Qt.QAction(Qt.QIcon(":/actions/go-up.svg"), "Move up", self) + self.removeAction = Qt.QAction( + Qt.QIcon(":/actions/list-remove.svg"), "Remove from favourites", self) + self.connect(self.removeAction, Qt.SIGNAL( + "triggered()"), self.removeMacros) + self.removeAction.setToolTip( + "Clicking this button will remov selected macros from favourites.") + + self.removeAllAction = Qt.QAction( + Qt.QIcon(":/places/user-trash.svg"), "Remove all from favourites", self) + self.connect(self.removeAllAction, Qt.SIGNAL( + "triggered()"), self.removeAllMacros) + self.removeAllAction.setToolTip( + "Clicking this button will remove all macros from favourites.") + + self.moveUpAction = Qt.QAction( + Qt.QIcon(":/actions/go-up.svg"), "Move up", self) self.connect(self.moveUpAction, Qt.SIGNAL("triggered()"), self.upMacro) - self.moveUpAction.setToolTip("Clicking this button will move the macro up in the favourites hierarchy.") + self.moveUpAction.setToolTip( + "Clicking this button will move the macro up in the favourites hierarchy.") - self.moveDownAction = Qt.QAction(Qt.QIcon(":/actions/go-down.svg"), "Move up", self) - self.connect(self.moveDownAction, Qt.SIGNAL("triggered()"), self.downMacro) - self.moveDownAction.setToolTip("Clicking this button will move the macro down in the favourites hierarchy.") + self.moveDownAction = Qt.QAction( + Qt.QIcon(":/actions/go-down.svg"), "Move up", self) + self.connect(self.moveDownAction, Qt.SIGNAL( + "triggered()"), self.downMacro) + self.moveDownAction.setToolTip( + "Clicking this button will move the macro down in the favourites hierarchy.") self.disableActions() @@ -142,8 +156,10 @@ def selectionChanged(self, old, new): def isIndexSelected(self): if len(self.selectedIndexes()) > 0: self.removeAction.setEnabled(True) - self.moveUpAction.setEnabled(self.model().isUpRowAllowed(self.currentIndex())) - self.moveDownAction.setEnabled(self.model().isDownRowAllowed(self.currentIndex())) + self.moveUpAction.setEnabled( + self.model().isUpRowAllowed(self.currentIndex())) + self.moveDownAction.setEnabled( + self.model().isDownRowAllowed(self.currentIndex())) else: self.removeAction.setEnabled(False) self.moveUpAction.setEnabled(False) @@ -167,7 +183,8 @@ def insertMacro(self, macroNode): self.setCurrentIndex(idx) def removeMacros(self): - slist = sorted(self.selectedIndexes(), key=lambda index: index.row(), reverse=True) + slist = sorted(self.selectedIndexes(), + key=lambda index: index.row(), reverse=True) for index in slist: row = index.row() idx = self.model().removeRow(row) @@ -175,7 +192,8 @@ def removeMacros(self): def removeAllMacros(self): self.selectAll() - slist = sorted(self.selectedIndexes(), key=lambda index: index.row(), reverse=True) + slist = sorted(self.selectedIndexes(), + key=lambda index: index.row(), reverse=True) for index in slist: self.model().removeRow(index.row()) @@ -197,8 +215,10 @@ def fromXmlString(self, xmlString): def test(): - import sys, taurus, time - from taurus.qt.qtgui.application import TaurusApplication + import sys + import taurus + import time + from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication(sys.argv) diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/historyviewer.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/historyviewer.py index e89967a61f..aa065b080e 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/historyviewer.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/historyviewer.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -33,6 +33,7 @@ from taurus.qt.qtcore.configuration import BaseConfigurableClass from model import MacrosListModel + class HistoryMacrosViewer(TaurusWidget): __pyqtSignals__ = ("modelChanged(const QString &)",) @@ -50,7 +51,7 @@ def initComponents(self): self._model = MacrosListModel() self.list.setModel(self._model) -##### self.registerConfigDelegate(self.list) +# self.registerConfigDelegate(self.list) self.layout().addWidget(self.list) actionBar = self.createActionBar() @@ -62,21 +63,24 @@ def createActionBar(self): deleteAllButton = Qt.QToolButton() deleteAllButton.setDefaultAction(self.list.removeAllAction) layout.addWidget(deleteAllButton) - spacerItem = Qt.QSpacerItem(0, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) + spacerItem = Qt.QSpacerItem( + 0, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) layout.addItem(spacerItem) return layout def listElementUp(self): indexPos = self.list.currentIndex() if indexPos.isValid() and indexPos.row() >= 1: - self.list.setCurrentIndex(indexPos.sibling(indexPos.row() - 1, indexPos.column())) + self.list.setCurrentIndex(indexPos.sibling( + indexPos.row() - 1, indexPos.column())) else: self.selectFirstElement() def listElementDown(self): indexPos = self.list.currentIndex() if indexPos.isValid() and indexPos.row() < self._model.rowCount() - 1: - self.list.setCurrentIndex(indexPos.sibling(indexPos.row() + 1, indexPos.column())) + self.list.setCurrentIndex(indexPos.sibling( + indexPos.row() + 1, indexPos.column())) elif indexPos.row() == self._model.rowCount() - 1: return else: @@ -102,7 +106,6 @@ def selectFirstElement(self): self.list.removeAllAction.setEnabled(True) self.list.setCurrentIndex(self._model.index(0)) - @classmethod def getQtDesignerPluginInfo(cls): return None @@ -113,9 +116,12 @@ class HistoryMacrosList(Qt.QListView, BaseConfigurableClass): def __init__(self, parent): Qt.QListView.__init__(self, parent) self.setSelectionMode(Qt.QListView.SingleSelection) - self.removeAllAction = Qt.QAction(Qt.QIcon(":/places/user-trash.svg"), "Remove all from history", self) - self.connect(self.removeAllAction, Qt.SIGNAL("triggered()"), self.removeAllMacros) - self.removeAllAction.setToolTip("Clicking this button will remove all macros from history.") + self.removeAllAction = Qt.QAction( + Qt.QIcon(":/places/user-trash.svg"), "Remove all from history", self) + self.connect(self.removeAllAction, Qt.SIGNAL( + "triggered()"), self.removeAllMacros) + self.removeAllAction.setToolTip( + "Clicking this button will remove all macros from history.") self.removeAllAction.setEnabled(False) def currentChanged(self, current, previous): @@ -144,7 +150,8 @@ def insertMacro(self, macroNode): def removeAllMacros(self): self.selectAll() - slist = sorted(self.selectedIndexes(), key=lambda index: index.row(), reverse=True) + slist = sorted(self.selectedIndexes(), + key=lambda index: index.row(), reverse=True) for index in slist: self.model().removeRow(index.row()) self.removeAllAction.setEnabled(False) @@ -157,8 +164,10 @@ def fromXmlString(self, xmlString): def test(): - import sys, taurus, time - from taurus.qt.qtgui.application import TaurusApplication + import sys + import taurus + import time + from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication(sys.argv) diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/model.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/model.py index 0950c46451..b94f99b133 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/model.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/favouriteseditor/model.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/globals.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/globals.py index b69a8b449f..cd7848cb47 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/globals.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/globals.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrobutton.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrobutton.py index b7817c1ebd..cf7c698156 100755 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrobutton.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrobutton.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -59,13 +59,13 @@ def eventReceived(self, evt_src, evt_type, evt_value): door_state = evt_value.value self.emit(Qt.SIGNAL('doorStateChanged'), door_state) - + @UILoadable(with_ui='ui') class MacroButton(TaurusWidget): ''' A button to execute/pause/stop macros. The model must be a valid door. - + .. todo:: Not implemented but will be needed: set an icon - + .. todo:: It may be useful to have all the streams from qdoor available somehow (right-click?) ''' @@ -85,17 +85,17 @@ def __init__(self, parent=None, designMode=False): self.ui.progress.setValue(0) self.ui.button.setCheckable(True) - self.connect(self.ui.button, Qt.SIGNAL('clicked()'), + self.connect(self.ui.button, Qt.SIGNAL('clicked()'), self._onButtonClicked) def toggleProgress(self, visible): '''deprecated''' self.warning('toggleProgress is deprecated. Use showProgress') self.showProgress(visible) - + def showProgress(self, visible): '''Set whether the progress bar is shown - + :param visible: (bool) If True, the progress bar is shown. Otherwise it is hidden''' self.ui.progress.setVisible(visible) @@ -107,23 +107,32 @@ def setModel(self, model): ''' TaurusWidget.setModel(self, model) if self.door is not None: - self.disconnect(self.door, Qt.SIGNAL('macroStatusUpdated'), self._statusUpdated) - self.disconnect(self.door, Qt.SIGNAL('resultUpdated'), self._resultUpdated) + self.disconnect(self.door, Qt.SIGNAL( + 'macroStatusUpdated'), self._statusUpdated) + self.disconnect(self.door, Qt.SIGNAL( + 'resultUpdated'), self._resultUpdated) # disable management of Door Tango States - self.door.getAttribute('State').removeListener(self.door_state_listener) - self.disconnect(self.door_state_listener, Qt.SIGNAL('doorStateChanged'), self._doorStateChanged) + self.door.getAttribute('State').removeListener( + self.door_state_listener) + self.disconnect(self.door_state_listener, Qt.SIGNAL( + 'doorStateChanged'), self._doorStateChanged) self.door_state_listener = None - try: self.door = taurus.Device(model) - except: return + try: + self.door = taurus.Device(model) + except: + return - self.connect(self.door, Qt.SIGNAL('macroStatusUpdated'), self._statusUpdated) - self.connect(self.door, Qt.SIGNAL('resultUpdated'), self._resultUpdated) + self.connect(self.door, Qt.SIGNAL( + 'macroStatusUpdated'), self._statusUpdated) + self.connect(self.door, Qt.SIGNAL( + 'resultUpdated'), self._resultUpdated) # Manage Door Tango States self.door_state_listener = DoorStateListener() - self.connect(self.door_state_listener, Qt.SIGNAL('doorStateChanged'), self._doorStateChanged) + self.connect(self.door_state_listener, Qt.SIGNAL( + 'doorStateChanged'), self._doorStateChanged) self.door.getAttribute('State').addListener(self.door_state_listener) def _doorStateChanged(self, state): @@ -132,7 +141,8 @@ def _doorStateChanged(self, state): stylesheet = 'QFrame{border: 4px solid %s;}' % color self.ui.frame.setStyleSheet(stylesheet) - # In case state is not ON, and macro not triggered by the button, disable it + # In case state is not ON, and macro not triggered by the button, + # disable it door_available = True if state not in [PyTango.DevState.ON, PyTango.DevState.ALARM] and not self.ui.button.isChecked(): door_available = False @@ -140,7 +150,6 @@ def _doorStateChanged(self, state): self.ui.button.setEnabled(door_available) self.ui.progress.setEnabled(door_available) - def _statusUpdated(self, *args): '''slot called on status changes''' # SHOULD SEE THE DOCUMENTATION ABOUT THE ARGS AND ALSO THE STATUS STATE MACHINE @@ -155,7 +164,8 @@ def _statusUpdated(self, *args): self.running_macro = first_tuple[0] status_dict = first_tuple[1][0] - # KEYS RECEIVED FROM A 'SCAN' MACRO AND A 'TWICE' MACRO: IS IT GENERAL ?!?!?! + # KEYS RECEIVED FROM A 'SCAN' MACRO AND A 'TWICE' MACRO: IS IT GENERAL + # ?!?!?! macro_id = status_dict['id'] # if macro id is unknown ignoring this signal if macro_id is None: @@ -180,7 +190,8 @@ def _statusUpdated(self, *args): def _resultUpdated(self, *args): '''slot called on result changes''' # ARGS APPEAR TO BE EMPTY... SHOULD THEY CONTAIN THE RESULT ?!?!?! - # I have to rely on the 'macro object' received in the last status update + # I have to rely on the 'macro object' received in the last status + # update if self.running_macro is None: return result = self.running_macro.getResult() @@ -188,12 +199,12 @@ def _resultUpdated(self, *args): def setText(self, text): '''set the button text - + :param text: (str) text for the button ''' self.setButtonText(text) - def setButtonText(self, text): + def setButtonText(self, text): '''same as :meth:`setText` ''' # SHOULD ALSO BE POSSIBLE TO SET AN ICON @@ -201,39 +212,39 @@ def setButtonText(self, text): def setMacroName(self, name): '''set the name of the macro to be executed - + :param name: (str) text for the button ''' self.macro_name = str(name) - #update tooltip + # update tooltip self.setToolTip(self.macro_name + ' ' + ' '.join(self.macro_args)) def updateMacroArgument(self, index, value): '''change a given argument - + :param index: (int) positional index for this argument :param value: (str) value for this argument ''' - #make sure that the macro_args is at least as long as index + # make sure that the macro_args is at least as long as index while len(self.macro_args) < index + 1: self.macro_args.append('') - #update the given argument + # update the given argument if re.search('\s', value): value = '"{0}"'.format(value) self.macro_args[index] = str(value) - #update tooltip + # update tooltip self.setToolTip(self.macro_name + ' ' + ' '.join(self.macro_args)) - + def updateMacroArgumentFromSignal(self, index, obj, signal): '''deprecated''' msg = 'updateMacroArgumentFromSignal is deprecated. connectArgEditors' self.warning(msg) - self.connect(obj, signal, + self.connect(obj, signal, functools.partial(self.updateMacroArgument, index)) - + def connectArgEditors(self, signals): '''Associate signals to argument changes. - + :param signals: (seq) An ordered sequence of (`obj`, `sig`) tuples , where `obj` is a parameter editor object and `sig` is a signature for a signal emitted by `obj` which @@ -241,9 +252,9 @@ def connectArgEditors(self, signals): Each (`obj`, `sig`) tuple is associated to parameter corresponding to its position in the `signals` sequence. ''' - - for i,(obj,sig) in enumerate(signals): - self.connect(obj, Qt.SIGNAL(sig), + + for i, (obj, sig) in enumerate(signals): + self.connect(obj, Qt.SIGNAL(sig), functools.partial(self.updateMacroArgument, i)) def _onButtonClicked(self): @@ -278,13 +289,15 @@ def abort(self): self.door.PauseMacro() # Since this could be done by error (impatient users clicking more than once) # we provide a warning message that does not make the process too slow - # It may also be useful and 'ABORT' at TaurusApplication level (macros+motions+acquisitions) + # It may also be useful and 'ABORT' at TaurusApplication level + # (macros+motions+acquisitions) title = 'Aborting macro' message = 'The following macro is still running:\n\n' message += '%s %s\n\n' % (self.macro_name, ' '.join(self.macro_args)) message += 'Are you sure you want to abort?\n' buttons = Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel - ans = Qt.QMessageBox.warning(self, title, message, buttons, Qt.QMessageBox.Ok) + ans = Qt.QMessageBox.warning( + self, title, message, buttons, Qt.QMessageBox.Ok) if ans == Qt.QMessageBox.Ok: self.door.abort(synch=True) else: @@ -304,12 +317,13 @@ class MacroButtonAbortDoor(Qt.QPushButton, TaurusBaseWidget): '''Deprecated class. Instead use TaurusCommandButton. A button for aborting macros on a door ''' - #todo: why not inheriting from (TaurusBaseComponent, Qt.QPushButton)? + # todo: why not inheriting from (TaurusBaseComponent, Qt.QPushButton)? + def __init__(self, parent=None, designMode=False): name = self.__class__.__name__ self.call__init__wo_kw(Qt.QPushButton, parent) self.call__init__(TaurusBaseWidget, name, designMode=designMode) - self.warning('Deprecation warning: use TaurusCommandButton class ' +\ + self.warning('Deprecation warning: use TaurusCommandButton class ' + 'instead of MacroButtonAbortDoor') self.setText('Abort') @@ -356,8 +370,8 @@ def abort(self): sys.exit(1) door_name = args[0] - class TestWidget(Qt.QWidget): + def __init__(self, door, macro): Qt.QWidget.__init__(self) @@ -375,9 +389,9 @@ def update_result(self, result): def toggle_progress(self, toggle): visible = self.show_progress.isChecked() self.mb.toggleProgress(visible or toggle) - + def getMacroInfo(self, macro_name): - + door = taurus.Device(self.door_name) try: pars = door.macro_server.getMacroInfoObj(macro_name).parameters @@ -398,11 +412,11 @@ def getMacroInfo(self, macro_name): param_names.append(p['name']) default_values.append(p['default_value']) - self.macro_name = macro_name - return param_names, default_values + self.macro_name = macro_name + return param_names, default_values def clean_layout(self, layout): - + while layout.count(): child = layout.takeAt(0) if child.widget(): @@ -450,7 +464,8 @@ def create_layout(self, macro_name): self.w_bottom.layout().addWidget(mb_abort, 3, 1) # Toggle progressbar - Qt.QObject.connect(self.show_progress, Qt.SIGNAL('stateChanged(int)'), self.toggle_progress) + Qt.QObject.connect(self.show_progress, Qt.SIGNAL( + 'stateChanged(int)'), self.toggle_progress) # connect the argument editors signals = [(e, 'textChanged(QString)') for e in _argEditors] self.mb.connectArgEditors(signals) @@ -460,12 +475,17 @@ def create_layout(self, macro_name): self.layout().addWidget(self.w_bottom) # Update possible macro result - Qt.QObject.connect(self.mb, Qt.SIGNAL('resultUpdated'), self.update_result) - - Qt.QObject.connect(self.w_macro_name, Qt.SIGNAL('textEdited(QString)'), self.update_macro_name) - Qt.QObject.connect(self.w_macro_name, Qt.SIGNAL('editingFinished()'), self.update_layout) - Qt.QObject.connect(self.w_macro_name, Qt.SIGNAL('textChanged(QString)'), self.mb.setMacroName) - Qt.QObject.connect(self.w_macro_name, Qt.SIGNAL('textChanged(QString)'), self.mb.setButtonText) + Qt.QObject.connect(self.mb, Qt.SIGNAL( + 'resultUpdated'), self.update_result) + + Qt.QObject.connect(self.w_macro_name, Qt.SIGNAL( + 'textEdited(QString)'), self.update_macro_name) + Qt.QObject.connect(self.w_macro_name, Qt.SIGNAL( + 'editingFinished()'), self.update_layout) + Qt.QObject.connect(self.w_macro_name, Qt.SIGNAL( + 'textChanged(QString)'), self.mb.setMacroName) + Qt.QObject.connect(self.w_macro_name, Qt.SIGNAL( + 'textChanged(QString)'), self.mb.setButtonText) # Since everything is now connected, the parameters will be updated self.w_macro_name.setText(macro_name) diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrodescriptionviewer.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrodescriptionviewer.py index da50526705..c39c44a2b6 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrodescriptionviewer.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macrodescriptionviewer.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -68,16 +68,15 @@ def getFormatedToolTip(self, cache=True): """This method was overridden to get rid of the default tooltip of TaurusWidget""" return "" - model = Qt.pyqtProperty("QString", - TaurusBaseWidget.getModel, - TaurusBaseWidget.setModel, - TaurusBaseWidget.resetModel) + TaurusBaseWidget.getModel, + TaurusBaseWidget.setModel, + TaurusBaseWidget.resetModel) useParentModel = Qt.pyqtProperty("bool", - TaurusBaseWidget.getUseParentModel, - TaurusBaseWidget.setUseParentModel, - TaurusBaseWidget.resetUseParentModel) + TaurusBaseWidget.getUseParentModel, + TaurusBaseWidget.setUseParentModel, + TaurusBaseWidget.resetUseParentModel) def test(): @@ -97,5 +96,3 @@ def test(): if __name__ == "__main__": test() - - diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroeditor.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroeditor.py index 0ec20c26ef..85481add09 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroeditor.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroeditor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -53,49 +53,59 @@ def __init__(self, parent=None, designMode=False): self.newAction.setToolTip("Create new file") self.newAction.setShortcut("Ctrl+N") - self.openAction = Qt.QAction(getThemeIcon("document-open"), "Open", self) + self.openAction = Qt.QAction( + getThemeIcon("document-open"), "Open", self) self.connect(self.openAction, Qt.SIGNAL("triggered()"), self.openFile) self.openAction.setToolTip("Open existing file") self.openAction.setShortcut("Ctrl+O") - self.saveAction = Qt.QAction(getThemeIcon("document-save"), "Save", self) + self.saveAction = Qt.QAction( + getThemeIcon("document-save"), "Save", self) self.connect(self.saveAction, Qt.SIGNAL("triggered()"), self.saveFile) self.saveAction.setToolTip("Save document to disk") self.saveAction.setShortcut("Ctrl+S") - self.saveAsAction = Qt.QAction(getThemeIcon("document-save-as"), "Save as...", self) - self.connect(self.saveAsAction, Qt.SIGNAL("triggered()"), self.saveFile) + self.saveAsAction = Qt.QAction(getThemeIcon( + "document-save-as"), "Save as...", self) + self.connect(self.saveAsAction, Qt.SIGNAL( + "triggered()"), self.saveFile) self.saveAsAction.setToolTip("Save document under a new name") self.cutAction = Qt.QAction(getThemeIcon("edit-cut"), "Cut", self) self.connect(self.cutAction, Qt.SIGNAL("triggered()"), self.cut) - self.cutAction.setToolTip("Cut current selection's contents to the clipboard") + self.cutAction.setToolTip( + "Cut current selection's contents to the clipboard") self.cutAction.setShortcut("Ctrl+X") self.cutAction.setEnabled(False) self.copyAction = Qt.QAction(getThemeIcon("edit-copy"), "Copy", self) self.connect(self.copyAction, Qt.SIGNAL("triggered()"), self.copy) - self.copyAction.setToolTip("Copy current selection's contents to the clipboard") + self.copyAction.setToolTip( + "Copy current selection's contents to the clipboard") self.copyAction.setShortcut("Ctrl+C") self.copyAction.setEnabled(False) - self.pasteAction = Qt.QAction(getThemeIcon("edit-paste"), "Paste", self) + self.pasteAction = Qt.QAction( + getThemeIcon("edit-paste"), "Paste", self) self.connect(self.pasteAction, Qt.SIGNAL("triggered()"), self.paste) - self.pasteAction.setToolTip("Paste the clipboard's contents into the current selection") + self.pasteAction.setToolTip( + "Paste the clipboard's contents into the current selection") self.pasteAction.setShortcut("Ctrl+V") self.aboutAction = Qt.QAction("About", self) self.connect(self.aboutAction, Qt.SIGNAL("triggered()"), self.about) self.aboutAction.setToolTip("Show the application's About box") - self.connect(self.textEdit, Qt.SIGNAL("copyAvailable(bool)"), self.cutAction.setEnabled) - self.connect(self.textEdit, Qt.SIGNAL("copyAvailable(bool)"), self.copyAction.setEnabled) + self.connect(self.textEdit, Qt.SIGNAL( + "copyAvailable(bool)"), self.cutAction.setEnabled) + self.connect(self.textEdit, Qt.SIGNAL( + "copyAvailable(bool)"), self.copyAction.setEnabled) self.setCurrentFile("") def closeEvent(self, event): if self.maybeSave(): -# self.writeSettings() + # self.writeSettings() event.accept() else: event.ignore() @@ -124,7 +134,8 @@ def __saveAs(self): return self.__saveFile(self.fileName) def about(self): - Qt.QMessageBox.about(self, "About MacroEditor", "The MacroEditor by Zbigniew Reszela") + Qt.QMessageBox.about(self, "About MacroEditor", + "The MacroEditor by Zbigniew Reszela") def documentWasModified(self): self.setWindowModified(self.textEdit.isModified()) @@ -166,10 +177,10 @@ def createStatusBar(self): def maybeSave(self): if self.textEdit.isModified(): ret = Qt.QMessageBox.warning(self, "MacroEditor", - "The document has been modified\nDo you want to save your changes?", - Qt.QMessageBox.Yes | Qt.QMessageBox.Default, - Qt.QMessageBox.No, - Qt.QMessageBox.Cancel | Qt.QMessageBox.Escape) + "The document has been modified\nDo you want to save your changes?", + Qt.QMessageBox.Yes | Qt.QMessageBox.Default, + Qt.QMessageBox.No, + Qt.QMessageBox.Cancel | Qt.QMessageBox.Escape) if ret == Qt.QMessageBox.Yes: return self.save() elif ret == Qt.QMessageBox.Cancel: @@ -180,7 +191,8 @@ def loadFile(self, fileName): try: fileHandle = open(fileName, 'r') except IOError, e: - Qt.QMessageBox.warning(self, "MacroEditor", "Cannot read file %s:\n%s." % (fileName, e)) + Qt.QMessageBox.warning(self, "MacroEditor", + "Cannot read file %s:\n%s." % (fileName, e)) return False fileContents = fileHandle.read() Qt.QApplication.setOverrideCursor(Qt.Qt.WaitCursor) @@ -194,7 +206,8 @@ def __saveFile(self, fileName): try: file = open(fileName, 'w') except IOError, e: - Qt.QMessageBox.warning(self, "MacroEditor", "Cannot write file %s:\n%s." % (fileName, e)) + Qt.QMessageBox.warning( + self, "MacroEditor", "Cannot write file %s:\n%s." % (fileName, e)) return False Qt.QApplication.setOverrideCursor(Qt.Qt.WaitCursor) file.write(self.textEdit.text()) diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py index baa049427f..e07f29231a 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroexecutor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -53,12 +53,15 @@ class MacroProgressBar(Qt.QProgressBar): def __init__(self, parent=None): Qt.QProgressBar.__init__(self, parent) + class SpockCommandWidget(Qt.QLineEdit, TaurusBaseContainer): + def __init__(self, name, parent=None, designMode=False): - #self.newValue - is used as a flag to indicate whether a controlUp controlDown actions are used to iterate existing element or put new one - #self.disableEditMode - flag, used to disable edition, when user enters name of the macro which is not valid (not allowed to edit in the yellow line) + # self.newValue - is used as a flag to indicate whether a controlUp controlDown actions are used to iterate existing element or put new one + # self.disableEditMode - flag, used to disable edition, when user enters name of the macro which is not valid (not allowed to edit in the yellow line) # switches off validation - #disableSpockCommandUpdate - flag, it disables updates of the model when macro is edited by macroEditor + # disableSpockCommandUpdate - flag, it disables updates of the model + # when macro is edited by macroEditor Qt.QLineEdit.__init__(self, parent) TaurusBaseContainer.__init__(self, name, parent, designMode) @@ -75,7 +78,8 @@ def __init__(self, name, parent=None, designMode=False): self.setEnabled(False) self.setActions() - self.connect(self, Qt.SIGNAL("textChanged(const QString &)"), self.textChanged) + self.connect(self, Qt.SIGNAL( + "textChanged(const QString &)"), self.textChanged) self.connect(self, Qt.SIGNAL("returnPressed()"), self.returnPressed) def setActions(self): @@ -84,24 +88,29 @@ def setActions(self): self._ctrlDownAction = Qt.QAction("controlDownAction", self) self._ctrlUpAction = Qt.QAction("controlUpAction", self) - self._ctrlDownAction.setShortcut(Qt.QKeySequence(Qt.Qt.CTRL + Qt.Qt.Key_Down)) - self._ctrlUpAction.setShortcut(Qt.QKeySequence(Qt.Qt.CTRL + Qt.Qt.Key_Up)) + self._ctrlDownAction.setShortcut( + Qt.QKeySequence(Qt.Qt.CTRL + Qt.Qt.Key_Down)) + self._ctrlUpAction.setShortcut( + Qt.QKeySequence(Qt.Qt.CTRL + Qt.Qt.Key_Up)) self._downAction.setShortcuts([Qt.Qt.Key_Down]) self._upAction.setShortcuts([Qt.Qt.Key_Up]) - self._ctrlDownAction.setShortcutContext (Qt.Qt.WidgetShortcut) - self._ctrlUpAction.setShortcutContext (Qt.Qt.WidgetShortcut) - self._downAction.setShortcutContext (Qt.Qt.WidgetShortcut) - self._upAction.setShortcutContext (Qt.Qt.WidgetShortcut) + self._ctrlDownAction.setShortcutContext(Qt.Qt.WidgetShortcut) + self._ctrlUpAction.setShortcutContext(Qt.Qt.WidgetShortcut) + self._downAction.setShortcutContext(Qt.Qt.WidgetShortcut) + self._upAction.setShortcutContext(Qt.Qt.WidgetShortcut) self.addAction(self._ctrlDownAction) self.addAction(self._ctrlUpAction) self.addAction(self._downAction) self.addAction(self._upAction) - self.connect(self._downAction, Qt.SIGNAL("triggered()"), self.downAction) + self.connect(self._downAction, Qt.SIGNAL( + "triggered()"), self.downAction) self.connect(self._upAction, Qt.SIGNAL("triggered()"), self.upAction) - self.connect(self._ctrlDownAction, Qt.SIGNAL("triggered()"), self.controlDownAction) - self.connect(self._ctrlUpAction, Qt.SIGNAL("triggered()"), self.controlUpAction) + self.connect(self._ctrlDownAction, Qt.SIGNAL( + "triggered()"), self.controlDownAction) + self.connect(self._ctrlUpAction, Qt.SIGNAL( + "triggered()"), self.controlUpAction) def setCommand(self): command = self._model.toSpockCommand().strip() @@ -127,14 +136,17 @@ def setModel(self, model): self.disableEditMode = not enable self.setEnabled(enable) self._model = model - self.connect(self._model, Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), self.onDataChanged) + self.connect(self._model, Qt.SIGNAL( + "dataChanged(QModelIndex,QModelIndex)"), self.onDataChanged) self.connect(self._model, Qt.SIGNAL("modelReset()"), self.setCommand) def model(self): return self._model def getIndex(self, elementNumber=-1): - #Returns QModelIndex of the required element (number of single parameter). If the elementNumber == -1 next single parameter index is returned. + # Returns QModelIndex of the required element (number of single + # parameter). If the elementNumber == -1 next single parameter index is + # returned. if elementNumber == -1: ix = self.currentIndex elementNumber = 1 @@ -144,11 +156,12 @@ def getIndex(self, elementNumber=-1): ix = Qt.QModelIndex() (col, row, parentIdx) = (ix.column(), ix.row(), ix.parent()) - #to start from second column + # to start from second column if col == -1 and row == -1: ix = self.forwardIdx(0, 1, ix) - for i in range (0, elementNumber): - #This condition in case we start tabbing with cursor on first column + for i in range(0, elementNumber): + # This condition in case we start tabbing with cursor on first + # column if col == 0: currentNode = self.model().nodeFromIndex(ix) if isinstance(currentNode, macro.SingleParamNode): @@ -157,8 +170,8 @@ def getIndex(self, elementNumber=-1): nextIdx = self.forwardIdx(0, 1, ix) else: nextIdx = self.forwardIdx(row + 1, 1, parentIdx) - #this condition in case there is no next index and we want to pass focus - #to next widget in parent obj + # this condition in case there is no next index and we want to pass focus + # to next widget in parent obj if nextIdx == "term": return Qt.QModelIndex() ix = nextIdx @@ -166,7 +179,8 @@ def getIndex(self, elementNumber=-1): return ix def forwardIdx(self, row, col, parentIdx): - #This method is moving down the tree to get next SingleParamNode index. + # This method is moving down the tree to get next SingleParamNode + # index. try: proposalIdx = self.model().index(row, col, parentIdx) except AssertionError: @@ -204,17 +218,18 @@ def forwardIdx(self, row, col, parentIdx): return proposalIdx def validateAllExpresion(self, secValidation=False): - #This method is responsible for full validation of the macro. It is executed whenever the text is changed (when user edits values). - #Validation starts with checking if the macro (name) is valid. - #Next steps: - #1. Validates every SingleParamNode and counts how many there are in the macro. - #2. If there are more SingleParamNodes than entered values it will check if there is RepeatParamNode. + # This method is responsible for full validation of the macro. It is executed whenever the text is changed (when user edits values). + # Validation starts with checking if the macro (name) is valid. + # Next steps: + # 1. Validates every SingleParamNode and counts how many there are in the macro. + # 2. If there are more SingleParamNodes than entered values it will check if there is RepeatParamNode. # If there is RepeatParamNode it will check if its RepeatNodes can be deleted. - #3. If there are more values entered than SingleParamNodes in macro it will check if there is RepeatParamNode. + # 3. If there are more values entered than SingleParamNodes in macro it will check if there is RepeatParamNode. # If there is it will try to add new RepeatNode. if self.model() is None: - raise RuntimeError('Door must be set in order to use the macroexecutor.') + raise RuntimeError( + 'Door must be set in order to use the macroexecutor.') self.currentIndex = Qt.QModelIndex() mlist = str(self.text()).split() @@ -237,10 +252,10 @@ def validateAllExpresion(self, secValidation=False): problems.append(message) except IndexError: - problems.append("Macro<\b> is missing!") - self.setStyleSheet("") - self.setToolTip('
'.join(problems)) - return + problems.append("Macro<\b> is missing!") + self.setStyleSheet("") + self.setToolTip('
'.join(problems)) + return self.currentIndex = Qt.QModelIndex() ix = self.getIndex() @@ -254,11 +269,13 @@ def validateAllExpresion(self, secValidation=False): self.model().setData(self.currentIndex, Qt.QVariant(propValue)) except Exception as e: self.model().setData(self.currentIndex, Qt.QVariant('None')) - txt = str(Qt.from_qvariant(ix.sibling(ix.row(), 0).data(), str)) + txt = str(Qt.from_qvariant( + ix.sibling(ix.row(), 0).data(), str)) message = "" + txt + " " + e[0] problems.append(message) except IndexError: - txt = str(Qt.from_qvariant(ix.sibling(ix.row(), 0).data(), str)) + txt = str(Qt.from_qvariant( + ix.sibling(ix.row(), 0).data(), str)) problems.append("" + txt + " is missing!") data = str(Qt.from_qvariant(ix.data(), str)) @@ -268,7 +285,7 @@ def validateAllExpresion(self, secValidation=False): ix = self.getIndex() self.currentIndex = ix - if len(mlist) > counter: #if there are more values than parameters + if len(mlist) > counter: # if there are more values than parameters repeatNode = None for i in self.model().root().params(): repeatNode = i @@ -310,7 +327,8 @@ def validateAllExpresion(self, secValidation=False): return if len(problems) == 0: - self.setStyleSheet('SpockCommandWidget {background-color: %s; color: %s; border: %s; border-radius: %s}' % ('yellow', 'black', '3px solid green', '5px')) + self.setStyleSheet('SpockCommandWidget {background-color: %s; color: %s; border: %s; border-radius: %s}' % ( + 'yellow', 'black', '3px solid green', '5px')) self.setToolTip("") else: self.setStyleSheet("") @@ -318,30 +336,31 @@ def validateAllExpresion(self, secValidation=False): return def findParamRepeat(self, repeatNode): - #Method which finds index of given ParamRepeatNode in the macro. + # Method which finds index of given ParamRepeatNode in the macro. children = self.model().root().children() occ = children.count(repeatNode) idx = 0 for i in range(0, occ): idx = children.index(repeatNode, idx) - index = self.model().index(idx , 0, Qt.QModelIndex()) + index = self.model().index(idx, 0, Qt.QModelIndex()) return index def validateOneValue(self, value): - #Validates value of a SingleParamNode of a currentIndex + # Validates value of a SingleParamNode of a currentIndex paramNode = deepcopy(self.model().nodeFromIndex(self.currentIndex)) paramNode.setValue(value) return self.getModelObj().validateSingleParam(paramNode) def returnPressed(self): - #SLOT called when return is pressed + # SLOT called when return is pressed if self.toolTip() == "": self.emit(Qt.SIGNAL("pressedReturn")) else: - raise Exception("Cannot start macro. Please correct following mistakes:
" + self.toolTip()) + raise Exception( + "Cannot start macro. Please correct following mistakes:
" + self.toolTip()) def textChanged(self, strs): - #SLOT called when QLineEdit text is changed + # SLOT called when QLineEdit text is changed if strs == "": self.updateMacroEditor("") @@ -358,31 +377,37 @@ def textChanged(self, strs): self.setToolTip("Read Mode") def validateMacro(self, value): - #Method which ivestigates if the macro can be edited using yellow line. - #It cannot be executed when: 1. there are more than 1 ParamRepeatNodes, - #2. There is a ParamRepeatNode inside ParamRepeatNodem - #3. After ParamRepeatNode there are other nodes + # Method which ivestigates if the macro can be edited using yellow line. + # It cannot be executed when: 1. there are more than 1 ParamRepeatNodes, + # 2. There is a ParamRepeatNode inside ParamRepeatNodem + # 3. After ParamRepeatNode there are other nodes macroNode = self.getModelObj().getMacroNodeObj(str(value)) - if macroNode is None: return False - t = [child for child in macroNode.children() if isinstance(child, macro.RepeatParamNode)] + if macroNode is None: + return False + t = [child for child in macroNode.children() if isinstance(child, + macro.RepeatParamNode)] if len(t) > 1: self.disableEditMode = True - raise Exception('Macro %s cannot be edited using yellow line.
It contains more than 1 paramRepeat node.
Please use Macro Editor Widget to edit and execute this macro.' % str(value)) + raise Exception( + 'Macro %s cannot be edited using yellow line.
It contains more than 1 paramRepeat node.
Please use Macro Editor Widget to edit and execute this macro.' % str(value)) elif len(t) == 1: if len([child for child in t[0].children() if isinstance(child, macro.RepeatParamNode)]) > 0: self.disableEditMode = True - raise Exception('Macro %s cannot be edited using yellow line.
It contains paramRepeat node inside paramRepeat node.
Please use Macro Editor Widget to edit and execute this macro.' % str(value)) + raise Exception( + 'Macro %s cannot be edited using yellow line.
It contains paramRepeat node inside paramRepeat node.
Please use Macro Editor Widget to edit and execute this macro.' % str(value)) else: - if macroNode.children().index(t[0]) != len(macroNode.children()) - 1 : + if macroNode.children().index(t[0]) != len(macroNode.children()) - 1: self.disableEditMode = True - raise Exception('Macro %s cannot be edited using yellow line.
It contains paramRepeat node but not as a last parameter.
Please use Macro Editor Widget to edit and execute this macro.' % str(value)) + raise Exception( + 'Macro %s cannot be edited using yellow line.
It contains paramRepeat node but not as a last parameter.
Please use Macro Editor Widget to edit and execute this macro.' % str(value)) self.disableEditMode = False return True def downAction(self): - #Goes down in the history list of executed macros. - #self.disableSpockCommandUpdate flag is used to allow updating yellow line when model is changed. (when new row in history is chosen) + # Goes down in the history list of executed macros. + # self.disableSpockCommandUpdate flag is used to allow updating yellow + # line when model is changed. (when new row in history is chosen) self.disableSpockCommandUpdate = False self.emit(Qt.SIGNAL("elementDown")) @@ -484,7 +509,8 @@ def controlUpAction(self): self.model().setData(self.currentIndex, Qt.QVariant(value)) def getParamItems(self, index): - #Returns list of items that can be chosen for the node corresponding to the given index. Used by {next,prev}Value methods + # Returns list of items that can be chosen for the node corresponding + # to the given index. Used by {next,prev}Value methods node = self.model().nodeFromIndex(index) if isinstance(node, macro.MacroNode): @@ -551,9 +577,9 @@ def prevValue(self, current): return str(value) def updateMacroEditor(self, macroName): - #I had to make the macroname lowered as macros in comboBox (with macros), has names with all letter low. - #Because of that sometimes it was not loading macros in MacroEditor - #TO FIX + # I had to make the macroname lowered as macros in comboBox (with macros), has names with all letter low. + # Because of that sometimes it was not loading macros in MacroEditor + # TO FIX self.emit(Qt.SIGNAL("spockComboBox"), str(macroName).lower()) def measureSelection(self, position): @@ -567,7 +593,7 @@ def measureSelection(self, position): beg = s.rfind(' ', 0, position + 1) if end == -1: end = s.length() - 1 - return beg + 1, end - beg - 1 #returns the start and length of the value + return beg + 1, end - beg - 1 # returns the start and length of the value def focusInEvent(self, event): self.disableSpockCommandUpdate = True @@ -577,6 +603,7 @@ def focusOutEvent(self, event): self.disableSpockCommandUpdate = False Qt.QLineEdit.focusOutEvent(self, event) + class TaurusMacroExecutorWidget(TaurusWidget): def __init__(self, parent=None, designMode=False): @@ -588,17 +615,25 @@ def __init__(self, parent=None, designMode=False): self.setLayout(Qt.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) - self.addToFavouritesAction = Qt.QAction(getThemeIcon("software-update-available"), "Add to favourites", self) - self.connect(self.addToFavouritesAction, Qt.SIGNAL("triggered()"), self.onAddToFavourites) + self.addToFavouritesAction = Qt.QAction(getThemeIcon( + "software-update-available"), "Add to favourites", self) + self.connect(self.addToFavouritesAction, Qt.SIGNAL( + "triggered()"), self.onAddToFavourites) self.addToFavouritesAction.setToolTip("Add to favourites") - self.stopMacroAction = Qt.QAction(getIcon(":/actions/media_playback_stop.svg"), "Stop macro", self) - self.connect(self.stopMacroAction, Qt.SIGNAL("triggered()"), self.onStopMacro) + self.stopMacroAction = Qt.QAction( + getIcon(":/actions/media_playback_stop.svg"), "Stop macro", self) + self.connect(self.stopMacroAction, Qt.SIGNAL( + "triggered()"), self.onStopMacro) self.stopMacroAction.setToolTip("Stop macro") - self.pauseMacroAction = Qt.QAction(getIcon(":/actions/media_playback_pause.svg"), "Pause macro", self) - self.connect(self.pauseMacroAction, Qt.SIGNAL("triggered()"), self.onPauseMacro) + self.pauseMacroAction = Qt.QAction( + getIcon(":/actions/media_playback_pause.svg"), "Pause macro", self) + self.connect(self.pauseMacroAction, Qt.SIGNAL( + "triggered()"), self.onPauseMacro) self.pauseMacroAction.setToolTip("Pause macro") - self.playMacroAction = Qt.QAction(getIcon(":/actions/media_playback_start.svg"), "Start macro", self) - self.connect(self.playMacroAction, Qt.SIGNAL("triggered()"), self.onPlayMacro) + self.playMacroAction = Qt.QAction( + getIcon(":/actions/media_playback_start.svg"), "Start macro", self) + self.connect(self.playMacroAction, Qt.SIGNAL( + "triggered()"), self.onPlayMacro) self.playMacroAction.setToolTip("Start macro") actionsLayout = Qt.QHBoxLayout() actionsLayout.setContentsMargins(0, 0, 0, 0) @@ -631,7 +666,8 @@ def __init__(self, parent=None, designMode=False): self._paramEditorModel = ParamEditorModel() self.stackedWidget = Qt.QStackedWidget() - self.standardMacroParametersEditor = StandardMacroParametersEditor(self.stackedWidget) + self.standardMacroParametersEditor = StandardMacroParametersEditor( + self.stackedWidget) self.stackedWidget.addWidget(self.standardMacroParametersEditor) self.customMacroParametersEditor = None splitter.addWidget(self.stackedWidget) @@ -649,8 +685,10 @@ def __init__(self, parent=None, designMode=False): self.historyMacrosViewer.setFocusPolicy(Qt.Qt.NoFocus) self.tabMacroListsWidget = Qt.QTabWidget(self) - self.tabMacroListsWidget.addTab(self.favouritesMacrosEditor, "Favourite list") - self.tabMacroListsWidget.addTab(self.historyMacrosViewer, "History Viewer") + self.tabMacroListsWidget.addTab( + self.favouritesMacrosEditor, "Favourite list") + self.tabMacroListsWidget.addTab( + self.historyMacrosViewer, "History Viewer") splitter.addWidget(self.tabMacroListsWidget) self._isHistoryMacro = False @@ -658,32 +696,43 @@ def __init__(self, parent=None, designMode=False): self.layout().addWidget(self.macroProgressBar) #spockCommandLabel = Qt.QLabel("Spock command:", self) - #spockCommandLabel.setFont(Qt.QFont("Courier",9)) + # spockCommandLabel.setFont(Qt.QFont("Courier",9)) self.spockCommand = SpockCommandWidget("Spock", self) - self.spockCommand.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum) + self.spockCommand.setSizePolicy( + Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum) self.spockCommand.setUseParentModel(True) spockCommandLayout = Qt.QHBoxLayout() spockCommandLayout.setContentsMargins(0, 0, 0, 0) - #spockCommandLayout.addWidget(spockCommandLabel) + # spockCommandLayout.addWidget(spockCommandLabel) spockCommandLayout.addWidget(self.spockCommand) self.layout().addLayout(spockCommandLayout) - self.connect(self.macroComboBox, Qt.SIGNAL("currentIndexChanged(QString)"), self.onMacroComboBoxChanged) - self.connect(self.favouritesMacrosEditor.list, Qt.SIGNAL("favouriteSelected"), self.onFavouriteSelected) - self.connect(self.historyMacrosViewer.list, Qt.SIGNAL("historySelected"), self.onHistorySelected) - - self.connect(self.spockCommand, Qt.SIGNAL("pressedReturn"), self.onPlayMacro) - self.connect(self.spockCommand, Qt.SIGNAL("spockComboBox"), self.setComboBoxItem) - self.connect(self.spockCommand, Qt.SIGNAL("elementUp"), self.setHistoryUp) - self.connect(self.spockCommand, Qt.SIGNAL("elementDown"), self.setHistoryDown) - self.connect(self.spockCommand, Qt.SIGNAL("setHistoryFocus"), self.setHistoryFocus) - self.connect(self.spockCommand, Qt.SIGNAL("expandTree"), self.standardMacroParametersEditor.tree.expandAll) + self.connect(self.macroComboBox, Qt.SIGNAL( + "currentIndexChanged(QString)"), self.onMacroComboBoxChanged) + self.connect(self.favouritesMacrosEditor.list, Qt.SIGNAL( + "favouriteSelected"), self.onFavouriteSelected) + self.connect(self.historyMacrosViewer.list, Qt.SIGNAL( + "historySelected"), self.onHistorySelected) + + self.connect(self.spockCommand, Qt.SIGNAL( + "pressedReturn"), self.onPlayMacro) + self.connect(self.spockCommand, Qt.SIGNAL( + "spockComboBox"), self.setComboBoxItem) + self.connect(self.spockCommand, Qt.SIGNAL( + "elementUp"), self.setHistoryUp) + self.connect(self.spockCommand, Qt.SIGNAL( + "elementDown"), self.setHistoryDown) + self.connect(self.spockCommand, Qt.SIGNAL( + "setHistoryFocus"), self.setHistoryFocus) + self.connect(self.spockCommand, Qt.SIGNAL("expandTree"), + self.standardMacroParametersEditor.tree.expandAll) def macroId(self): return self._macroId def contextMenuEvent(self, event): menu = Qt.QMenu() - action = menu.addAction(getThemeIcon("view-refresh"), "Check door state", self.checkDoorState) + action = menu.addAction(getThemeIcon( + "view-refresh"), "Check door state", self.checkDoorState) menu.exec_(event.globalPos()) def checkDoorState(self): @@ -718,7 +767,7 @@ def setDoorName(self, doorName): def setFavouritesBuffer(self, favouritesMacro): self._favouritesBuffer = favouritesMacro - #History Widget + # History Widget def setHistoryUp(self): self.setHistoryFocus() self.historyMacrosViewer.listElementUp() @@ -729,7 +778,7 @@ def setHistoryDown(self): def setHistoryFocus(self): self.tabMacroListsWidget.setCurrentWidget(self.historyMacrosViewer) - #self.historyMacrosViewer.setFocus() + # self.historyMacrosViewer.setFocus() def historyBuffer(self): return self._historyBuffer @@ -778,13 +827,16 @@ def onMacroComboBoxChanged(self, macroName): if self.stackedWidget.count() == 2: self.stackedWidget.removeWidget(self.customMacroParametersEditor) self.customMacroParametersEditor.setParent(None) - self.customMacroParametersEditor = ParamEditorManager().getMacroEditor(macroName, self.stackedWidget) + self.customMacroParametersEditor = ParamEditorManager( + ).getMacroEditor(macroName, self.stackedWidget) if self.customMacroParametersEditor: self.customMacroParametersEditor.setModel(self.paramEditorModel()) self.stackedWidget.addWidget(self.customMacroParametersEditor) - self.stackedWidget.setCurrentWidget(self.customMacroParametersEditor) + self.stackedWidget.setCurrentWidget( + self.customMacroParametersEditor) else: - self.standardMacroParametersEditor.setModel(self.paramEditorModel()) + self.standardMacroParametersEditor.setModel( + self.paramEditorModel()) self.emit(Qt.SIGNAL("macroNameChanged"), macroName) @@ -805,10 +857,12 @@ def onHistorySelected(self, macroNode): self.macroComboBox.selectMacro(name) def onAddToFavourites(self): - self.favouritesMacrosEditor.addMacro(deepcopy(self.paramEditorModel().root())) + self.favouritesMacrosEditor.addMacro( + deepcopy(self.paramEditorModel().root())) def addToHistory(self): - self.historyMacrosViewer.addMacro(deepcopy(self.paramEditorModel().root())) + self.historyMacrosViewer.addMacro( + deepcopy(self.paramEditorModel().root())) def onDoorChanged(self, doorName): self.setDoorName(doorName) @@ -845,7 +899,8 @@ def onPlayMacro(self): params, alerts = macroNode.toRun() xmlString = paramEditorModel.toXmlString() if len(alerts) > 0: - Qt.QMessageBox.warning(self, "Macro parameters warning", alerts) + Qt.QMessageBox.warning( + self, "Macro parameters warning", alerts) return door.runMacro(xmlString) self.addToHistory() @@ -886,12 +941,16 @@ def onPauseMacro(self): def onMacroStatusUpdated(self, data): macro = data[0] - if macro is None: return + if macro is None: + return data = data[1][0] - state, range, step, id = data["state"], data["range"], data["step"], data["id"] - if id is None: return + state, range, step, id = data["state"], data[ + "range"], data["step"], data["id"] + if id is None: + return id = int(id) - if id != self.macroId(): return + if id != self.macroId(): + return macroName = macro.name shortMessage = "" if state == "start": @@ -901,7 +960,8 @@ def onMacroStatusUpdated(self, data): self.pauseMacroAction.setEnabled(True) self.stopMacroAction.setEnabled(True) self.emit(Qt.SIGNAL("plotablesFilterChanged"), None) - self.emit(Qt.SIGNAL("plotablesFilterChanged"), standardPlotablesFilter) + self.emit(Qt.SIGNAL("plotablesFilterChanged"), + standardPlotablesFilter) shortMessage = "Macro %s started." % macroName elif state == "pause": self.playMacroAction.setText("Resume macro") @@ -926,7 +986,8 @@ def onMacroStatusUpdated(self, data): self.stopMacroAction.setEnabled(False) shortMessage = "Macro %s error." % macroName exc_value, exc_stack = data['exc_value'], data['exc_stack'] - exceptionDialog = TaurusMessageBox(MacroRunException, exc_value, exc_stack) + exceptionDialog = TaurusMessageBox( + MacroRunException, exc_value, exc_stack) exceptionDialog.exec_() elif state == "abort": self.playMacroAction.setText("Start macro") @@ -948,10 +1009,12 @@ def disableControlActions(self): def setModel(self, model): oldModelObj = self.getModelObj() if oldModelObj is not None: - self.disconnect(oldModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated) + self.disconnect(oldModelObj, Qt.SIGNAL( + "macrosUpdated"), self.macroComboBox.onMacrosUpdated) TaurusWidget.setModel(self, model) newModelObj = self.getModelObj() - self.connect(newModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated) + self.connect(newModelObj, Qt.SIGNAL("macrosUpdated"), + self.macroComboBox.onMacrosUpdated) @classmethod def getQtDesignerPluginInfo(cls): @@ -971,11 +1034,13 @@ def initComponents(self): self.registerConfigDelegate(self.taurusMacroExecutorWidget) self.taurusMacroExecutorWidget.setUseParentModel(True) self.setCentralWidget(self.taurusMacroExecutorWidget) - self.connect(self.taurusMacroExecutorWidget, Qt.SIGNAL('shortMessageEmitted'), self.onShortMessage) + self.connect(self.taurusMacroExecutorWidget, Qt.SIGNAL( + 'shortMessageEmitted'), self.onShortMessage) self.statusBar().showMessage("MacroExecutor ready") def setCustomMacroEditorPaths(self, customMacroEditorPaths): - MacroExecutionWindow.setCustomMacroEditorPaths(self, customMacroEditorPaths) + MacroExecutionWindow.setCustomMacroEditorPaths( + self, customMacroEditorPaths) ParamEditorManager().parsePaths(customMacroEditorPaths) ParamEditorManager().browsePaths() @@ -986,10 +1051,13 @@ def loadSettings(self): def onDoorChanged(self, doorName): MacroExecutionWindow.onDoorChanged(self, doorName) if self._qDoor: - Qt.QObject.disconnect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusMacroExecutorWidget.onMacroStatusUpdated) - if doorName == "": return + Qt.QObject.disconnect(self._qDoor, Qt.SIGNAL( + "macroStatusUpdated"), self.taurusMacroExecutorWidget.onMacroStatusUpdated) + if doorName == "": + return self._qDoor = Device(doorName) - Qt.QObject.connect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusMacroExecutorWidget.onMacroStatusUpdated) + Qt.QObject.connect(self._qDoor, Qt.SIGNAL( + "macroStatusUpdated"), self.taurusMacroExecutorWidget.onMacroStatusUpdated) self.taurusMacroExecutorWidget.onDoorChanged(doorName) @classmethod @@ -1000,22 +1068,26 @@ def getQtDesignerPluginInfo(cls): def createMacroExecutorWidget(args): macroExecutor = TaurusMacroExecutorWidget() macroExecutor.setModelInConfig(True) - Qt.QObject.connect(macroExecutor, Qt.SIGNAL("doorChanged"), macroExecutor.onDoorChanged) + Qt.QObject.connect(macroExecutor, Qt.SIGNAL( + "doorChanged"), macroExecutor.onDoorChanged) if len(args) == 2: macroExecutor.setModel(args[0]) macroExecutor.emit(Qt.SIGNAL('doorChanged'), args[1]) return macroExecutor + def createMacroExecutor(args): macroExecutor = TaurusMacroExecutor() macroExecutor.setModelInConfig(True) - Qt.QObject.connect(macroExecutor, Qt.SIGNAL("doorChanged"), macroExecutor.onDoorChanged) + Qt.QObject.connect(macroExecutor, Qt.SIGNAL( + "doorChanged"), macroExecutor.onDoorChanged) if len(args) == 2: macroExecutor.setModel(args[0]) macroExecutor.emit(Qt.SIGNAL('doorChanged'), args[1]) macroExecutor.loadSettings() return macroExecutor + def main(): from taurus.qt.qtgui.application import TaurusApplication import taurus diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/__init__.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/__init__.py index fc9c991c85..b4af3d0275 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/__init__.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/__init__.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/__init__.py index 141eb7017b..c470b50746 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/__init__.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/senv.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/senv.py index dbe358d91c..81ab3ce1be 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/senv.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/customeditors/senv.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -49,9 +49,11 @@ def initComponents(self): self.layout().addRow(Qt.QLabel("Setting environment variable:", self)) self.nameComboBox = ComboBoxParam(self) - self.nameComboBox.addItems(["ActiveMntGrp", "ExtraColumns", "JsonRecorder", "ScanFile", "ScanDir"]) + self.nameComboBox.addItems( + ["ActiveMntGrp", "ExtraColumns", "JsonRecorder", "ScanFile", "ScanDir"]) self.nameComboBox.setEditable(True) - self.connect(self.nameComboBox, Qt.SIGNAL("currentIndexChanged(int)"), self.onNameComboBoxChanged) + self.connect(self.nameComboBox, Qt.SIGNAL( + "currentIndexChanged(int)"), self.onNameComboBoxChanged) self.layout().addRow("name:", self.nameComboBox) nameIndex = self.model().index(0, 1, self.rootIndex()) @@ -98,10 +100,11 @@ def onNameComboBoxChanged(self, index): else: self.layout().addRow(self.valueWidget) + def getSenvValueEditor(envName, parent): """Factory method, requires: string, and QWidget as a parent for returned editor. Factory returns a tuple of widget and a label for it. - + :return: (Qt.QWidget, str) """ label = "value:" if envName == "ActiveMntGrp": @@ -121,6 +124,7 @@ def getSenvValueEditor(envName, parent): editor = LineEditParam(parent) return editor, label + class ExtraColumnsEditor(ParamBase, Qt.QWidget): def __init__(self, parent=None, paramModel=None): @@ -129,8 +133,10 @@ def __init__(self, parent=None, paramModel=None): self.setLayout(Qt.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) - addNewColumnButton = Qt.QPushButton(getThemeIcon("list-add") , "Add new column...", self) - removeSelectedColumnsButton = Qt.QPushButton(getThemeIcon("list-remove") , "Remove selected...", self) + addNewColumnButton = Qt.QPushButton( + getThemeIcon("list-add"), "Add new column...", self) + removeSelectedColumnsButton = Qt.QPushButton( + getThemeIcon("list-remove"), "Remove selected...", self) buttonsLayout = Qt.QHBoxLayout() buttonsLayout.addWidget(addNewColumnButton) buttonsLayout.addWidget(removeSelectedColumnsButton) @@ -139,14 +145,19 @@ def __init__(self, parent=None, paramModel=None): self.extraColumnsTable = ExtraColumnsTable(self) self.extraColumnsModel = ExtraColumnsModel() self.extraColumnsTable.setModel(self.extraColumnsModel) - self.extraColumnsTable.setItemDelegate(ExtraColumnsDelegate(self.extraColumnsTable)) + self.extraColumnsTable.setItemDelegate( + ExtraColumnsDelegate(self.extraColumnsTable)) self.layout().addWidget(self.extraColumnsTable) - self.connect(addNewColumnButton, Qt.SIGNAL("clicked()"), self.onAddNewColumn) - self.connect(removeSelectedColumnsButton, Qt.SIGNAL("clicked()"), self.onRemoveSelectedColumns) - self.connect(self.extraColumnsModel, Qt.SIGNAL("dataChanged (const QModelIndex&,const QModelIndex&)"), self.onExtraColumnsChanged) - self.connect(self.extraColumnsModel, Qt.SIGNAL("modelReset()"), self.onExtraColumnsChanged) + self.connect(addNewColumnButton, Qt.SIGNAL( + "clicked()"), self.onAddNewColumn) + self.connect(removeSelectedColumnsButton, Qt.SIGNAL( + "clicked()"), self.onRemoveSelectedColumns) + self.connect(self.extraColumnsModel, Qt.SIGNAL( + "dataChanged (const QModelIndex&,const QModelIndex&)"), self.onExtraColumnsChanged) + self.connect(self.extraColumnsModel, Qt.SIGNAL( + "modelReset()"), self.onExtraColumnsChanged) def getValue(self): return repr(self.extraColumnsTable.model().columns()) @@ -178,7 +189,8 @@ def __init__(self, parent): self.setSelectionMode(Qt.QAbstractItemView.ExtendedSelection) def setColumns(self, columns): - if columns == None: columns = [] + if columns == None: + columns = [] self.model().setColumns(columns) self.resizeColumnsToContents() @@ -202,7 +214,8 @@ def __init__(self, parent=None): def createEditor(self, parent, option, index): if index.column() == 1: - self.combo_attr_tree_widget = TaurusDbTreeWidget(perspective=TaurusElementType.Device) + self.combo_attr_tree_widget = TaurusDbTreeWidget( + perspective=TaurusElementType.Device) self.combo_attr_tree_widget.setModel(self.host) treeView = self.combo_attr_tree_widget.treeView() qmodel = self.combo_attr_tree_widget.getQModel() @@ -220,7 +233,8 @@ def createEditor(self, parent, option, index): def setEditorData(self, editor, index): if index.column() == 2: - text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) + text = Qt.from_qvariant(index.model().data( + index, Qt.Qt.DisplayRole), str) editor.setCurrentText(text) else: Qt.QItemDelegate.setEditorData(self, editor, index) @@ -229,7 +243,8 @@ def setModelData(self, editor, model, index): column = index.column() if column == 1: selectedItems = self.combo_attr_tree_widget.selectedItems() - if not len(selectedItems) == 1: return + if not len(selectedItems) == 1: + return taurusTreeAttributeItem = selectedItems[0] itemData = taurusTreeAttributeItem.itemData() if isinstance(itemData, TaurusAttrInfo): @@ -242,7 +257,8 @@ def setModelData(self, editor, model, index): def sizeHint(self, option, index): if index.column() == 0: fm = option.fontMetrics - text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) + text = Qt.from_qvariant(index.model().data( + index, Qt.Qt.DisplayRole), str) document = Qt.QTextDocument() document.setDefaultFont(option.font) document.setHtml(text) @@ -260,11 +276,12 @@ def sizeHint(self, option, index): size = Qt.QItemDelegate.sizeHint(self, option, index) return size -class ExtraColumnsModel(Qt.QAbstractTableModel): +class ExtraColumnsModel(Qt.QAbstractTableModel): def __init__(self, columns=None): - if columns is None: columns = [] + if columns is None: + columns = [] Qt.QAbstractItemModel.__init__(self) self.__columns = columns @@ -286,11 +303,14 @@ def data(self, index, role=Qt.Qt.DisplayRole): return Qt.QVariant() row = index.row() column = index.column() - #Display Role + # Display Role if role == Qt.Qt.DisplayRole: - if column == 0: return Qt.QVariant(Qt.QString(self.__columns[row]['label'])) - elif column == 1: return Qt.QVariant(Qt.QString(self.__columns[row]['model'])) - elif column == 2: return Qt.QVariant(Qt.QString(self.__columns[row]['instrument'])) + if column == 0: + return Qt.QVariant(Qt.QString(self.__columns[row]['label'])) + elif column == 1: + return Qt.QVariant(Qt.QString(self.__columns[row]['model'])) + elif column == 2: + return Qt.QVariant(Qt.QString(self.__columns[row]['instrument'])) return Qt.QVariant() def headerData(self, section, orientation, role=Qt.Qt.DisplayRole): @@ -300,11 +320,14 @@ def headerData(self, section, orientation, role=Qt.Qt.DisplayRole): return Qt.QVariant(int(Qt.Qt.AlignRight | Qt.Qt.AlignVCenter)) if role != Qt.Qt.DisplayRole: return Qt.QVariant() - #So this is DisplayRole... + # So this is DisplayRole... if orientation == Qt.Qt.Horizontal: - if section == 0: return Qt.QVariant("Label") - elif section == 1: return Qt.QVariant("Attribute") - elif section == 2: return Qt.QVariant("Instrument") + if section == 0: + return Qt.QVariant("Label") + elif section == 1: + return Qt.QVariant("Attribute") + elif section == 2: + return Qt.QVariant("Instrument") return Qt.QVariant() else: return Qt.QVariant(Qt.QString.number(section + 1)) @@ -322,15 +345,20 @@ def setData(self, index, value=None, role=Qt.Qt.EditRole): row = index.row() column = index.column() value = Qt.from_qvariant(value, str) - if column == 0: self.__columns[row]['label'] = value - elif column == 1: self.__columns[row]['model'] = value - elif column == 2: self.__columns[row]['instrument'] = value - self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) + if column == 0: + self.__columns[row]['label'] = value + elif column == 1: + self.__columns[row]['model'] = value + elif column == 2: + self.__columns[row]['instrument'] = value + self.emit( + Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) return True return False def insertRows(self, row, rows=1, parentindex=None): - if parentindex is None: parentindex = Qt.QModelIndex() + if parentindex is None: + parentindex = Qt.QModelIndex() first = row last = row + rows - 1 self.beginInsertRows(parentindex, first, last) @@ -340,10 +368,12 @@ def insertRows(self, row, rows=1, parentindex=None): return True def insertRow(self, row, parentIndex=None): - self.__columns.insert(row, {'label':'', 'model':'', 'instrument':''}) + self.__columns.insert( + row, {'label': '', 'model': '', 'instrument': ''}) def removeRows(self, row, rows=1, parentindex=None): - if parentindex is None: parentindex = Qt.QModelIndex() + if parentindex is None: + parentindex = Qt.QModelIndex() first = row last = row + rows - 1 self.beginRemoveRows(parentindex, first, last) diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/delegate.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/delegate.py index 66d796f1c8..28e3a1bdbf 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/delegate.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/delegate.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -35,6 +35,7 @@ from .parameditors import MSAttrListComboBoxParam, SpinBoxParam, \ DoubleSpinBoxParam, LineEditParam, FileDialogParam, ComboBoxParam, ComboBoxBoolean + class ParamEditorDelegate(Qt.QStyledItemDelegate): def __init__(self, parent=None): @@ -52,8 +53,8 @@ def createEditor(self, parent, option, index): ################## # The setUseParentModel mechanism is not working # we do it manually here as a hack - #comboBox.setUseParentModel(True) - #comboBox.setModel('/elements') + # comboBox.setUseParentModel(True) + # comboBox.setModel('/elements') w = parent while w is not None: if hasattr(w, 'getModelName'): @@ -78,7 +79,8 @@ def createEditor(self, parent, option, index): def setEditorData(self, editor, index): if index.column() == 1: - text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) + text = Qt.from_qvariant(index.model().data( + index, Qt.Qt.DisplayRole), str) if text == "None" or text == "" or text is None: Qt.QStyledItemDelegate.setEditorData(self, editor, index) else: @@ -107,7 +109,8 @@ def setModelData(self, editor, model, index): def sizeHint(self, option, index): if index.column() == 0: fm = option.fontMetrics - text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) + text = Qt.from_qvariant(index.model().data( + index, Qt.Qt.DisplayRole), str) document = Qt.QTextDocument() document.setDefaultFont(option.font) document.setHtml(text) diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/macroparameterseditor.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/macroparameterseditor.py index 8e0f371aa4..215f7cebf8 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/macroparameterseditor.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/macroparameterseditor.py @@ -2,31 +2,33 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """ macroparameterseditor.py: """ -import sys, inspect, glob +import sys +import inspect +import glob from taurus.external.qt import Qt from taurus.core.util.singleton import Singleton @@ -53,6 +55,7 @@ def __init__(self): # def onModelReset(self): # self.onDataChanged() + class StandardMacroParametersEditor(Qt.QWidget, MacroParametersEditor): def __init__(self, parent=None, macroNode=None): @@ -66,7 +69,8 @@ def initComponents(self): self.tree = MacroParametersTree(self) self.delegate = ParamEditorDelegate(self.tree) self.tree.setItemDelegate(self.delegate) - self.tree.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Expanding) + self.tree.setSizePolicy(Qt.QSizePolicy.Expanding, + Qt.QSizePolicy.Expanding) self.layout().addWidget(self.tree) actionLayout = Qt.QVBoxLayout() @@ -86,7 +90,8 @@ def initComponents(self): duplicateButton = Qt.QToolButton() duplicateButton.setDefaultAction(self.tree.duplicateAction) actionLayout.addWidget(duplicateButton) - spacerItem = Qt.QSpacerItem(0, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) + spacerItem = Qt.QSpacerItem( + 0, 0, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) actionLayout.addItem(spacerItem) self.layout().addLayout(actionLayout) @@ -101,6 +106,7 @@ def macroNode(self): def setMacroNode(self, macroNode): self.tree.setMacroNode(macroNode) + class MacroParametersTree(Qt.QTreeView): def __init__(self, parent=None, designMode=False): @@ -110,21 +116,32 @@ def __init__(self, parent=None, designMode=False): # self.setTabKeyNavigation(True) self.setEditTriggers(Qt.QAbstractItemView.AllEditTriggers) - self.addAction = Qt.QAction(getThemeIcon("list-add"), "Add new repetition", self) - self.connect(self.addAction, Qt.SIGNAL("triggered()"), self.onAddRepeat) - self.addAction.setToolTip("Clicking this button will add new repetition to current parameter.") + self.addAction = Qt.QAction(getThemeIcon( + "list-add"), "Add new repetition", self) + self.connect(self.addAction, Qt.SIGNAL( + "triggered()"), self.onAddRepeat) + self.addAction.setToolTip( + "Clicking this button will add new repetition to current parameter.") - self.deleteAction = Qt.QAction(getThemeIcon("list-remove"), "Remove repetition", self) - self.connect(self.deleteAction, Qt.SIGNAL("triggered()"), self.onDelRepeat) - self.deleteAction.setToolTip("Clicking this button will remove current repetition.") + self.deleteAction = Qt.QAction(getThemeIcon( + "list-remove"), "Remove repetition", self) + self.connect(self.deleteAction, Qt.SIGNAL( + "triggered()"), self.onDelRepeat) + self.deleteAction.setToolTip( + "Clicking this button will remove current repetition.") self.moveUpAction = Qt.QAction(getThemeIcon("go-up"), "Move up", self) - self.connect(self.moveUpAction, Qt.SIGNAL("triggered()"), self.onUpRepeat) - self.moveUpAction.setToolTip("Clicking this button will move current repetition up.") - - self.moveDownAction = Qt.QAction(getThemeIcon("go-down"), "Move down", self) - self.connect(self.moveDownAction, Qt.SIGNAL("triggered()"), self.onDownRepeat) - self.moveDownAction.setToolTip("Clicking this button will move current repetition down.") + self.connect(self.moveUpAction, Qt.SIGNAL( + "triggered()"), self.onUpRepeat) + self.moveUpAction.setToolTip( + "Clicking this button will move current repetition up.") + + self.moveDownAction = Qt.QAction( + getThemeIcon("go-down"), "Move down", self) + self.connect(self.moveDownAction, Qt.SIGNAL( + "triggered()"), self.onDownRepeat) + self.moveDownAction.setToolTip( + "Clicking this button will move current repetition down.") self.duplicateAction = Qt.QAction(getThemeIcon("edit-copy"), "Duplicate", self) @@ -135,7 +152,6 @@ def __init__(self, parent=None, designMode=False): self.disableActions() - def disableActions(self): self.addAction.setEnabled(False) self.deleteAction.setEnabled(False) @@ -159,12 +175,11 @@ def manageActions(self, currentIndex): self.deleteAction.setEnabled(False) self.duplicateAction.setEnabled(False) - def currentChanged(self, current, previous): self.manageActions(current) Qt.QTreeView.currentChanged(self, current, previous) - #def focusInEvent(self, event): + # def focusInEvent(self, event): # reason = event.reason() # if (reason == Qt.Qt.TabFocusReason) | (reason == Qt.Qt.BacktabFocusReason): # if reason == Qt.Qt.TabFocusReason: @@ -176,7 +191,7 @@ def currentChanged(self, current, previous): # else: # Qt.QTreeView.focusInEvent(self, event) # - #def forwardIdx(self, row, col, parentIdx): + # def forwardIdx(self, row, col, parentIdx): # try: # proposalIdx = self.model().index(row, col, parentIdx) # except AssertionError: @@ -213,7 +228,7 @@ def currentChanged(self, current, previous): # ##self.model().setRoot(proposalNode) # return self.forwardIdx(0,1,proposalIdx) # - #def backwardIdx(self, row, col, parentIdx): + # def backwardIdx(self, row, col, parentIdx): # try: # proposalIdx = self.model().index(row, col, parentIdx) # except AssertionError: @@ -246,7 +261,7 @@ def currentChanged(self, current, previous): # # return proposalIdx # - #def moveCursor (self, cursorAction, modifiers): + # def moveCursor (self, cursorAction, modifiers): # ix=self.currentIndex() # self.manageActions(ix) # (col, row, parentIdx)=(ix.column(), ix.row(), ix.parent()) @@ -297,7 +312,7 @@ def currentChanged(self, current, previous): # self.manageActions(backwardIdx) # return backwardIdx # - #def expanded(self): + # def expanded(self): # for column in range(self.model().columnCount(Qt.QModelIndex())): # self.resizeColumnToContents(column) @@ -398,5 +413,3 @@ def getMacroEditor(self, macroName=None, parent=None): return editorClass(parent=parent) except: return None - - diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/model.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/model.py index 6a7f746052..bff14c9d2c 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/model.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/model.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -48,7 +48,8 @@ def root(self): return self._root def setRoot(self, node=None): - if node == None: node = macro.MacroNode() + if node == None: + node = macro.MacroNode() self._root = node self.reset() @@ -59,17 +60,19 @@ def flags(self, index): node = self.nodeFromIndex(index) if (index.column() == 1 and - isinstance(node, macro.SingleParamNode) and - not node.type() in globals.EDITOR_NONEDITABLE_PARAMS): + isinstance(node, macro.SingleParamNode) and + not node.type() in globals.EDITOR_NONEDITABLE_PARAMS): return Qt.Qt.ItemIsEnabled | Qt.Qt.ItemIsEditable return Qt.Qt.ItemIsEnabled def _insertRow(self, parentIndex, node=None, row=-1): parentNode = self.nodeFromIndex(parentIndex) - if row == -1: row = len(parentNode) + if row == -1: + row = len(parentNode) - if node == None: node = parentNode.newRepeat() + if node == None: + node = parentNode.newRepeat() self.beginInsertRows(parentIndex, row, row) row = parentNode.insertChild(node, row) @@ -176,13 +179,13 @@ def data(self, index, role): return Qt.QVariant() - - def setData (self, index, value, role=Qt.Qt.EditRole): + def setData(self, index, value, role=Qt.Qt.EditRole): node = self.nodeFromIndex(index) # if index.isValid() and 0 <= index.row() < len(node.parent()): if index.column() == 1: node.setValue(Qt.from_qvariant(value, str)) - self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) + self.emit( + Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) return True return False @@ -193,15 +196,14 @@ def headerData(self, section, orientation, role): def index(self, row, column, parent): if not parent.isValid(): - parentNode = self.root(); + parentNode = self.root() else: parentNode = parent.internalPointer() childNode = parentNode.child(row) if childNode is None: - return Qt.QModelIndex(); + return Qt.QModelIndex() else: - return self.createIndex(row, column, childNode); - + return self.createIndex(row, column, childNode) def parent(self, child): node = self.nodeFromIndex(child) diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/parameditors.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/parameditors.py index f38f90f9e4..b0b19c0ca4 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/parameditors.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/macroparameterseditor/parameditors.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -36,9 +36,12 @@ from sardana.taurus.qt.qtgui.extra_macroexecutor.common import MSAttrListComboBox #@todo: replace by method from common module + + def str2bool(text): return text in ("True", "1") + class ParamBase: def __init__(self, paramModel=None): @@ -70,13 +73,16 @@ def onModelChanged(self): model = self.index().model() model.setData(self.index(), Qt.QVariant(self.getValue())) + class ComboBoxBoolean(ParamBase, Qt.QComboBox): + def __init__(self, parent=None, paramModel=None): Qt.QComboBox.__init__(self, parent) ParamBase.__init__(self, paramModel) self.addItems(['True', 'False']) - self.connect(self, Qt.SIGNAL("currentIndexChanged(int)"), self.onCurrentIndexChanged) + self.connect(self, Qt.SIGNAL("currentIndexChanged(int)"), + self.onCurrentIndexChanged) def getValue(self): return str(self.currentText()) @@ -85,19 +91,22 @@ def setValue(self, value): currentIdx = self.currentIndex() idx = self.findText(value) if currentIdx == idx: - self.emit(Qt.SIGNAL("currentIndexChanged(int)"), self.currentIndex()) + self.emit(Qt.SIGNAL("currentIndexChanged(int)"), + self.currentIndex()) else: self.setCurrentIndex(idx) def onCurrentIndexChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) + class ComboBoxParam(ParamBase, Qt.QComboBox): def __init__(self, parent=None, paramModel=None): Qt.QComboBox.__init__(self, parent) ParamBase.__init__(self, paramModel) - self.connect(self, Qt.SIGNAL("currentIndexChanged(int)"), self.onCurrentIndexChanged) + self.connect(self, Qt.SIGNAL("currentIndexChanged(int)"), + self.onCurrentIndexChanged) def getValue(self): return str(self.currentText()) @@ -106,13 +115,15 @@ def setValue(self, value): currentIdx = self.currentIndex() idx = self.findText(value) if currentIdx == idx: - self.emit(Qt.SIGNAL("currentIndexChanged(int)"), self.currentIndex()) + self.emit(Qt.SIGNAL("currentIndexChanged(int)"), + self.currentIndex()) else: self.setCurrentIndex(idx) def onCurrentIndexChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) + class MSAttrListComboBoxParam(ParamBase, MSAttrListComboBox): def __init__(self, parent=None, paramModel=None): @@ -120,7 +131,8 @@ def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) # self.setUseParentModel(True) # self.setModel("/" + self.paramModel().type() + "List") - self.connect(self, Qt.SIGNAL("currentIndexChanged(int)"), self.onCurrentIndexChanged) + self.connect(self, Qt.SIGNAL("currentIndexChanged(int)"), + self.onCurrentIndexChanged) def getValue(self): return str(self.currentText()) @@ -139,7 +151,6 @@ def __init__(self, parent=None, paramModel=None): ParamBase.__init__(self, paramModel) self.setModel("/" + self.paramModel().type() + "List") - def handleEvent(self, src, type, value): self.clear() if src and value: @@ -163,10 +174,12 @@ def getValue(self): class LineEditParam(ParamBase, Qt.QLineEdit): + def __init__(self, parent=None, paramModel=None): Qt.QLineEdit.__init__(self, parent) ParamBase.__init__(self, paramModel) - self.connect(self, Qt.SIGNAL("textChanged(const QString&)"), self.onTextChanged) + self.connect(self, Qt.SIGNAL( + "textChanged(const QString&)"), self.onTextChanged) def onTextChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) @@ -186,6 +199,7 @@ def getValue(self): # self.setText("") # self.setDefaultValue() + class CheckBoxParam(ParamBase, Qt.QCheckBox): def __init__(self, parent=None, paramModel=None): @@ -204,6 +218,7 @@ def onStateChanged(self): class SpinBoxParam(ParamBase, Qt.QSpinBox): + def __init__(self, parent=None, paramModel=None): Qt.QSpinBox.__init__(self, parent) ParamBase.__init__(self, paramModel) @@ -220,7 +235,9 @@ def setValue(self, value): # self.setValue(0) # self.setDefaultValue() + class DoubleSpinBoxParam(ParamBase, Qt.QDoubleSpinBox): + def __init__(self, parent=None, paramModel=None): Qt.QDoubleSpinBox.__init__(self, parent) ParamBase.__init__(self, paramModel) @@ -249,7 +266,9 @@ def setValue(self, value): # self.setValue(0.0) # self.setDefaultValue() + class FileDialogParam(ParamBase, Qt.QWidget): + def __init__(self, parent=None, paramModel=None): Qt.QWidget.__init__(self, parent) ParamBase.__init__(self, paramModel) @@ -263,7 +282,8 @@ def __init__(self, parent=None, paramModel=None): self.text = "" - Qt.QObject.connect(self.button, Qt.SIGNAL("clicked()"), self._chooseAFile) + Qt.QObject.connect(self.button, Qt.SIGNAL( + "clicked()"), self._chooseAFile) def _chooseAFile(self): path = Qt.QFileDialog().getOpenFileName() @@ -290,6 +310,7 @@ def getValue(self): def setValue(self, value): self.filePath.setText(value) + class DirPathParam(ParamBase, Qt.QWidget): def __init__(self, parent=None, paramModel=None): @@ -305,7 +326,8 @@ def __init__(self, parent=None, paramModel=None): self.layout.addWidget(self.button) self.connect(self.button, Qt.SIGNAL("clicked()"), self.__chooseDirPath) - self.connect(self.dirPath, Qt.SIGNAL("textChanged(const QString&)"), self.onDirPathChanged) + self.connect(self.dirPath, Qt.SIGNAL( + "textChanged(const QString&)"), self.onDirPathChanged) def onDirPathChanged(self): self.emit(Qt.SIGNAL("modelChanged()")) @@ -319,5 +341,3 @@ def getValue(self): def setValue(self, value): self.dirPath.setText(value) - - diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/scanplotter.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/scanplotter.py index 6a353ac57e..def71c5295 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/scanplotter.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/scanplotter.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -109,14 +109,16 @@ def onDoorChanged(self, doorName): def getPlotables(self, macronames=None, doorname=None, movingmotors=None): """returns a list of plotables for this scan given macro (channels and moving motors)""" plotables = [] - if macronames is None: macronames = list(set(self._macroNames)) - if doorname is None: doorname = self._doorName - if movingmotors is None: movingmotors = list(set(self._movingMotors)) + if macronames is None: + macronames = list(set(self._macroNames)) + if doorname is None: + doorname = self._doorName + if movingmotors is None: + movingmotors = list(set(self._movingMotors)) if doorname is None or not len(macronames): return plotables door = taurus.Device(doorname) - for macroname in macronames: env = dictFromSequence(door.getMacroEnv([macroname])) mntgrp_name = env.get("ActiveMntGrp") @@ -126,7 +128,8 @@ def getPlotables(self, macronames=None, doorname=None, movingmotors=None): channels = mntgrp.getAttribute('Channels').read() channelsList = channels.value timer_name = mntgrp.getAttribute('Timer').read().value.lower() - plotables += [('%s/%s_value' % (mntgrp_name, ch)).lower() for ch in channelsList if ch.lower() != timer_name] + plotables += [('%s/%s_value' % (mntgrp_name, ch)).lower() + for ch in channelsList if ch.lower() != timer_name] for m in movingmotors: if not (m is None or m == "" or m == "None"): @@ -134,14 +137,16 @@ def getPlotables(self, macronames=None, doorname=None, movingmotors=None): return plotables def populatePlotables(self, plotables=None): - ##@TODO: The name in the legend should be more descriptive: i.e. "dev/attr" instead of "attr" (this probably has to be changed for taurusplot in general ) - if plotables is None: plotables = self.getPlotables() + # @TODO: The name in the legend should be more descriptive: i.e. "dev/attr" instead of "attr" (this probably has to be changed for taurusplot in general ) + if plotables is None: + plotables = self.getPlotables() self.setModel(plotables) self.curves_lock.acquire() try: for name in self.getTrendSetNames(): ts = self.getTrendSet(name) - ts.fireEvent(None, taurus.core.taurusbasetypes.TaurusEventType.Change, None) + ts.fireEvent( + None, taurus.core.taurusbasetypes.TaurusEventType.Change, None) finally: self.curves_lock.release() self.setEventFilters([eventfilters.ONLY_VALID], plotables) @@ -150,7 +155,9 @@ def populatePlotables(self, plotables=None): import sys app = QtGui.QApplication(sys.argv) form = ScanPlotter() - if len(sys.argv) < 4: raise ValueError('Syntax: ' + sys.argv[0] + ' macroname doorname plotable [anotherplotable...]') + if len(sys.argv) < 4: + raise ValueError( + 'Syntax: ' + sys.argv[0] + ' macroname doorname plotable [anotherplotable...]') form._macroName = sys.argv[1] form._doorName = sys.argv[2] form.populatePlotables(sys.argv[3:]) diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/__init__.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/__init__.py index 8866e60f99..a3b9001128 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/__init__.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/delegate.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/delegate.py index 9b742f6cf5..a1adaaec09 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/delegate.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/delegate.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -36,6 +36,7 @@ from sardana.taurus.qt.qtgui.extra_macroexecutor import globals + class SequenceEditorDelegate(Qt.QItemDelegate): def __init__(self, parent=None): @@ -59,7 +60,6 @@ def paint(self, painter, option, index): else: Qt.QItemDelegate.paint(self, painter, option, index) - def createEditor(self, parent, option, index): if index.column() == 3: return Qt.QCheckBox(parent) @@ -68,7 +68,7 @@ def createEditor(self, parent, option, index): def setEditorData(self, editor, index): node = index.model().mapToSource(index).internalPointer() - if index.column() == 3: #and isinstance(node, MacroNode): + if index.column() == 3: # and isinstance(node, MacroNode): editor.setChecked(node.isPause()) else: Qt.QItemDelegate.setEditorData(self, editor, index) @@ -77,6 +77,7 @@ def setModelData(self, editor, model, index): if index.column() == 3: model.setData(index, Qt.QVariant(editor.isChecked())) + class MacroParametersProxyDelegate(Qt.QItemDelegate): def __init__(self, parent=None): @@ -103,13 +104,14 @@ def createEditor(self, parent, option, index): def setEditorData(self, editor, index): if index.column() == 1: - text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) + text = Qt.from_qvariant(index.model().data( + index, Qt.Qt.DisplayRole), str) if text in ["None", "", None]: Qt.QItemDelegate.setEditorData(self, editor, index) else: node = index.model().mapToSource(index).internalPointer() paramType = node.type() - if paramType in globals.EDITOR_COMBOBOX_PARAMS : + if paramType in globals.EDITOR_COMBOBOX_PARAMS: i = editor.findText(text) if i == -1: i = 0 @@ -134,7 +136,8 @@ def setModelData(self, editor, model, index): def sizeHint(self, option, index): if index.column() == 0: fm = option.fontMetrics - text = Qt.from_qvariant(index.model().data(index, Qt.Qt.DisplayRole), str) + text = Qt.from_qvariant(index.model().data( + index, Qt.Qt.DisplayRole), str) document = Qt.QTextDocument() document.setDefaultFont(option.font) document.setHtml(text) @@ -151,5 +154,3 @@ def sizeHint(self, option, index): else: size = Qt.QItemDelegate.sizeHint(self, option, index) return size - - diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/model.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/model.py index 3b263c50db..6616098513 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/model.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/model.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -65,7 +65,7 @@ def flags(self, index): elif column == 1: if isinstance(node, macro.SingleParamNode) and \ - not node.type() == "User": + not node.type() == "User": flags |= Qt.Qt.ItemIsEditable else: flags |= Qt.Qt.ItemIsSelectable @@ -85,10 +85,12 @@ def flags(self, index): def _insertRow(self, parentIndex, node=None, row=-1): parentNode = self.nodeFromIndex(parentIndex) - if row == -1: row = len(parentNode) + if row == -1: + row = len(parentNode) if isinstance(parentNode, macro.RepeatParamNode): - if node == None: node = parentNode.newRepeat() + if node == None: + node = parentNode.newRepeat() self.beginInsertRows(parentIndex, row, row) row = parentNode.insertChild(node, row) @@ -181,28 +183,31 @@ def data(self, index, role): return Qt.QVariant(Qt.QIcon(":/actions/media-playback-pause.svg")) return Qt.QVariant() - def setData (self, index, value, role=Qt.Qt.EditRole): + def setData(self, index, value, role=Qt.Qt.EditRole): node = self.nodeFromIndex(index) if index.column() == 1: if isinstance(node, macro.SingleParamNode): node.setValue(Qt.from_qvariant(value, str)) - self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) + self.emit( + Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) while True: index = index.parent() node = self.nodeFromIndex(index) if isinstance(node, macro.MacroNode): - self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index.sibling(index.row(), self.columnCount(index) - 1)) + self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index.sibling( + index.row(), self.columnCount(index) - 1)) break elif index.column() == 2: progress = Qt.from_qvariant(value, float) node.setProgress(progress) - self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) + self.emit( + Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) elif index.column() == 3: node.setPause(Qt.from_qvariant(value, bool)) - self.emit(Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) + self.emit( + Qt.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index) return True - def headerData(self, section, orientation, role): if orientation == Qt.Qt.Horizontal and role == Qt.Qt.DisplayRole: return Qt.QVariant(self.headers[section]) @@ -259,7 +264,7 @@ def assignIds(self): """ Assigns ids for all macros present in the sequence. If certain macro already had an id, it stays without change. A list of all ids is returned - + :return: (list) """ parentNode = self.root() @@ -374,6 +379,7 @@ def filterAcceptsRow(self, row, parentIndex): node = self.sourceModel().nodeFromIndex(child) return isinstance(node, macro.MacroNode) + class MacroParametersProxyModel(Qt.QSortFilterProxyModel): def __init__(self, parent=None): @@ -413,6 +419,3 @@ def filterAcceptsRow(self, row, parentIndex): if not isinstance(node, macro.ParamNode): return False return True - - - diff --git a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/sequenceeditor.py b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/sequenceeditor.py index e198ed18a4..f00810487c 100644 --- a/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/sequenceeditor.py +++ b/src/sardana/taurus/qt/qtgui/extra_macroexecutor/sequenceeditor/sequenceeditor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -51,6 +51,7 @@ from .model import MacroSequenceTreeModel, MacroSequenceProxyModel, MacroParametersProxyModel from .delegate import SequenceEditorDelegate + class HookAction(Qt.QAction): def __init__(self, text, parent, macroNode): @@ -74,6 +75,7 @@ def onToggle(self, trueFalse): else: self.macroNode().removeHookPlace(str(self.text())) + class MacroSequenceTree(Qt.QTreeView, BaseConfigurableClass): def __init__(self, parent=None): @@ -88,28 +90,42 @@ def __init__(self, parent=None): self.setDragEnabled(True) self.setAcceptDrops(True) self.setTabKeyNavigation(True) - self.setEditTriggers(Qt.QAbstractItemView.EditKeyPressed | Qt.QAbstractItemView.CurrentChanged) + self.setEditTriggers(Qt.QAbstractItemView.EditKeyPressed | + Qt.QAbstractItemView.CurrentChanged) self.setDropIndicatorShown(True) - self.deleteAction = Qt.QAction(getThemeIcon("list-remove"), "Remove macro", self) - self.connect(self.deleteAction, Qt.SIGNAL("triggered()"), self.deleteMacro) - self.deleteAction.setToolTip("Clicking this button will remove current macro.") + self.deleteAction = Qt.QAction( + getThemeIcon("list-remove"), "Remove macro", self) + self.connect(self.deleteAction, Qt.SIGNAL( + "triggered()"), self.deleteMacro) + self.deleteAction.setToolTip( + "Clicking this button will remove current macro.") self.moveUpAction = Qt.QAction(getThemeIcon("go-up"), "Move up", self) self.connect(self.moveUpAction, Qt.SIGNAL("triggered()"), self.upMacro) - self.moveUpAction.setToolTip("Clicking this button will move current macro up.") - - self.moveDownAction = Qt.QAction(getThemeIcon("go-down"), "Move down", self) - self.connect(self.moveDownAction, Qt.SIGNAL("triggered()"), self.downMacro) - self.moveDownAction.setToolTip("Clicking this button will move current macro down.") - - self.moveLeftAction = Qt.QAction(getThemeIcon("go-previous"), "Move left", self) - self.connect(self.moveLeftAction, Qt.SIGNAL("triggered()"), self.leftMacro) - self.moveLeftAction.setToolTip("Clicking this button will move current macro to the left.") - - self.moveRightAction = Qt.QAction(getThemeIcon("go-next"), "Move right", self) - self.connect(self.moveRightAction, Qt.SIGNAL("triggered()"), self.rightMacro) - self.moveRightAction.setToolTip("Clicking this button will move current macro to the right.") + self.moveUpAction.setToolTip( + "Clicking this button will move current macro up.") + + self.moveDownAction = Qt.QAction( + getThemeIcon("go-down"), "Move down", self) + self.connect(self.moveDownAction, Qt.SIGNAL( + "triggered()"), self.downMacro) + self.moveDownAction.setToolTip( + "Clicking this button will move current macro down.") + + self.moveLeftAction = Qt.QAction( + getThemeIcon("go-previous"), "Move left", self) + self.connect(self.moveLeftAction, Qt.SIGNAL( + "triggered()"), self.leftMacro) + self.moveLeftAction.setToolTip( + "Clicking this button will move current macro to the left.") + + self.moveRightAction = Qt.QAction( + getThemeIcon("go-next"), "Move right", self) + self.connect(self.moveRightAction, Qt.SIGNAL( + "triggered()"), self.rightMacro) + self.moveRightAction.setToolTip( + "Clicking this button will move current macro to the right.") def disableActions(self): self.deleteAction.setEnabled(False) @@ -122,11 +138,13 @@ def contextMenuEvent(self, event): contextMenu = Qt.QMenu() proxyIndex = self.indexAt(event.pos()) node = self.model().nodeFromIndex(proxyIndex) - #this is in case if we right click on an empty field of tree - if not isinstance(node, MacroNode): return + # this is in case if we right click on an empty field of tree + if not isinstance(node, MacroNode): + return parentNode = node.parent() - #this is in case if we right click on a top level macro - if not isinstance(parentNode, MacroNode): return + # this is in case if we right click on a top level macro + if not isinstance(parentNode, MacroNode): + return allowedHooks = parentNode.allowedHookPlaces() if allowedHooks: hookPlacesSubmenu = contextMenu.addMenu("Hook places") @@ -268,14 +286,16 @@ def prepareMacroProgresses(self): def setProgressForMacro(self, macroId, progress): persistentIndex = self._idIndexDict.get(macroId, None) - if persistentIndex == None: return + if persistentIndex == None: + return progressIndex = persistentIndex.sibling(persistentIndex.row(), 2) index = Qt.QModelIndex(progressIndex) self.model().setData(index, Qt.QVariant(progress)) def setRangeForMacro(self, macroId, range): persistentIndex = self._idIndexDict.get(macroId, None) - if persistentIndex == None: return + if persistentIndex == None: + return index = Qt.QModelIndex(persistentIndex) node = self.model().nodeFromIndex(index) node.setRange(range) @@ -300,11 +320,14 @@ class TaurusSequencerWidget(TaurusWidget): def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) - self._macroIds = [] #list representing all macros ids (all from sequence) currently executed + # list representing all macros ids (all from sequence) currently + # executed + self._macroIds = [] self._sequencesPath = str(Qt.QDir.homePath()) self._sequenceModel = MacroSequenceTreeModel() - self.registerConfigProperty("sequencesPath", "setSequencesPath", "sequencesPath") + self.registerConfigProperty( + "sequencesPath", "setSequencesPath", "sequencesPath") self.setLayout(Qt.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) @@ -326,45 +349,57 @@ def __init__(self, parent=None, designMode=False): actionsLayout = Qt.QHBoxLayout() actionsLayout.setContentsMargins(0, 0, 0, 0) - self.newSequenceAction = Qt.QAction(getThemeIcon("document-new"), "New", self) - self.connect(self.newSequenceAction, Qt.SIGNAL("triggered()"), self.onNewSequence) + self.newSequenceAction = Qt.QAction( + getThemeIcon("document-new"), "New", self) + self.connect(self.newSequenceAction, Qt.SIGNAL( + "triggered()"), self.onNewSequence) self.newSequenceAction.setToolTip("New sequence") self.newSequenceAction.setEnabled(False) newSequenceButton = Qt.QToolButton() newSequenceButton.setDefaultAction(self.newSequenceAction) actionsLayout.addWidget(newSequenceButton) - self.openSequenceAction = Qt.QAction(getThemeIcon("document-open"), "Open...", self) - self.connect(self.openSequenceAction, Qt.SIGNAL("triggered()"), self.onOpenSequence) + self.openSequenceAction = Qt.QAction( + getThemeIcon("document-open"), "Open...", self) + self.connect(self.openSequenceAction, Qt.SIGNAL( + "triggered()"), self.onOpenSequence) self.openSequenceAction.setToolTip("Open sequence...") openSequenceButton = Qt.QToolButton() openSequenceButton.setDefaultAction(self.openSequenceAction) actionsLayout.addWidget(openSequenceButton) - self.saveSequenceAction = Qt.QAction(getThemeIcon("document-save"), "Save...", self) - self.connect(self.saveSequenceAction, Qt.SIGNAL("triggered()"), self.onSaveSequence) + self.saveSequenceAction = Qt.QAction( + getThemeIcon("document-save"), "Save...", self) + self.connect(self.saveSequenceAction, Qt.SIGNAL( + "triggered()"), self.onSaveSequence) self.saveSequenceAction.setToolTip("Save sequence...") self.saveSequenceAction.setEnabled(False) saveSequenceButton = Qt.QToolButton() saveSequenceButton.setDefaultAction(self.saveSequenceAction) actionsLayout.addWidget(saveSequenceButton) - self.stopSequenceAction = Qt.QAction(getIcon(":/actions/media_playback_stop.svg"), "Stop", self) - self.connect(self.stopSequenceAction, Qt.SIGNAL("triggered()"), self.onStopSequence) + self.stopSequenceAction = Qt.QAction( + getIcon(":/actions/media_playback_stop.svg"), "Stop", self) + self.connect(self.stopSequenceAction, Qt.SIGNAL( + "triggered()"), self.onStopSequence) self.stopSequenceAction.setToolTip("Stop sequence") stopSequenceButton = Qt.QToolButton() stopSequenceButton.setDefaultAction(self.stopSequenceAction) actionsLayout.addWidget(stopSequenceButton) - self.pauseSequenceAction = Qt.QAction(getIcon(":/actions/media_playback_pause.svg"), "Pause", self) - self.connect(self.pauseSequenceAction, Qt.SIGNAL("triggered()"), self.onPauseSequence) + self.pauseSequenceAction = Qt.QAction( + getIcon(":/actions/media_playback_pause.svg"), "Pause", self) + self.connect(self.pauseSequenceAction, Qt.SIGNAL( + "triggered()"), self.onPauseSequence) self.pauseSequenceAction.setToolTip("Pause sequence") pauseSequenceButton = Qt.QToolButton() pauseSequenceButton.setDefaultAction(self.pauseSequenceAction) actionsLayout.addWidget(pauseSequenceButton) - self.playSequenceAction = Qt.QAction(getIcon(":/actions/media_playback_start.svg"), "Play", self) - self.connect(self.playSequenceAction, Qt.SIGNAL("triggered()"), self.onPlaySequence) + self.playSequenceAction = Qt.QAction( + getIcon(":/actions/media_playback_start.svg"), "Play", self) + self.connect(self.playSequenceAction, Qt.SIGNAL( + "triggered()"), self.onPlaySequence) self.playSequenceAction.setToolTip("Play sequence") playSequenceButton = Qt.QToolButton() playSequenceButton.setDefaultAction(self.playSequenceAction) @@ -374,13 +409,16 @@ def __init__(self, parent=None, designMode=False): actionsLayout.addWidget(self.doorStateLed) #@todo this feature will be replaced by checkboxes in the sequence tree view - #indicating clearing of the plot after execution - self.fullSequencePlotCheckBox = Qt.QCheckBox("Full sequence plot", self) - self.connect(self.fullSequencePlotCheckBox, Qt.SIGNAL("toggled(bool)"), self.setFullSequencePlot) + # indicating clearing of the plot after execution + self.fullSequencePlotCheckBox = Qt.QCheckBox( + "Full sequence plot", self) + self.connect(self.fullSequencePlotCheckBox, Qt.SIGNAL( + "toggled(bool)"), self.setFullSequencePlot) self.fullSequencePlotCheckBox.setChecked(True) actionsLayout.addWidget(self.fullSequencePlotCheckBox) - spacerItem = Qt.QSpacerItem(0, 0, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed) + spacerItem = Qt.QSpacerItem( + 0, 0, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed) actionsLayout.addItem(spacerItem) sequenceEditor.layout().addLayout(actionsLayout) @@ -392,12 +430,15 @@ def __init__(self, parent=None, designMode=False): self.macroComboBox = MacroComboBox(self) self.macroComboBox.setUseParentModel(True) self.macroComboBox.setModelColumn(0) - self.macroComboBox.setSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum) + self.macroComboBox.setSizePolicy( + Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum) macroLayout.addWidget(self.macroComboBox) - self.addMacroAction = Qt.QAction(getThemeIcon("list-add"), "Add macro...", self) + self.addMacroAction = Qt.QAction( + getThemeIcon("list-add"), "Add macro...", self) self.connect(self.addMacroAction, Qt.SIGNAL("triggered()"), self.onAdd) - self.addMacroAction.setToolTip("Clicking this button will add selected macro") + self.addMacroAction.setToolTip( + "Clicking this button will add selected macro") self.addMacroAction.setEnabled(False) addButton = Qt.QToolButton() addButton.setDefaultAction(self.addMacroAction) @@ -429,7 +470,8 @@ def __init__(self, parent=None, designMode=False): rightButton.setDefaultAction(self.tree.moveRightAction) rightButton.setEnabled(False) layout.addWidget(rightButton) - spacerItem = Qt.QSpacerItem(0, 40, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) + spacerItem = Qt.QSpacerItem( + 0, 40, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Expanding) layout.addItem(spacerItem) sequenceLayout.addLayout(layout) sequenceEditor.layout().addLayout(sequenceLayout) @@ -439,19 +481,23 @@ def __init__(self, parent=None, designMode=False): self.stackedWidget = Qt.QStackedWidget() splitter.addWidget(self.stackedWidget) - self.standardMacroParametersEditor = StandardMacroParametersEditor(self.stackedWidget) + self.standardMacroParametersEditor = StandardMacroParametersEditor( + self.stackedWidget) self.standardMacroParametersEditor.setModel(self.parametersProxyModel) - self.standardMacroParametersEditor.tree.setItemDelegate(ParamEditorDelegate(self.standardMacroParametersEditor.tree)) + self.standardMacroParametersEditor.tree.setItemDelegate( + ParamEditorDelegate(self.standardMacroParametersEditor.tree)) self.stackedWidget.addWidget(self.standardMacroParametersEditor) self.customMacroParametersEditor = None - self.connect(self.macroComboBox, Qt.SIGNAL("currentIndexChanged(QString)"), self.onMacroComboBoxChanged) - self.connect(self.tree, Qt.SIGNAL("macroChanged"), self.setMacroParametersRootIndex) - + self.connect(self.macroComboBox, Qt.SIGNAL( + "currentIndexChanged(QString)"), self.onMacroComboBoxChanged) + self.connect(self.tree, Qt.SIGNAL("macroChanged"), + self.setMacroParametersRootIndex) def contextMenuEvent(self, event): menu = Qt.QMenu() - action = menu.addAction(getThemeIcon("view-refresh"), "Check door state", self.checkDoorState) + action = menu.addAction(getThemeIcon( + "view-refresh"), "Check door state", self.checkDoorState) menu.exec_(event.globalPos()) def checkDoorState(self): @@ -478,7 +524,6 @@ def checkDoorState(self): self.pauseSequenceAction.setEnabled(False) self.stopSequenceAction.setEnabled(True) - def doorName(self): return self._doorName @@ -545,10 +590,11 @@ def onOpenSequence(self): sequencesPath = self.sequencesPath() fileName = str(Qt.QFileDialog.getOpenFileName(self, - "Choose a sequence to open...", - sequencesPath, - "*")) - if fileName == "": return + "Choose a sequence to open...", + sequencesPath, + "*")) + if fileName == "": + return #@todo: reset macroComboBox to index 0 try: file = open(fileName, 'r') @@ -569,7 +615,8 @@ def onOpenSequence(self): self.saveSequenceAction.setEnabled(True) self.playSequenceAction.setEnabled(True) except IOError: - Qt.QMessageBox.warning(self, "Error while loading macros sequence", "There was a problem while reading from file: %s" % fileName) + Qt.QMessageBox.warning(self, "Error while loading macros sequence", + "There was a problem while reading from file: %s" % fileName) self.tree.clearTree() self.newSequenceAction.setEnabled(False) self.saveSequenceAction.setEnabled(False) @@ -580,7 +627,8 @@ def onOpenSequence(self): self.saveSequenceAction.setEnabled(False) raise finally: - if not file is None: file.close() + if not file is None: + file.close() self.setSequencesPath(str.join("/", fileName.rsplit("/")[:-1])) self.emit(Qt.SIGNAL("currentMacroChanged"), None) @@ -592,19 +640,22 @@ def onSaveSequence(self): sequencesPath = os.path.join(sequencesPath, "Untitled.xml") fileName = str(Qt.QFileDialog.getSaveFileName(self, - "Choose a sequence file name...", - sequencesPath, - "*.xml")) - if fileName == "": return + "Choose a sequence file name...", + sequencesPath, + "*.xml")) + if fileName == "": + return try: file = open(fileName, "w") file.write(self.tree.toXmlString(pretty=True, withId=False)) self.setSequencesPath(str.join("/", fileName.rsplit("/")[:-1])) except Exception, e: - Qt.QMessageBox.warning(self, "Error while saving macros sequence", "There was a problem while writing to the file: %s" % fileName) + Qt.QMessageBox.warning(self, "Error while saving macros sequence", + "There was a problem while writing to the file: %s" % fileName) print e finally: - if not file is None: file.close() + if not file is None: + file.close() def onPlaySequence(self): door = Device(self.doorName()) @@ -655,12 +706,16 @@ def onPauseSequence(self): def onMacroStatusUpdated(self, data): macro = data[0] - if macro is None: return + if macro is None: + return data = data[1][0] - state, range, step, id = str(data["state"]), data["range"], data["step"], data["id"] - if id is None: return + state, range, step, id = str(data["state"]), data[ + "range"], data["step"], data["id"] + if id is None: + return id = int(id) - if not id in self.macroIds(): return + if not id in self.macroIds(): + return macroName = macro.name shortMessage = "" if state == "start": @@ -673,7 +728,8 @@ def onMacroStatusUpdated(self, data): self.stopSequenceAction.setEnabled(True) if id == self.firstMacroId(): self.emit(Qt.SIGNAL("plotablesFilterChanged"), None) - self.emit(Qt.SIGNAL("plotablesFilterChanged"), standardPlotablesFilter) + self.emit(Qt.SIGNAL("plotablesFilterChanged"), + standardPlotablesFilter) shortMessage = "Sequence started." elif not self.isFullSequencePlot(): self.emit(Qt.SIGNAL("plotablesFilterChanged"), None) @@ -703,7 +759,8 @@ def onMacroStatusUpdated(self, data): self.stopSequenceAction.setEnabled(False) shortMessage = "Macro %s error." % macroName exc_value, exc_stack = data['exc_value'], data['exc_stack'] - exceptionDialog = TaurusMessageBox(MacroRunException, exc_value, exc_stack) + exceptionDialog = TaurusMessageBox( + MacroRunException, exc_value, exc_stack) exceptionDialog.exec_() elif state == 'abort': self.playSequenceAction.setText("Start sequence") @@ -759,7 +816,8 @@ def setMacroParametersRootIndex(self, sourceIndex): self.customMacroParametersEditor.setModel(parametersModel) self.customMacroParametersEditor.setRootIndex(proxyIndex) self.stackedWidget.addWidget(self.customMacroParametersEditor) - self.stackedWidget.setCurrentWidget(self.customMacroParametersEditor) + self.stackedWidget.setCurrentWidget( + self.customMacroParametersEditor) else: self.standardMacroParametersEditor.tree.setRootIndex(proxyIndex) self.standardMacroParametersEditor.tree.expandAll() @@ -808,10 +866,12 @@ def fromPlainText(self, plainText): def setModel(self, model): oldModelObj = self.getModelObj() if oldModelObj is not None: - self.disconnect(oldModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated) + self.disconnect(oldModelObj, Qt.SIGNAL( + "macrosUpdated"), self.macroComboBox.onMacrosUpdated) TaurusWidget.setModel(self, model) newModelObj = self.getModelObj() - self.connect(newModelObj, Qt.SIGNAL("macrosUpdated"), self.macroComboBox.onMacrosUpdated) + self.connect(newModelObj, Qt.SIGNAL("macrosUpdated"), + self.macroComboBox.onMacrosUpdated) @classmethod def getQtDesignerPluginInfo(cls): @@ -833,11 +893,13 @@ def initComponents(self): self.taurusSequencerWidget.setUseParentModel(True) self.registerConfigDelegate(self.taurusSequencerWidget) self.setCentralWidget(self.taurusSequencerWidget) - self.connect(self.taurusSequencerWidget, Qt.SIGNAL('shortMessageEmitted'), self.onShortMessage) + self.connect(self.taurusSequencerWidget, Qt.SIGNAL( + 'shortMessageEmitted'), self.onShortMessage) self.statusBar().showMessage("Sequencer ready") def setCustomMacroEditorPaths(self, customMacroEditorPaths): - MacroExecutionWindow.setCustomMacroEditorPaths(self, customMacroEditorPaths) + MacroExecutionWindow.setCustomMacroEditorPaths( + self, customMacroEditorPaths) ParamEditorManager().parsePaths(customMacroEditorPaths) ParamEditorManager().browsePaths() @@ -848,10 +910,13 @@ def loadSettings(self): def onDoorChanged(self, doorName): MacroExecutionWindow.onDoorChanged(self, doorName) if self._qDoor: - Qt.QObject.disconnect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusSequencerWidget.onMacroStatusUpdated) - if doorName == "": return + Qt.QObject.disconnect(self._qDoor, Qt.SIGNAL( + "macroStatusUpdated"), self.taurusSequencerWidget.onMacroStatusUpdated) + if doorName == "": + return self._qDoor = Device(doorName) - Qt.QObject.connect(self._qDoor, Qt.SIGNAL("macroStatusUpdated"), self.taurusSequencerWidget.onMacroStatusUpdated) + Qt.QObject.connect(self._qDoor, Qt.SIGNAL( + "macroStatusUpdated"), self.taurusSequencerWidget.onMacroStatusUpdated) self.taurusSequencerWidget.onDoorChanged(doorName) @classmethod @@ -862,22 +927,26 @@ def getQtDesignerPluginInfo(cls): def createSequencerWidget(args): sequencer = TaurusSequencerWidget() sequencer.setModelInConfig(True) - Qt.QObject.connect(sequencer, Qt.SIGNAL("doorChanged"), sequencer.onDoorChanged) + Qt.QObject.connect(sequencer, Qt.SIGNAL( + "doorChanged"), sequencer.onDoorChanged) if len(args) == 2: sequencer.setModel(args[0]) sequencer.emit(Qt.SIGNAL('doorChanged'), args[1]) return sequencer + def createSequencer(args): sequencer = TaurusSequencer() sequencer.setModelInConfig(True) - Qt.QObject.connect(sequencer, Qt.SIGNAL("doorChanged"), sequencer.onDoorChanged) + Qt.QObject.connect(sequencer, Qt.SIGNAL( + "doorChanged"), sequencer.onDoorChanged) if len(args) == 2: sequencer.setModel(args[0]) sequencer.emit(Qt.SIGNAL('doorChanged'), args[1]) sequencer.loadSettings() return sequencer + def main(): from taurus.qt.qtgui.application import TaurusApplication import taurus diff --git a/src/sardana/taurus/qt/qtgui/extra_pool/__init__.py b/src/sardana/taurus/qt/qtgui/extra_pool/__init__.py index d8db3513d4..561d1259a9 100644 --- a/src/sardana/taurus/qt/qtgui/extra_pool/__init__.py +++ b/src/sardana/taurus/qt/qtgui/extra_pool/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/taurus/qt/qtgui/extra_pool/motor.py b/src/sardana/taurus/qt/qtgui/extra_pool/motor.py index 2d1e59dabd..3262e77411 100644 --- a/src/sardana/taurus/qt/qtgui/extra_pool/motor.py +++ b/src/sardana/taurus/qt/qtgui/extra_pool/motor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -35,7 +35,8 @@ def showDialogConfigureMotor(parent): Dialog = Qt.QDialog(parent) - Dialog.resize((Qt.QSize(Qt.QRect(0, 0, 310, 309).size()).expandedTo(Dialog.minimumSizeHint()))) + Dialog.resize((Qt.QSize(Qt.QRect(0, 0, 310, 309).size() + ).expandedTo(Dialog.minimumSizeHint()))) motorV2 = TaurusMotorV2(Dialog) motorV2.setModel(parent.model) motorV2.setGeometry(Qt.QRect(10, 10, 291, 291)) @@ -49,9 +50,11 @@ class TaurusMotorH(Qt.QWidget, TaurusBaseWidget): def __init__(self, parent=None, designMode=False): self.call__init__wo_kw(Qt.QWidget, parent) - self.call__init__(TaurusBaseWidget, str(self.objectName()), designMode=designMode) + self.call__init__(TaurusBaseWidget, str( + self.objectName()), designMode=designMode) self.loadUi() - Qt.QObject.connect(self.ui.config, Qt.SIGNAL("clicked()"), self.configureMotor) + Qt.QObject.connect(self.ui.config, Qt.SIGNAL( + "clicked()"), self.configureMotor) def sizeHint(self): return Qt.QSize(330, 50) @@ -83,7 +86,6 @@ def setModel(self, model): def resetModel(self): self.ui.TaurusGroupBox.resetModel() - @Qt.pyqtSignature("getShowText()") def getShowText(self): return self.ui.TaurusGroupBox.getShowText() @@ -107,9 +109,11 @@ class TaurusMotorH2(Qt.QWidget, TaurusBaseWidget): def __init__(self, parent=None, designMode=False): self.call__init__wo_kw(Qt.QWidget, parent) - self.call__init__(TaurusBaseWidget, str(self.objectName()), designMode=designMode) + self.call__init__(TaurusBaseWidget, str( + self.objectName()), designMode=designMode) self.loadUi() - Qt.QObject.connect(self.ui.config, Qt.SIGNAL("clicked()"), self.configureMotor) + Qt.QObject.connect(self.ui.config, Qt.SIGNAL( + "clicked()"), self.configureMotor) def sizeHint(self): return Qt.QSize(215, 85) @@ -141,7 +145,6 @@ def setModel(self, model): def resetModel(self): self.ui.TaurusGroupBox.resetModel() - @Qt.pyqtSignature("getShowText()") def getShowText(self): return self.ui.TaurusGroupBox.getShowText() @@ -154,7 +157,6 @@ def setShowText(self, showText): def resetShowText(self): self.ui.TaurusGroupBox.resetShowText() - model = Qt.pyqtProperty("QString", getModel, setModel, resetModel) showText = Qt.pyqtProperty("bool", getShowText, setShowText, resetShowText) @@ -166,9 +168,11 @@ class TaurusMotorV(Qt.QWidget, TaurusBaseWidget): def __init__(self, parent=None, designMode=False): self.call__init__wo_kw(Qt.QWidget, parent) - self.call__init__(TaurusBaseWidget, str(self.objectName()), designMode=designMode) - self.loadUi() - Qt.QObject.connect(self.ui.config, Qt.SIGNAL("clicked()"), self.configureMotor) + self.call__init__(TaurusBaseWidget, str( + self.objectName()), designMode=designMode) + self.loadUi() + Qt.QObject.connect(self.ui.config, Qt.SIGNAL( + "clicked()"), self.configureMotor) def sizeHint(self): return Qt.QSize(120, 145) @@ -200,7 +204,6 @@ def setModel(self, model): def resetModel(self): self.ui.TaurusGroupBox.resetModel() - @Qt.pyqtSignature("getShowText()") def getShowText(self): return self.ui.TaurusGroupBox.getShowText() @@ -213,7 +216,6 @@ def setShowText(self, showText): def resetShowText(self): self.ui.TaurusGroupBox.resetShowText() - model = Qt.pyqtProperty("QString", getModel, setModel, resetModel) showText = Qt.pyqtProperty("bool", getShowText, setShowText, resetShowText) @@ -225,7 +227,8 @@ class TaurusMotorV2(Qt.QWidget, TaurusBaseWidget): def __init__(self, parent=None, designMode=False): self.call__init__wo_kw(Qt.QWidget, parent) - self.call__init__(TaurusBaseWidget, str(self.objectName()), designMode=designMode) + self.call__init__(TaurusBaseWidget, str( + self.objectName()), designMode=designMode) self.loadUi() def sizeHint(self): @@ -255,7 +258,6 @@ def setModel(self, model): def resetModel(self): self.ui.TaurusGroupBox.resetModel() - @Qt.pyqtSignature("getShowText()") def getShowText(self): return self.ui.TaurusGroupBox.getShowText() @@ -268,7 +270,6 @@ def setShowText(self, showText): def resetShowText(self): self.ui.TaurusGroupBox.resetShowText() - model = Qt.pyqtProperty("QString", getModel, setModel, resetModel) showText = Qt.pyqtProperty("bool", getShowText, setShowText, resetShowText) diff --git a/src/sardana/taurus/qt/qtgui/extra_pool/poolchannel.py b/src/sardana/taurus/qt/qtgui/extra_pool/poolchannel.py index 042b24472c..c09494e515 100644 --- a/src/sardana/taurus/qt/qtgui/extra_pool/poolchannel.py +++ b/src/sardana/taurus/qt/qtgui/extra_pool/poolchannel.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -39,14 +39,17 @@ class _ParentDevButton(TaurusDevButton): '''A TaurusDevButton that receives an attribute name but sets the corresponding device as model. **For internal use only** ''' + def __init__(self, **kwargs): TaurusDevButton.__init__(self, **kwargs) self.setText('') self.setSizePolicy(Qt.QSizePolicy.Preferred, Qt.QSizePolicy.Maximum) def setModel(self, model): - try: attr = taurus.Attribute(model) - except: return + try: + attr = taurus.Attribute(model) + except: + return dev = attr.getParentObj() devname = dev.getFullName() TaurusDevButton.setModel(self, devname) @@ -57,6 +60,7 @@ class PoolChannelTV(TaurusValue): It differs from :class:`PoolChannel` in that it behaves as a TaurusValue (i.e., it allows its subwidgets to be aligned in columns in a TaurusForm)` ''' + def __init__(self, parent=None, designMode=False): TaurusValue.__init__(self, parent=parent, designMode=designMode) self.setLabelWidgetClass(LabelWidgetDragsDeviceAndAttribute) @@ -67,36 +71,42 @@ def getDefaultExtraWidgetClass(self): def setModel(self, model): if model is not None: - model = "%s/value" % model #@todo: change this (it assumes tango naming!) + # @todo: change this (it assumes tango naming!) + model = "%s/value" % model TaurusValue.setModel(self, model) def showEvent(self, event): TaurusValue.showEvent(self, event) - try: self.getModelObj().getParentObj().getAttribute('Value').enablePolling(force=True) - except: pass + try: + self.getModelObj().getParentObj().getAttribute('Value').enablePolling(force=True) + except: + pass def hideEvent(self, event): TaurusValue.hideEvent(self, event) - try: self.getModelObj().getParentObj().getAttribute('Value').disablePolling() - except: pass - + try: + self.getModelObj().getParentObj().getAttribute('Value').disablePolling() + except: + pass class PoolChannel(TaurusWidget): ''' A widget that displays and controls a pool channel device - + .. seealso:: :class:`PoolChannelTV` ''' + def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent) self.setLayout(Qt.QHBoxLayout()) - #put a widget with a TaurusValue + # put a widget with a TaurusValue w = Qt.QWidget() w.setLayout(Qt.QGridLayout()) self._TaurusValue = TaurusValue(parent=w, designMode=designMode) - self._TaurusValue.setLabelWidgetClass(LabelWidgetDragsDeviceAndAttribute) + self._TaurusValue.setLabelWidgetClass( + LabelWidgetDragsDeviceAndAttribute) self._TaurusValue.setLabelConfig('dev_alias') self.layout().addWidget(w) @@ -105,7 +115,8 @@ def __init__(self, parent=None, designMode=False): self._devButton.setText('') self.layout().addWidget(self._devButton) - self.connect(self, Qt.SIGNAL('modelChanged(const QString &)'), self._updateTaurusValue) + self.connect(self, Qt.SIGNAL( + 'modelChanged(const QString &)'), self._updateTaurusValue) def _updateTaurusValue(self): m = self.getModelName() @@ -113,7 +124,7 @@ def _updateTaurusValue(self): self._devButton.setModel(m) -#if __name__ == '__main__': +# if __name__ == '__main__': # import sys # app = Qt.QApplication(sys.argv) # diff --git a/src/sardana/taurus/qt/qtgui/extra_pool/poolioregister.py b/src/sardana/taurus/qt/qtgui/extra_pool/poolioregister.py index e2d8bf8196..c54095f213 100644 --- a/src/sardana/taurus/qt/qtgui/extra_pool/poolioregister.py +++ b/src/sardana/taurus/qt/qtgui/extra_pool/poolioregister.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -41,18 +41,23 @@ import taurus + class PoolIORegisterReadWidget(TaurusLabel): ''' This class is intended to be used as a read widget of a TaurusValue with IORegister devices. After setting the model, it gets the Labels and creates a filter to show them instead of the values. ''' + def __init__(self, parent=None, designMode=False): TaurusLabel.__init__(self, parent, designMode) def setModel(self, model): - TaurusLabel.setModel(self, '%s/value' % model) #@todo: change this (it assumes tango naming!) + # @todo: change this (it assumes tango naming!) + TaurusLabel.setModel(self, '%s/value' % model) - try: ior_dev = taurus.Device(model) - except: return + try: + ior_dev = taurus.Device(model) + except: + return labels = ior_dev.getAttribute('Labels').read().value labels_list = labels.split(' ') @@ -64,7 +69,7 @@ def setModel(self, model): # @TODO: Some day filters will work again... # until then, it is better to NOT have the filter # so at least we see a value and not '------' - #self.setEventFilters([self.readEventValueMap]) + # self.setEventFilters([self.readEventValueMap]) ########################################################## # FILTERS ARE NOT WORKING AS OF SVN:17541 @@ -93,19 +98,24 @@ def getFormatedToolTip(self, cache=True): def getQtDesignerPluginInfo(cls): return None + class PoolIORegisterWriteWidget(TaurusValueComboBox): ''' This class is intended to be used as a write widget of a TaurusValue with IORegister devices. After setting the model, it gets the Labels and populates the combobox. It has AutoApply set to True. ''' + def __init__(self, parent=None, designMode=False): TaurusValueComboBox.__init__(self, parent, designMode) TaurusValueComboBox.setForcedApply(self, True) def setModel(self, model): - TaurusValueComboBox.setModel(self, '%s/value' % model) #@todo: change this (it assumes tango naming!) + # @todo: change this (it assumes tango naming!) + TaurusValueComboBox.setModel(self, '%s/value' % model) - try: ior_dev = taurus.Device(model) - except: return + try: + ior_dev = taurus.Device(model) + except: + return labels = ior_dev.getAttribute('Labels').read().value labels_list = labels.split(' ') @@ -117,14 +127,17 @@ def setModel(self, model): self.writeValueNames.append((label, value)) self.setValueNames(self.writeValueNames) + @classmethod def getQtDesignerPluginInfo(cls): return None + class PoolIORegisterTV(TaurusValue): ''' A widget that displays and controls a pool IORegister device. It behaves as a TaurusValue. ''' + def __init__(self, parent=None, designMode=False): TaurusValue.__init__(self, parent=parent, designMode=designMode) self.setLabelWidgetClass(LabelWidgetDragsDeviceAndAttribute) @@ -135,8 +148,10 @@ def __init__(self, parent=None, designMode=False): def setModel(self, model): TaurusValue.setModel(self, model) - try: self.ioreg_dev = taurus.Device(model) - except: return + try: + self.ioreg_dev = taurus.Device(model) + except: + return def showEvent(self, event): TaurusValue.showEvent(self, event) @@ -155,6 +170,7 @@ class PoolIORegister(TaurusWidget): NOTE: It would be nice to provide 'ABORT' button if the device allows it. NOTE: It would be nice to set icons for each possible value label. ''' + def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) @@ -175,8 +191,10 @@ def __init__(self, parent=None, designMode=False): self.layout().addWidget(self.write_widget) def setModel(self, model): - try: self.ioreg_dev = taurus.Device(model) - except: return + try: + self.ioreg_dev = taurus.Device(model) + except: + return self.alias_label.setModel('%s/State?configuration=dev_alias' % model) self.read_widget.setModel(model) @@ -200,10 +218,11 @@ class PoolIORegisterButtons(TaurusWidget): NOTE: It would be nice to provide 'ABORT' button if the device allows it. NOTE: It would be nice to set icons for each possible value label. ''' + def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.loadUi() - + self.ioreg_dev = None self.alias_label = TaurusLabel() @@ -219,14 +238,16 @@ def __init__(self, parent=None, designMode=False): self.ui.lo_state_read.addWidget(self.value_label) def setModel(self, model): - try: self.ioreg_dev = taurus.Device(model) - except: return + try: + self.ioreg_dev = taurus.Device(model) + except: + return self.alias_label.setModel('%s/State?configuration=dev_alias' % model) self.value_label.setModel(model) # Empty previous buttons - #self.ui.lo_buttons_write. + # self.ui.lo_buttons_write. for button in self.button_value_dict.keys(): self.disconnect(button, Qt.SIGNAL('clicked'), self.writeValue) button.deleteLater() @@ -260,10 +281,9 @@ def hideEvent(self, event): self.ioreg_dev.getAttribute('Value').disablePolling() - def test_form(): from taurus.qt.qtgui.panel import TaurusForm - tgclass_map = {'IORegister':PoolIORegisterTV} + tgclass_map = {'IORegister': PoolIORegisterTV} form = TaurusForm() form.setCustomWidgetMap(tgclass_map) model = 'tango://controls02:10000/ioregister/gc_tgiorctrl/1' @@ -273,6 +293,7 @@ def test_form(): form.setModel([model]) form.show() + def test_widget(): w = PoolIORegister() model = 'tango://controls02:10000/ioregister/gc_tgiorctrl/1' @@ -282,6 +303,7 @@ def test_widget(): w.setModel(model) w.show() + def test_buttons(): w = PoolIORegisterButtons() model = 'tango://controls02:10000/ioregister/gc_tgiorctrl/1' @@ -295,8 +317,8 @@ def test_buttons(): import sys app = Qt.QApplication(sys.argv) - #test_form() - #test_widget() + # test_form() + # test_widget() test_buttons() sys.exit(app.exec_()) diff --git a/src/sardana/taurus/qt/qtgui/extra_pool/poolmotor.py b/src/sardana/taurus/qt/qtgui/extra_pool/poolmotor.py index a059a3e86e..153e79533b 100644 --- a/src/sardana/taurus/qt/qtgui/extra_pool/poolmotor.py +++ b/src/sardana/taurus/qt/qtgui/extra_pool/poolmotor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -63,6 +63,7 @@ class LimitsListener(Qt.QObject): If that is the case it emits a signal so the application can do whatever with it. """ + def __init__(self): Qt.QObject.__init__(self) @@ -72,9 +73,11 @@ def eventReceived(self, evt_src, evt_type, evt_value): limits = evt_value.value self.emit(Qt.SIGNAL('updateLimits(PyQt_PyObject)'), limits.tolist()) + class PoolMotorClient(): maxint_in_32_bits = 2147483647 + def __init__(self): self.motor_dev = None self.has_limits = False @@ -107,7 +110,8 @@ def jogNeg(self): if hasattr(self.motor_dev, 'step_per_unit'): neg_limit = neg_limit / self.motor_dev['step_per_unit'].value try: - min_value = self.motor_dev.getAttribute('Position').getConfig().getValueObj().min_value + min_value = self.motor_dev.getAttribute( + 'Position').getConfig().getValueObj().min_value neg_limit = float(min_value) except Exception: pass @@ -120,7 +124,8 @@ def jogPos(self): if hasattr(self.motor_dev, 'step_per_unit'): pos_limit = pos_limit / self.motor_dev['step_per_unit'].value try: - max_value = self.motor_dev.getAttribute('Position').getConfig().getValueObj().max_value + max_value = self.motor_dev.getAttribute( + 'Position').getConfig().getValueObj().max_value pos_limit = float(max_value) except Exception: pass @@ -132,8 +137,10 @@ def goHome(self): def abort(self): self.motor_dev.abort() + class LabelWidgetDragsDeviceAndAttribute(DefaultLabelWidget): """ Offer richer mime data with taurus-device, taurus-attribute, and plain-text. """ + def mouseMoveEvent(self, event): model = self.taurusValueBuddy().getModelName() mimeData = Qt.QMimeData() @@ -148,6 +155,7 @@ def mouseMoveEvent(self, event): drag.setHotSpot(event.pos() - self.rect().topLeft()) drag.start(Qt.Qt.CopyAction) + class PoolMotorConfigurationForm(TaurusAttrForm): def __init__(self, parent=None, designMode=False): @@ -166,8 +174,8 @@ def getMotorControllerType(self): for motorInfo in poolMotorInfos: # BE CAREFUL, THIS ONLY WORKS IF NOBODY CHANGES THE DEVICE NAME OF A MOTOR!!! # ALSO THERE COULD BE A CASE PROBLEM, BETTER DO COMPARISONS WITH .lower() - #to better understand following actions - #this is an example of one motor info record + # to better understand following actions + # this is an example of one motor info record #'dummymotor10 (motor/dummymotorctrl/10) (dummymotorctrl/10) Motor', motorInfos = motorInfo.split() if modelNormalName.lower() == motorInfos[1][1:-1].lower(): @@ -175,8 +183,8 @@ def getMotorControllerType(self): poolControllerInfos = pool["ControllerList"].value for controllerInfo in poolControllerInfos: - #to better understand following actions - #this is an example of one controller info record + # to better understand following actions + # this is an example of one controller info record #'dummymotorctrl (DummyMotorController.DummyMotorController/dummymotorctrl) - Motor Python ctrl (DummyMotorController.py)' controllerInfos = controllerInfo.split() if controllerName.lower() == controllerInfos[0].lower(): @@ -246,7 +254,7 @@ def getDisplayAttributes(self, controllerType): attributes.extend(["motoractivated", "negativeendlimitset", "positiveendlimitset", - "extendedservoalgorithmenabled" + "extendedservoalgorithmenabled" "amplifierenabled", "openloopmode", "movetimeractive", @@ -290,7 +298,8 @@ def setModel(self, modelName): controllerType = self.getMotorControllerType() attributes = self.getDisplayAttributes(controllerType) #self.setViewFilters([lambda a: a.name.lower() in attributes]) - self.setSortKey(lambda att: attributes.index(att.name.lower()) if att.name.lower() in attributes else 1) + self.setSortKey(lambda att: attributes.index( + att.name.lower()) if att.name.lower() in attributes else 1) @UILoadable(with_ui='ui') @@ -318,8 +327,10 @@ def __init__(self, parent=None, designMode=False): # CREATE THE TaurusValue that can not be configured in the Designer self.taurus_value = TaurusValue(self.ui.taurusValueContainer) - # Use a DragDevAndAttributeLabelWidget to provide a richer QMimeData content - self.taurus_value.setLabelWidgetClass(LabelWidgetDragsDeviceAndAttribute) + # Use a DragDevAndAttributeLabelWidget to provide a richer QMimeData + # content + self.taurus_value.setLabelWidgetClass( + LabelWidgetDragsDeviceAndAttribute) # Make the label to be the device alias self.taurus_value.setLabelConfig('dev_alias') @@ -337,7 +348,8 @@ def __init__(self, parent=None, designMode=False): self.ui.btnCfg.setWidget(taurus_attr_form) self.ui.btnCfg.setUseParentModel(True) - # ADD AN EVENT FILTER FOR THE STATUS LABEL IN ORDER TO PROVIDE JUST THE STRING FROM THE CONTROLLER (LAST LINE) + # ADD AN EVENT FILTER FOR THE STATUS LABEL IN ORDER TO PROVIDE JUST THE + # STRING FROM THE CONTROLLER (LAST LINE) def just_ctrl_status_line(evt_src, evt_type, evt_value): if evt_type not in [TaurusEventType.Change, TaurusEventType.Periodic]: return evt_src, evt_type, evt_value @@ -367,36 +379,52 @@ def just_ctrl_status_line(evt_src, evt_type, evt_value): self.__setTaurusIcons() self.ui.motorGroupBox.setContextMenuPolicy(Qt.Qt.CustomContextMenu) - self.connect(self.ui.motorGroupBox, Qt.SIGNAL('customContextMenuRequested(QPoint)'), self.buildContextMenu) + self.connect(self.ui.motorGroupBox, Qt.SIGNAL( + 'customContextMenuRequested(QPoint)'), self.buildContextMenu) self.connect(self.ui.btnGoToNeg, Qt.SIGNAL('clicked()'), self.jogNeg) - self.connect(self.ui.btnGoToNegPress, Qt.SIGNAL('pressed()'), self.jogNeg) - self.connect(self.ui.btnGoToNegPress, Qt.SIGNAL('released()'), self.abort) - self.connect(self.ui.btnGoToNegInc, Qt.SIGNAL('clicked()'), self.goToNegInc) + self.connect(self.ui.btnGoToNegPress, + Qt.SIGNAL('pressed()'), self.jogNeg) + self.connect(self.ui.btnGoToNegPress, + Qt.SIGNAL('released()'), self.abort) + self.connect(self.ui.btnGoToNegInc, Qt.SIGNAL( + 'clicked()'), self.goToNegInc) self.connect(self.ui.btnGoToPos, Qt.SIGNAL('clicked()'), self.jogPos) - self.connect(self.ui.btnGoToPosPress, Qt.SIGNAL('pressed()'), self.jogPos) - self.connect(self.ui.btnGoToPosPress, Qt.SIGNAL('released()'), self.abort) - self.connect(self.ui.btnGoToPosInc, Qt.SIGNAL('clicked()'), self.goToPosInc) + self.connect(self.ui.btnGoToPosPress, + Qt.SIGNAL('pressed()'), self.jogPos) + self.connect(self.ui.btnGoToPosPress, + Qt.SIGNAL('released()'), self.abort) + self.connect(self.ui.btnGoToPosInc, Qt.SIGNAL( + 'clicked()'), self.goToPosInc) self.connect(self.ui.btnHome, Qt.SIGNAL('clicked()'), self.goHome) self.connect(self.ui.btnStop, Qt.SIGNAL('clicked()'), self.abort) # ALSO UPDATE THE WIDGETS EVERYTIME THE FORM HAS TO BE SHOWN - self.connect(self.ui.btnCfg, Qt.SIGNAL('clicked()'), taurus_attr_form._updateAttrWidgets) - self.connect(self.ui.btnCfg, Qt.SIGNAL('clicked()'), self.buildBetterCfgDialogTitle) + self.connect(self.ui.btnCfg, Qt.SIGNAL('clicked()'), + taurus_attr_form._updateAttrWidgets) + self.connect(self.ui.btnCfg, Qt.SIGNAL('clicked()'), + self.buildBetterCfgDialogTitle) - ################################################################################################################# + ####################################################################### ######################################## # LET TAURUS CONFIGURATION MECANISM SHINE! ######################################## - self.registerConfigProperty(self.ui.inc.isVisible, self.toggleMoveRelative, 'MoveRelative') - self.registerConfigProperty(self.ui.btnGoToNegPress.isVisible, self.toggleMoveContinuous, 'MoveContinuous') - self.registerConfigProperty(self.ui.btnGoToNeg.isVisible, self.toggleMoveToLimits, 'MoveToLimits') - self.registerConfigProperty(self.ui.btnStop.isVisible, self.toggleStopMove, 'StopMove') - self.registerConfigProperty(self.ui.btnHome.isVisible, self.toggleHoming, 'Homing') - self.registerConfigProperty(self.ui.btnCfg.isVisible, self.toggleConfig, 'Config') - self.registerConfigProperty(self.ui.lblStatus.isVisible, self.toggleStatus, 'Status') - ################################################################################################################# + self.registerConfigProperty( + self.ui.inc.isVisible, self.toggleMoveRelative, 'MoveRelative') + self.registerConfigProperty( + self.ui.btnGoToNegPress.isVisible, self.toggleMoveContinuous, 'MoveContinuous') + self.registerConfigProperty( + self.ui.btnGoToNeg.isVisible, self.toggleMoveToLimits, 'MoveToLimits') + self.registerConfigProperty( + self.ui.btnStop.isVisible, self.toggleStopMove, 'StopMove') + self.registerConfigProperty( + self.ui.btnHome.isVisible, self.toggleHoming, 'Homing') + self.registerConfigProperty( + self.ui.btnCfg.isVisible, self.toggleConfig, 'Config') + self.registerConfigProperty( + self.ui.lblStatus.isVisible, self.toggleStatus, 'Status') + ####################################################################### def __setTaurusIcons(self): self.ui.btnMin.setText('') @@ -405,54 +433,59 @@ def __setTaurusIcons(self): self.ui.btnMax.setIcon(getIcon(':/actions/list-add.svg')) self.ui.btnGoToNeg.setText('') - self.ui.btnGoToNeg.setIcon(getIcon(':/actions/media_skip_backward.svg')) + self.ui.btnGoToNeg.setIcon( + getIcon(':/actions/media_skip_backward.svg')) self.ui.btnGoToNegPress.setText('') - self.ui.btnGoToNegPress.setIcon(getIcon(':/actions/media_seek_backward.svg')) + self.ui.btnGoToNegPress.setIcon( + getIcon(':/actions/media_seek_backward.svg')) self.ui.btnGoToNegInc.setText('') - self.ui.btnGoToNegInc.setIcon(getIcon(':/actions/media_playback_backward.svg')) + self.ui.btnGoToNegInc.setIcon( + getIcon(':/actions/media_playback_backward.svg')) self.ui.btnGoToPos.setText('') self.ui.btnGoToPos.setIcon(getIcon(':/actions/media_skip_forward.svg')) self.ui.btnGoToPosPress.setText('') - self.ui.btnGoToPosPress.setIcon(getIcon(':/actions/media_seek_forward.svg')) + self.ui.btnGoToPosPress.setIcon( + getIcon(':/actions/media_seek_forward.svg')) self.ui.btnGoToPosInc.setText('') - self.ui.btnGoToPosInc.setIcon(getIcon(':/actions/media_playback_start.svg')) + self.ui.btnGoToPosInc.setIcon( + getIcon(':/actions/media_playback_start.svg')) self.ui.btnStop.setText('') self.ui.btnStop.setIcon(getIcon(':/actions/media_playback_stop.svg')) self.ui.btnHome.setText('') self.ui.btnHome.setIcon(getIcon(':/actions/go-home.svg')) self.ui.btnCfg.setText('') self.ui.btnCfg.setIcon(getIcon(':/categories/preferences-system.svg')) - ################################################################################################################# - - + ####################################################################### #@Qt.pyqtSlot(list) def updateLimits(self, limits): - if isinstance(limits, dict): limits = limits["limits"] + if isinstance(limits, dict): + limits = limits["limits"] pos_lim = limits[1] pos_btnstylesheet = '' enabled = True if pos_lim: - pos_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet(PyTango.DevState.ALARM) + pos_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet( + PyTango.DevState.ALARM) enabled = False self.ui.btnMax.setStyleSheet(pos_btnstylesheet) self.ui.btnGoToPos.setEnabled(enabled) self.ui.btnGoToPosPress.setEnabled(enabled) self.ui.btnGoToPosInc.setEnabled(enabled) - neg_lim = limits[2] neg_btnstylesheet = '' enabled = True if neg_lim: - neg_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet(PyTango.DevState.ALARM) + neg_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet( + PyTango.DevState.ALARM) enabled = False self.ui.btnMin.setStyleSheet(neg_btnstylesheet) self.ui.btnGoToNeg.setEnabled(enabled) self.ui.btnGoToNegPress.setEnabled(enabled) self.ui.btnGoToNegInc.setEnabled(enabled) - #def sizeHint(self): + # def sizeHint(self): # return Qt.QSize(300,30) def goToNegInc(self): @@ -477,7 +510,8 @@ def buildContextMenu(self, point): action_move_absolute = Qt.QAction(self) action_move_absolute.setText('Move Absolute') action_move_absolute.setCheckable(True) - action_move_absolute.setChecked(self.taurus_value.writeWidget().isVisible()) + action_move_absolute.setChecked( + self.taurus_value.writeWidget().isVisible()) menu.addAction(action_move_absolute) action_move_relative = Qt.QAction(self) @@ -529,17 +563,28 @@ def buildContextMenu(self, point): action_status.setChecked(self.ui.lblStatus.isVisible()) menu.addAction(action_status) - self.connect(action_hide_all, Qt.SIGNAL('triggered()'), self.toggleHideAll) - self.connect(action_show_all, Qt.SIGNAL('triggered()'), self.toggleShowAll) - self.connect(action_move_absolute, Qt.SIGNAL('toggled(bool)'), self.toggleMoveAbsolute) - self.connect(action_move_relative, Qt.SIGNAL('toggled(bool)'), self.toggleMoveRelative) - self.connect(action_move_continuous, Qt.SIGNAL('toggled(bool)'), self.toggleMoveContinuous) - self.connect(action_move_to_limits, Qt.SIGNAL('toggled(bool)'), self.toggleMoveToLimits) - self.connect(action_encoder, Qt.SIGNAL('toggled(bool)'), self.toggleEncoder) - self.connect(action_stop_move, Qt.SIGNAL('toggled(bool)'), self.toggleStopMove) - self.connect(action_homing, Qt.SIGNAL('toggled(bool)'), self.toggleHoming) - self.connect(action_config, Qt.SIGNAL('toggled(bool)'), self.toggleConfig) - self.connect(action_status, Qt.SIGNAL('toggled(bool)'), self.toggleStatus) + self.connect(action_hide_all, Qt.SIGNAL( + 'triggered()'), self.toggleHideAll) + self.connect(action_show_all, Qt.SIGNAL( + 'triggered()'), self.toggleShowAll) + self.connect(action_move_absolute, Qt.SIGNAL( + 'toggled(bool)'), self.toggleMoveAbsolute) + self.connect(action_move_relative, Qt.SIGNAL( + 'toggled(bool)'), self.toggleMoveRelative) + self.connect(action_move_continuous, Qt.SIGNAL( + 'toggled(bool)'), self.toggleMoveContinuous) + self.connect(action_move_to_limits, Qt.SIGNAL( + 'toggled(bool)'), self.toggleMoveToLimits) + self.connect(action_encoder, Qt.SIGNAL( + 'toggled(bool)'), self.toggleEncoder) + self.connect(action_stop_move, Qt.SIGNAL( + 'toggled(bool)'), self.toggleStopMove) + self.connect(action_homing, Qt.SIGNAL( + 'toggled(bool)'), self.toggleHoming) + self.connect(action_config, Qt.SIGNAL( + 'toggled(bool)'), self.toggleConfig) + self.connect(action_status, Qt.SIGNAL( + 'toggled(bool)'), self.toggleStatus) menu.popup(self.cursor().pos()) @@ -615,7 +660,8 @@ def buildBetterCfgDialogTitle(self): while self.ui.btnCfg._dialog is None: pass model = self.getModel() - self.ui.btnCfg._dialog.setWindowTitle('%s config' % taurus.Factory().getDevice(model).getSimpleName()) + self.ui.btnCfg._dialog.setWindowTitle( + '%s config' % taurus.Factory().getDevice(model).getSimpleName()) @classmethod def getQtDesignerPluginInfo(cls): @@ -633,7 +679,6 @@ def showEvent(self, event): except AttributeError, e: self.debug('Error in showEvent: %s', repr(e)) - def hideEvent(self, event): TaurusWidget.hideEvent(self, event) try: @@ -664,10 +709,12 @@ def setModel(self, model): self.taurus_value.setModel(model + '/Position') - # DUE TO A BUG IN TAURUSVALUE, THAT DO NOT USE PARENT MODEL WE NEED TO ALWAYS SET THE MODEL + # DUE TO A BUG IN TAURUSVALUE, THAT DO NOT USE PARENT MODEL WE NEED + # TO ALWAYS SET THE MODEL self.taurus_value.setUseParentModel(False) - # THE FORCED APPLY HAS TO BE DONE AFTER THE MODEL IS SET, SO THE WRITEWIDGET IS AVAILABLE + # THE FORCED APPLY HAS TO BE DONE AFTER THE MODEL IS SET, SO THE + # WRITEWIDGET IS AVAILABLE if self.taurus_value.writeWidget() is not None: self.taurus_value.writeWidget().setForcedApply(True) @@ -687,9 +734,10 @@ def setModel(self, model): self.unregisterConfigurableItem('Encoder') except: pass - self.registerConfigProperty(self.taurus_value.writeWidget().isVisible, self.toggleMoveAbsolute, 'MoveAbsolute') - self.registerConfigProperty(self.taurus_value_enc.isVisible, self.toggleEncoder, 'Encoder') - + self.registerConfigProperty(self.taurus_value.writeWidget( + ).isVisible, self.toggleMoveAbsolute, 'MoveAbsolute') + self.registerConfigProperty( + self.taurus_value_enc.isVisible, self.toggleEncoder, 'Encoder') # SINCE TAURUSLAUNCHERBUTTON HAS NOT THIS PROPERTY IN THE # DESIGNER, WE MUST SET IT HERE @@ -697,18 +745,21 @@ def setModel(self, model): # CONFIGURE A LISTENER IN ORDER TO UPDATE LIMIT SWITCHES STATES self.limits_listener = LimitsListener() - self.connect(self.limits_listener, Qt.SIGNAL('updateLimits(PyQt_PyObject)'), self.updateLimits) + self.connect(self.limits_listener, Qt.SIGNAL( + 'updateLimits(PyQt_PyObject)'), self.updateLimits) limits_visible = False if self.has_limits: - limits_attribute = self.motor_dev.getAttribute('Limit_switches') + limits_attribute = self.motor_dev.getAttribute( + 'Limit_switches') limits_attribute.addListener(self.limits_listener) - #self.updateLimits(limits_attribute.read().value) + # self.updateLimits(limits_attribute.read().value) limits_visible = True self.ui.btnMin.setVisible(limits_visible) self.ui.btnMax.setVisible(limits_visible) except Exception, e: self.ui.motorGroupBox.setEnabled(False) - self.info('Error setting model "%s". Reason: %s' % (model, repr(e))) + self.info('Error setting model "%s". Reason: %s' % + (model, repr(e))) self.traceback() @Qt.pyqtSignature("resetModel()") @@ -752,21 +803,23 @@ def resetStepSizeIncrement(self): self.setStepSizeIncrement(1) model = Qt.pyqtProperty("QString", getModel, setModel, resetModel) - stepSize = Qt.pyqtProperty("double", getStepSize, setStepSize, resetStepSize) - stepSizeIncrement = Qt.pyqtProperty("double", getStepSizeIncrement, setStepSizeIncrement, resetStepSizeIncrement) + stepSize = Qt.pyqtProperty( + "double", getStepSize, setStepSize, resetStepSize) + stepSizeIncrement = Qt.pyqtProperty( + "double", getStepSizeIncrement, setStepSizeIncrement, resetStepSizeIncrement) - -################################################################################################ +########################################################################## # NEW APPROACH TO OPERATE POOL MOTORS FROM A TAURUS FORM INHERITTING DIRECTLY FROM TaurusVALUE # # AND USING PARTICULAR CLASSES THAT KNOW THEY ARE PART OF A TAURUSVALUE AND CAN INTERACT # -################################################################################################ +########################################################################## class TaurusAttributeListener(Qt.QObject): """ A class that recieves events on tango attribute changes. If that is the case it emits a signal with the event's value. """ + def __init__(self): Qt.QObject.__init__(self) @@ -789,9 +842,9 @@ class PoolMotorTVLabelWidget(TaurusWidget): For the (3), a drop event should accept if it is a device, and add it to the 'change-motor' list and select @TODO on the 'expert' row, it could be an ENABLE section with a button to set PowerOn to True/False ''' - + layoutAlignment = Qt.Qt.AlignTop - + def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) self.setLayout(Qt.QGridLayout()) @@ -807,11 +860,13 @@ def __init__(self, parent=None, designMode=False): self.layout().addWidget(self.btn_poweron) # Align everything on top - self.layout().addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Minimum, Qt.QSizePolicy.Expanding)) + self.layout().addItem(Qt.QSpacerItem( + 1, 1, Qt.QSizePolicy.Minimum, Qt.QSizePolicy.Expanding)) # I don't like this approach, there should be something like # self.lbl_alias.addAction(...) - self.lbl_alias.contextMenuEvent = lambda(event): self.contextMenuEvent(event) + self.lbl_alias.contextMenuEvent = lambda( + event): self.contextMenuEvent(event) # I' don't like this approach, there should be something like # self.lbl_alias.addToolTipCallback(self.calculate_extra_tooltip) @@ -819,7 +874,8 @@ def __init__(self, parent=None, designMode=False): # I' don't like this approach, there should be something like # self.lbl_alias.disableDrag() or self.lbl_alias.setDragEnabled(False) - # or better, define if Attribute or Device or Both have to be included in the mimeData + # or better, define if Attribute or Device or Both have to be included + # in the mimeData self.lbl_alias.mouseMoveEvent = self.mouseMoveEvent def setExpertView(self, expertView): @@ -835,8 +891,10 @@ def setPowerOn(self): def setModel(self, model): # Handle User/Expert view - self.disconnect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) - self.disconnect(self.btn_poweron, Qt.SIGNAL('clicked()'), self.setPowerOn) + self.disconnect(self.taurusValueBuddy(), Qt.SIGNAL( + 'expertViewChanged(bool)'), self.setExpertView) + self.disconnect(self.btn_poweron, Qt.SIGNAL( + 'clicked()'), self.setPowerOn) if model in (None, ''): self.lbl_alias.setModel(model) TaurusWidget.setModel(self, model) @@ -844,20 +902,23 @@ def setModel(self, model): self.lbl_alias.taurusValueBuddy = self.taurusValueBuddy self.lbl_alias.setModel(model) TaurusWidget.setModel(self, model + '/Status') - self.connect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) + self.connect(self.taurusValueBuddy(), Qt.SIGNAL( + 'expertViewChanged(bool)'), self.setExpertView) # Handle Power ON/OFF self.connect(self.btn_poweron, Qt.SIGNAL('clicked()'), self.setPowerOn) self.setExpertView(self.taurusValueBuddy()._expertView) def calculateExtendedTooltip(self, cache=False): - default_label_widget_tooltip = DefaultLabelWidget.getFormatedToolTip(self.lbl_alias, cache) + default_label_widget_tooltip = DefaultLabelWidget.getFormatedToolTip( + self.lbl_alias, cache) status_info = '' motor_dev = self.taurusValueBuddy().motor_dev if motor_dev is not None: status = motor_dev.getAttribute('Status').read().value # MAKE IT LOOK LIKE THE STANDARD TABLE FOR TAURUS TOOLTIPS status_lines = status.split('\n') - status_info = '' + status_info = '
Status:' + status_lines[0] + '
' for status_extra_line in status_lines[1:]: status_info += '' status_info += '
Status:' + \ + status_lines[0] + '
' + status_extra_line + '
' @@ -871,19 +932,23 @@ def contextMenuEvent(self, event): action_expert_view.setCheckable(True) action_expert_view.setChecked(self.taurusValueBuddy()._expertView) menu.addAction(action_expert_view) - self.connect(action_expert_view, Qt.SIGNAL('toggled(bool)'), self.taurusValueBuddy().setExpertView) + self.connect(action_expert_view, Qt.SIGNAL( + 'toggled(bool)'), self.taurusValueBuddy().setExpertView) action_tango_attributes = Qt.QAction(self) - action_tango_attributes.setIcon(getIcon(':/categories/preferences-system.svg')) + action_tango_attributes.setIcon( + getIcon(':/categories/preferences-system.svg')) action_tango_attributes.setText('Tango Attributes') menu.addAction(action_tango_attributes) - self.connect(action_tango_attributes, Qt.SIGNAL('triggered()'), self.taurusValueBuddy().showTangoAttributes) + self.connect(action_tango_attributes, Qt.SIGNAL( + 'triggered()'), self.taurusValueBuddy().showTangoAttributes) cm_action = menu.addAction("Compact") cm_action.setCheckable(True) cm_action.setChecked(self.taurusValueBuddy().isCompact()) - self.connect(cm_action, Qt.SIGNAL("toggled(bool)"), self.taurusValueBuddy().setCompact) - + self.connect(cm_action, Qt.SIGNAL("toggled(bool)"), + self.taurusValueBuddy().setCompact) + menu.exec_(event.globalPos()) event.accept() @@ -904,14 +969,16 @@ def mouseMoveEvent(self, event): ################################################## # READ WIDGET # ################################################## + + class PoolMotorTVReadWidget(TaurusWidget): ''' @TODO on the 'expert' row, there should be an Indexer/Encoder radiobuttongroup to show units from raw dial/indx/enc @TODO TaurusLCD may be used but, now it does not display the sign, and color is WHITE... ''' - + layoutAlignment = Qt.Qt.AlignTop - + def __init__(self, parent=None, designMode=False): TaurusWidget.__init__(self, parent, designMode) @@ -925,14 +992,14 @@ def __init__(self, parent=None, designMode=False): self.btn_lim_neg = Qt.QPushButton() self.btn_lim_neg.setToolTip('Negative Limit') - #self.btn_lim_neg.setEnabled(False) + # self.btn_lim_neg.setEnabled(False) self.prepare_button(self.btn_lim_neg) self.btn_lim_neg.setIcon(getIcon(':/actions/list-remove.svg')) limits_layout.addWidget(self.btn_lim_neg) self.btn_lim_pos = Qt.QPushButton() self.btn_lim_pos.setToolTip('Positive Limit') - #self.btn_lim_pos.setEnabled(False) + # self.btn_lim_pos.setEnabled(False) self.prepare_button(self.btn_lim_pos) self.btn_lim_pos.setIcon(getIcon(':/actions/list-add.svg')) limits_layout.addWidget(self.btn_lim_pos) @@ -941,7 +1008,8 @@ def __init__(self, parent=None, designMode=False): self.lbl_read = TaurusLabel() self.lbl_read.setBgRole('quality') - self.lbl_read.setSizePolicy(Qt.QSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed)) + self.lbl_read.setSizePolicy(Qt.QSizePolicy( + Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed)) self.layout().addWidget(self.lbl_read, 0, 1) # WITH A COMPACT VIEW, BETTER TO BE ABLE TO STOP! @@ -956,9 +1024,9 @@ def __init__(self, parent=None, designMode=False): # WITH COMPACT VIEW, WE NEED TO FORWARD DOUBLE CLICK EVENT self.lbl_read.installEventFilter(self) - ## @TODO right now, no options here... + # @TODO right now, no options here... #self.cb_expertRead = Qt.QComboBox() - #self.cb_expertRead.addItems(['Enc']) + # self.cb_expertRead.addItems(['Enc']) #self.layout().addWidget(self.cb_expertRead, 1, 0) self.lbl_enc = Qt.QLabel('Encoder') @@ -966,16 +1034,19 @@ def __init__(self, parent=None, designMode=False): self.lbl_enc_read = TaurusLabel() self.lbl_enc_read.setBgRole('none') - self.lbl_enc_read.setSizePolicy(Qt.QSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed)) + self.lbl_enc_read.setSizePolicy(Qt.QSizePolicy( + Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed)) self.layout().addWidget(self.lbl_enc_read, 1, 1) # Align everything on top - self.layout().addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Minimum, Qt.QSizePolicy.Expanding), 2, 0, 1, 2) + self.layout().addItem(Qt.QSpacerItem( + 1, 1, Qt.QSizePolicy.Minimum, Qt.QSizePolicy.Expanding), 2, 0, 1, 2) # IN ORDER TO BEHAVE AS EXPECTED REGARDING THE 'COMPACT VIEW' FEATURE # WE NEED TO SET THE 'EXPERTVIEW' WITHOUT ACCESSING THE taurusValueBuddy WHICH IS STILL NOT LINKED # SO WE ASSUME 'expertview is FALSE' AND WE HAVE TO AVOID self.setExpertView :-( - # WOULD BE NICE THAT THE taurusValueBuddy COULD EMIT THE PROPER SIGNAL... + # WOULD BE NICE THAT THE taurusValueBuddy COULD EMIT THE PROPER + # SIGNAL... self.lbl_enc.setVisible(False) self.lbl_enc_read.setVisible(False) @@ -1022,7 +1093,8 @@ def prepare_button(self, btn): def setModel(self, model): if hasattr(self, 'taurusValueBuddy'): - self.disconnect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) + self.disconnect(self.taurusValueBuddy(), Qt.SIGNAL( + 'expertViewChanged(bool)'), self.setExpertView) if model in (None, ''): TaurusWidget.setModel(self, model) self.lbl_read.setModel(model) @@ -1033,11 +1105,14 @@ def setModel(self, model): self.lbl_enc_read.setModel(model + '/Encoder') # Handle User/Expert view self.setExpertView(self.taurusValueBuddy()._expertView) - self.connect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) + self.connect(self.taurusValueBuddy(), Qt.SIGNAL( + 'expertViewChanged(bool)'), self.setExpertView) ################################################## # WRITE WIDGET # ################################################## + + class PoolMotorTVWriteWidget(TaurusWidget): layoutAlignment = Qt.Qt.AlignTop @@ -1062,7 +1137,8 @@ def __init__(self, parent=None, designMode=False): self.qw_write_relative.layout().setSpacing(0) self.cb_step = Qt.QComboBox() - self.cb_step.setSizePolicy(Qt.QSizePolicy(Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed)) + self.cb_step.setSizePolicy(Qt.QSizePolicy( + Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Fixed)) self.cb_step.setEditable(True) self.cb_step.lineEdit().setValidator(Qt.QDoubleValidator(self)) self.cb_step.lineEdit().setAlignment(Qt.Qt.AlignRight) @@ -1072,7 +1148,8 @@ def __init__(self, parent=None, designMode=False): self.btn_step_down = Qt.QPushButton() self.btn_step_down.setToolTip('Decrements motor position') self.prepare_button(self.btn_step_down) - self.btn_step_down.setIcon(getIcon(':/actions/media_playback_backward.svg')) + self.btn_step_down.setIcon( + getIcon(':/actions/media_playback_backward.svg')) self.qw_write_relative.layout().addWidget(self.btn_step_down) self.btn_step_up = Qt.QPushButton() @@ -1084,7 +1161,8 @@ def __init__(self, parent=None, designMode=False): self.layout().addWidget(self.qw_write_relative, 0, 0) self.cbAbsoluteRelative = Qt.QComboBox() - self.connect(self.cbAbsoluteRelative, Qt.SIGNAL('currentIndexChanged(QString)'), self.cbAbsoluteRelativeChanged) + self.connect(self.cbAbsoluteRelative, Qt.SIGNAL( + 'currentIndexChanged(QString)'), self.cbAbsoluteRelativeChanged) self.cbAbsoluteRelative.addItems(['Abs', 'Rel']) self.layout().addWidget(self.cbAbsoluteRelative, 0, 1) @@ -1092,41 +1170,49 @@ def __init__(self, parent=None, designMode=False): # WOULD BE BETTER AS AN 'EXTRA WIDGET' (SOME DAY...) #self.btn_stop = Qt.QPushButton() #self.btn_stop.setToolTip('Stops the motor') - #self.prepare_button(self.btn_stop) - #self.btn_stop.setIcon(getIcon(':/actions/media_playback_stop.svg')) + # self.prepare_button(self.btn_stop) + # self.btn_stop.setIcon(getIcon(':/actions/media_playback_stop.svg')) #self.layout().addWidget(self.btn_stop, 0, 2) btns_layout = Qt.QHBoxLayout() btns_layout.setMargin(0) btns_layout.setSpacing(0) - btns_layout.addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum)) + btns_layout.addItem(Qt.QSpacerItem( + 1, 1, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum)) self.btn_to_neg = Qt.QPushButton() - self.btn_to_neg.setToolTip('Moves the motor towards the Negative Software Limit') + self.btn_to_neg.setToolTip( + 'Moves the motor towards the Negative Software Limit') self.prepare_button(self.btn_to_neg) self.btn_to_neg.setIcon(getIcon(':/actions/media_skip_backward.svg')) btns_layout.addWidget(self.btn_to_neg) self.btn_to_neg_press = Qt.QPushButton() - self.btn_to_neg_press.setToolTip('Moves the motor (while pressed) towards the Negative Software Limit') + self.btn_to_neg_press.setToolTip( + 'Moves the motor (while pressed) towards the Negative Software Limit') self.prepare_button(self.btn_to_neg_press) - self.btn_to_neg_press.setIcon(getIcon(':/actions/media_seek_backward.svg')) + self.btn_to_neg_press.setIcon( + getIcon(':/actions/media_seek_backward.svg')) btns_layout.addWidget(self.btn_to_neg_press) self.btn_to_pos_press = Qt.QPushButton() self.prepare_button(self.btn_to_pos_press) - self.btn_to_pos_press.setToolTip('Moves the motor (while pressed) towards the Positive Software Limit') - self.btn_to_pos_press.setIcon(getIcon(':/actions/media_seek_forward.svg')) + self.btn_to_pos_press.setToolTip( + 'Moves the motor (while pressed) towards the Positive Software Limit') + self.btn_to_pos_press.setIcon( + getIcon(':/actions/media_seek_forward.svg')) btns_layout.addWidget(self.btn_to_pos_press) self.btn_to_pos = Qt.QPushButton() - self.btn_to_pos.setToolTip('Moves the motor towards the Positive Software Limit') + self.btn_to_pos.setToolTip( + 'Moves the motor towards the Positive Software Limit') self.prepare_button(self.btn_to_pos) self.btn_to_pos.setIcon(getIcon(':/actions/media_skip_forward.svg')) btns_layout.addWidget(self.btn_to_pos) - btns_layout.addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum)) + btns_layout.addItem(Qt.QSpacerItem( + 1, 1, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum)) self.layout().addLayout(btns_layout, 1, 0, 1, 3) @@ -1134,45 +1220,57 @@ def __init__(self, parent=None, designMode=False): self.connect(self.btn_step_up, Qt.SIGNAL('clicked()'), self.stepUp) ###self.connect(self.btn_stop, Qt.SIGNAL('clicked()'), self.abort) self.connect(self.btn_to_neg, Qt.SIGNAL('clicked()'), self.goNegative) - self.connect(self.btn_to_neg_press, Qt.SIGNAL('pressed()'), self.goNegative) - self.connect(self.btn_to_neg_press, Qt.SIGNAL('released()'), self.abort) + self.connect(self.btn_to_neg_press, Qt.SIGNAL( + 'pressed()'), self.goNegative) + self.connect(self.btn_to_neg_press, + Qt.SIGNAL('released()'), self.abort) self.connect(self.btn_to_pos, Qt.SIGNAL('clicked()'), self.goPositive) - self.connect(self.btn_to_pos_press, Qt.SIGNAL('pressed()'), self.goPositive) - self.connect(self.btn_to_pos_press, Qt.SIGNAL('released()'), self.abort) + self.connect(self.btn_to_pos_press, Qt.SIGNAL( + 'pressed()'), self.goPositive) + self.connect(self.btn_to_pos_press, + Qt.SIGNAL('released()'), self.abort) # Align everything on top - self.layout().addItem(Qt.QSpacerItem(1, 1, Qt.QSizePolicy.Minimum, Qt.QSizePolicy.Expanding), 2, 0, 1, 3) + self.layout().addItem(Qt.QSpacerItem( + 1, 1, Qt.QSizePolicy.Minimum, Qt.QSizePolicy.Expanding), 2, 0, 1, 3) # IN ORDER TO BEHAVE AS EXPECTED REGARDING THE 'COMPACT VIEW' FEATURE # WE NEED TO SET THE 'EXPERTVIEW' WITHOUT ACCESSING THE taurusValueBuddy WHICH IS STILL NOT LINKED # SO WE ASSUME 'expertview is FALSE' AND WE HAVE TO AVOID self.setExpertView :-( - # WOULD BE NICE THAT THE taurusValueBuddy COULD EMIT THE PROPER SIGNAL... + # WOULD BE NICE THAT THE taurusValueBuddy COULD EMIT THE PROPER + # SIGNAL... self.btn_to_neg.setVisible(False) self.btn_to_neg_press.setVisible(False) self.btn_to_pos.setVisible(False) self.btn_to_pos_press.setVisible(False) - # IN EXPERT VIEW, WE HAVE TO FORWARD THE ''editingFinished()' SIGNAL FROM TaurusValueLineEdit TO Switcher + # IN EXPERT VIEW, WE HAVE TO FORWARD THE ''editingFinished()' SIGNAL + # FROM TaurusValueLineEdit TO Switcher try: - self.connect(self.le_write_absolute, Qt.SIGNAL(TaurusBaseWritableWidget.appliedSignalSignature), self.emitEditingFinished) + self.connect(self.le_write_absolute, Qt.SIGNAL( + TaurusBaseWritableWidget.appliedSignalSignature), self.emitEditingFinished) except AttributeError: # TODO: For Taurus 4 adaptation self.le_write_absolute.applied.connect(self.emitEditingFinished) - self.connect(self.btn_step_down, Qt.SIGNAL("clicked()"), self.emitEditingFinished) - self.connect(self.btn_step_up, Qt.SIGNAL("clicked()"), self.emitEditingFinished) - self.connect(self.btn_to_neg, Qt.SIGNAL("clicked()"), self.emitEditingFinished) - self.connect(self.btn_to_pos, Qt.SIGNAL("clicked()"), self.emitEditingFinished) - + self.connect(self.btn_step_down, Qt.SIGNAL( + "clicked()"), self.emitEditingFinished) + self.connect(self.btn_step_up, Qt.SIGNAL( + "clicked()"), self.emitEditingFinished) + self.connect(self.btn_to_neg, Qt.SIGNAL( + "clicked()"), self.emitEditingFinished) + self.connect(self.btn_to_pos, Qt.SIGNAL( + "clicked()"), self.emitEditingFinished) + # list of widgets used for edition editingWidgets = (self.le_write_absolute, self.cbAbsoluteRelative, - self.cb_step, self.btn_step_down, - self.btn_step_up, self.btn_to_neg, + self.cb_step, self.btn_step_down, + self.btn_step_up, self.btn_to_neg, self.btn_to_pos, self.btn_to_neg_press, - self.btn_to_pos_press) + self.btn_to_pos_press) for w in editingWidgets: w.installEventFilter(self) - + def eventFilter(self, obj, event): '''reimplemented to intercept events from the subwidgets''' try: @@ -1182,10 +1280,10 @@ def eventFilter(self, obj, event): except AttributeError: # self.btn_to_neg_press, self.btn_to_pos_press may not exist now pass - # emit editingFinished when focus out to a non-editing widget - if event.type() == Qt.QEvent.FocusOut: - focused = Qt.qApp.focusWidget() - focusInChild = focused in self.findChildren(focused.__class__) + # emit editingFinished when focus out to a non-editing widget + if event.type() == Qt.QEvent.FocusOut: + focused = Qt.qApp.focusWidget() + focusInChild = focused in self.findChildren(focused.__class__) if not focusInChild: self.emitEditingFinished() return False @@ -1248,17 +1346,20 @@ def setExpertView(self, expertView): self.btn_to_pos_press.setVisible(expertView) if expertView and self.taurusValueBuddy().motor_dev is not None: - neg_sw_limit_enabled = self.taurusValueBuddy().motor_dev.getAttribute('Position').min_value.lower() != 'not specified' + neg_sw_limit_enabled = self.taurusValueBuddy().motor_dev.getAttribute( + 'Position').min_value.lower() != 'not specified' self.btn_to_neg.setEnabled(neg_sw_limit_enabled) self.btn_to_neg_press.setEnabled(neg_sw_limit_enabled) - pos_sw_limit_enabled = self.taurusValueBuddy().motor_dev.getAttribute('Position').max_value.lower() != 'not specified' + pos_sw_limit_enabled = self.taurusValueBuddy().motor_dev.getAttribute( + 'Position').max_value.lower() != 'not specified' self.btn_to_pos.setEnabled(pos_sw_limit_enabled) self.btn_to_pos_press.setEnabled(pos_sw_limit_enabled) def setModel(self, model): if hasattr(self, 'taurusValueBuddy'): - self.disconnect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) + self.disconnect(self.taurusValueBuddy(), Qt.SIGNAL( + 'expertViewChanged(bool)'), self.setExpertView) if model in (None, ''): TaurusWidget.setModel(self, model) self.le_write_absolute.setModel(model) @@ -1268,8 +1369,8 @@ def setModel(self, model): # Handle User/Expert View self.setExpertView(self.taurusValueBuddy()._expertView) - self.connect(self.taurusValueBuddy(), Qt.SIGNAL('expertViewChanged(bool)'), self.setExpertView) - + self.connect(self.taurusValueBuddy(), Qt.SIGNAL( + 'expertViewChanged(bool)'), self.setExpertView) def keyPressEvent(self, key_event): if key_event.key() == Qt.Qt.Key_Escape: @@ -1289,14 +1390,14 @@ def emitEditingFinished(self): # UNITS WIDGET # ################################################## class PoolMotorTVUnitsWidget(DefaultUnitsWidget): - + layoutAlignment = Qt.Qt.AlignTop - + def __init__(self, parent=None, designMode=False): DefaultUnitsWidget.__init__(self, parent, designMode) def setModel(self, model): - if model in (None,''): + if model in (None, ''): DefaultUnitsWidget.setModel(self, model) return DefaultUnitsWidget.setModel(self, model + '/Position') @@ -1305,6 +1406,7 @@ def setModel(self, model): # TV MOTOR WIDGET # ################################################## + class PoolMotorTV(TaurusValue): ''' A widget that displays and controls a pool Motor device. It behaves as a TaurusValue. @@ -1314,6 +1416,7 @@ class PoolMotorTV(TaurusValue): @TODO it would be nice if the neg/pos limits could react also when software limits are 'active' @TODO expert view for read widget should include signals (indexer/encoder/inpos)... ''' + def __init__(self, parent=None, designMode=False): TaurusValue.__init__(self, parent=parent, designMode=designMode) self.setLabelWidgetClass(PoolMotorTVLabelWidget) @@ -1336,29 +1439,37 @@ def setExpertView(self, expertView): self.emit(Qt.SIGNAL('expertViewChanged(bool)'), expertView) def minimumHeight(self): - return None #@todo: UGLY HACK to avoid subwidgets being forced to minimumheight=20 + return None # @todo: UGLY HACK to avoid subwidgets being forced to minimumheight=20 def setModel(self, model): TaurusValue.setModel(self, model) try: # disconnect signals if self.limits_listener is not None: - self.disconnect(self.limits_listener, Qt.SIGNAL('eventReceived'), self.updateLimits) + self.disconnect(self.limits_listener, Qt.SIGNAL( + 'eventReceived'), self.updateLimits) if self.poweron_listener is not None: - self.disconnect(self.poweron_listener, Qt.SIGNAL('eventReceived'), self.updatePowerOn) + self.disconnect(self.poweron_listener, Qt.SIGNAL( + 'eventReceived'), self.updatePowerOn) if self.status_listener is not None: - self.disconnect(self.status_listener, Qt.SIGNAL('eventReceived'), self.updateStatus) + self.disconnect(self.status_listener, Qt.SIGNAL( + 'eventReceived'), self.updateStatus) if self.position_listener is not None: - self.disconnect(self.position_listener, Qt.SIGNAL('eventReceived'), self.updatePosition) + self.disconnect(self.position_listener, Qt.SIGNAL( + 'eventReceived'), self.updatePosition) - #remove listeners + # remove listeners if self.motor_dev is not None: if self.hasHwLimits(): - self.motor_dev.getAttribute('Limit_Switches').removeListener(self.limits_listener) + self.motor_dev.getAttribute( + 'Limit_Switches').removeListener(self.limits_listener) if self.hasPowerOn(): - self.motor_dev.getAttribute('PowerOn').removeListener(self.poweron_listener) - self.motor_dev.getAttribute('Status').removeListener(self.status_listener) - self.motor_dev.getAttribute('Position').removeListener(self.position_listener) + self.motor_dev.getAttribute( + 'PowerOn').removeListener(self.poweron_listener) + self.motor_dev.getAttribute( + 'Status').removeListener(self.status_listener) + self.motor_dev.getAttribute( + 'Position').removeListener(self.position_listener) if model == '' or model is None: self.motor_dev = None @@ -1368,24 +1479,34 @@ def setModel(self, model): # CONFIGURE A LISTENER IN ORDER TO UPDATE LIMIT SWITCHES STATES self.limits_listener = TaurusAttributeListener() if self.hasHwLimits(): - self.connect(self.limits_listener, Qt.SIGNAL('eventReceived'), self.updateLimits) - self.motor_dev.getAttribute('Limit_Switches').addListener(self.limits_listener) + self.connect(self.limits_listener, Qt.SIGNAL( + 'eventReceived'), self.updateLimits) + self.motor_dev.getAttribute( + 'Limit_Switches').addListener(self.limits_listener) - # CONFIGURE AN EVENT RECEIVER IN ORDER TO PROVIDE POWERON <- True/False EXPERT OPERATION + # CONFIGURE AN EVENT RECEIVER IN ORDER TO PROVIDE POWERON <- + # True/False EXPERT OPERATION self.poweron_listener = TaurusAttributeListener() if self.hasPowerOn(): - self.connect(self.poweron_listener, Qt.SIGNAL('eventReceived'), self.updatePowerOn) - self.motor_dev.getAttribute('PowerOn').addListener(self.poweron_listener) + self.connect(self.poweron_listener, Qt.SIGNAL( + 'eventReceived'), self.updatePowerOn) + self.motor_dev.getAttribute( + 'PowerOn').addListener(self.poweron_listener) # CONFIGURE AN EVENT RECEIVER IN ORDER TO UPDATED STATUS TOOLTIP self.status_listener = TaurusAttributeListener() - self.connect(self.status_listener, Qt.SIGNAL('eventReceived'), self.updateStatus) - self.motor_dev.getAttribute('Status').addListener(self.status_listener) + self.connect(self.status_listener, Qt.SIGNAL( + 'eventReceived'), self.updateStatus) + self.motor_dev.getAttribute( + 'Status').addListener(self.status_listener) - # CONFIGURE AN EVENT RECEIVER IN ORDER TO ACTIVATE LIMIT BUTTONS ON SOFTWARE LIMITS + # CONFIGURE AN EVENT RECEIVER IN ORDER TO ACTIVATE LIMIT BUTTONS ON + # SOFTWARE LIMITS self.position_listener = TaurusAttributeListener() - self.connect(self.position_listener, Qt.SIGNAL('eventReceived'), self.updatePosition) - self.motor_dev.getAttribute('Position').addListener(self.position_listener) + self.connect(self.position_listener, Qt.SIGNAL( + 'eventReceived'), self.updatePosition) + self.motor_dev.getAttribute( + 'Position').addListener(self.position_listener) self.motor_dev.getAttribute('Position').enablePolling(force=True) @@ -1396,15 +1517,20 @@ def setModel(self, model): return def hasPowerOn(self): - try: return hasattr(self.motor_dev, 'PowerOn') - except: return False + try: + return hasattr(self.motor_dev, 'PowerOn') + except: + return False def hasHwLimits(self): - try: return hasattr(self.motor_dev, 'Limit_Switches') - except: return False + try: + return hasattr(self.motor_dev, 'Limit_Switches') + except: + return False def updateLimits(self, limits, position=None): - if isinstance(limits, dict): limits = limits["limits"] + if isinstance(limits, dict): + limits = limits["limits"] limits = list(limits) HOME = 0 POS = 1 @@ -1433,29 +1559,39 @@ def updateLimits(self, limits, position=None): pos_btnstylesheet = '' enabled = True if pos_lim: - pos_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet(PyTango.DevState.ALARM) + pos_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet( + PyTango.DevState.ALARM) enabled = False - self.readWidget(followCompact=True).btn_lim_pos.setStyleSheet(pos_btnstylesheet) + self.readWidget(followCompact=True).btn_lim_pos.setStyleSheet( + pos_btnstylesheet) self.writeWidget(followCompact=True).btn_step_up.setEnabled(enabled) - self.writeWidget(followCompact=True).btn_step_up.setStyleSheet(pos_btnstylesheet) - enabled = enabled and self.motor_dev.getAttribute('Position').max_value.lower() != 'not specified' + self.writeWidget(followCompact=True).btn_step_up.setStyleSheet( + pos_btnstylesheet) + enabled = enabled and self.motor_dev.getAttribute( + 'Position').max_value.lower() != 'not specified' self.writeWidget(followCompact=True).btn_to_pos.setEnabled(enabled) - self.writeWidget(followCompact=True).btn_to_pos_press.setEnabled(enabled) + self.writeWidget( + followCompact=True).btn_to_pos_press.setEnabled(enabled) neg_lim = limits[NEG] neg_btnstylesheet = '' enabled = True if neg_lim: - neg_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet(PyTango.DevState.ALARM) + neg_btnstylesheet = 'QPushButton{%s}' % DEVICE_STATE_PALETTE.qtStyleSheet( + PyTango.DevState.ALARM) enabled = False - self.readWidget(followCompact=True).btn_lim_neg.setStyleSheet(neg_btnstylesheet) + self.readWidget(followCompact=True).btn_lim_neg.setStyleSheet( + neg_btnstylesheet) self.writeWidget(followCompact=True).btn_step_down.setEnabled(enabled) - self.writeWidget(followCompact=True).btn_step_down.setStyleSheet(neg_btnstylesheet) - enabled = enabled and self.motor_dev.getAttribute('Position').min_value.lower() != 'not specified' + self.writeWidget(followCompact=True).btn_step_down.setStyleSheet( + neg_btnstylesheet) + enabled = enabled and self.motor_dev.getAttribute( + 'Position').min_value.lower() != 'not specified' self.writeWidget(followCompact=True).btn_to_neg.setEnabled(enabled) - self.writeWidget(followCompact=True).btn_to_neg_press.setEnabled(enabled) + self.writeWidget( + followCompact=True).btn_to_neg_press.setEnabled(enabled) def updatePowerOn(self, poweron='__no_argument__'): if poweron == '__no_argument__': @@ -1467,12 +1603,11 @@ def updatePowerOn(self, poweron='__no_argument__'): btn_text = 'Set OFF' self.labelWidget().btn_poweron.setText(btn_text) - def updateStatus(self, status): # SHOULD THERE BE A BETTER METHOD FOR THIS UPDATE? # IF THIS IS NOT DONE, THE TOOLTIP IS NOT CALCULATED EVERY TIME # TaurusLabel.updateStyle DIDN'T WORK, SO I HAD TO GO DEEPER TO THE CONTROLLER... - #self.labelWidget().lbl_alias.updateStyle() + # self.labelWidget().lbl_alias.updateStyle() self.labelWidget().lbl_alias.controllerUpdate() def updatePosition(self, position='__no_argument__'): @@ -1486,41 +1621,45 @@ def updatePosition(self, position='__no_argument__'): if self.motor_dev is not None: limit_switches = [False, False, False] if self.hasHwLimits(): - limit_switches = self.motor_dev.getAttribute('Limit_switches').read().value - #print "update limits", limit_switches + limit_switches = self.motor_dev.getAttribute( + 'Limit_switches').read().value + # print "update limits", limit_switches self.updateLimits(limit_switches, position=position) def hasEncoder(self): - try: return hasattr(self.motor_dev, 'Encoder') - except: return False + try: + return hasattr(self.motor_dev, 'Encoder') + except: + return False def showTangoAttributes(self): model = self.getModel() taurus_attr_form = TaurusAttrForm() taurus_attr_form.setMinimumSize(Qt.QSize(555, 800)) taurus_attr_form.setModel(model) - taurus_attr_form.setWindowTitle('%s Tango Attributes' % taurus.Factory().getDevice(model).getSimpleName()) + taurus_attr_form.setWindowTitle( + '%s Tango Attributes' % taurus.Factory().getDevice(model).getSimpleName()) taurus_attr_form.show() - - - ### def showEvent(self, event): + # def showEvent(self, event): ### TaurusValue.showEvent(self, event) - ### if self.motor_dev is not None: - ### self.motor_dev.getAttribute('Position').enablePolling(force=True) + # if self.motor_dev is not None: + # self.motor_dev.getAttribute('Position').enablePolling(force=True) ### - ### def hideEvent(self, event): + # def hideEvent(self, event): ### TaurusValue.hideEvent(self, event) - ### if self.motor_dev is not None: - ### self.motor_dev.getAttribute('Position').disablePolling() + # if self.motor_dev is not None: + # self.motor_dev.getAttribute('Position').disablePolling() ################################################### # A SIMPLER WIDGET THAT MAY BE USED OUTSIDE FORMS # ################################################### + class PoolMotor(TaurusFrame): ''' A widget that displays and controls a pool Motor device. ''' + def __init__(self, parent=None, designMode=False): TaurusFrame.__init__(self, parent, designMode) @@ -1534,8 +1673,11 @@ def __init__(self, parent=None, designMode=False): def setModel(self, model): self.pool_motor_tv.setModel(model) - try: self.motor_dev = taurus.Device(model) - except: return + try: + self.motor_dev = taurus.Device(model) + except: + return + def main(): @@ -1559,17 +1701,17 @@ def main(): w.setLayout(Qt.QVBoxLayout()) tests = [] - #tests.append(1) + # tests.append(1) tests.append(2) - #tests.append(3) - #tests.append(4) + # tests.append(3) + # tests.append(4) # 1) Test PoolMotorSlim motor widget form_pms = TaurusForm() pms_widget_class = 'sardana.taurus.qt.qtgui.extra_pool.PoolMotorSlim' - pms_tgclass_map = {'SimuMotor':(pms_widget_class, (), {}), - 'Motor':(pms_widget_class, (), {}), - 'PseudoMotor':(pms_widget_class, (), {})} + pms_tgclass_map = {'SimuMotor': (pms_widget_class, (), {}), + 'Motor': (pms_widget_class, (), {}), + 'PseudoMotor': (pms_widget_class, (), {})} form_pms.setCustomWidgetMap(pms_tgclass_map) if 1 in tests: form_pms.setModel(models) @@ -1579,9 +1721,9 @@ def main(): form_tv = TaurusForm() form_tv.setModifiableByUser(True) tv_widget_class = 'sardana.taurus.qt.qtgui.extra_pool.PoolMotorTV' - tv_tgclass_map = {'SimuMotor':(tv_widget_class, (), {}), - 'Motor':(tv_widget_class, (), {}), - 'PseudoMotor':(tv_widget_class, (), {})} + tv_tgclass_map = {'SimuMotor': (tv_widget_class, (), {}), + 'Motor': (tv_widget_class, (), {}), + 'PseudoMotor': (tv_widget_class, (), {})} form_tv.setCustomWidgetMap(tv_tgclass_map) if 2 in tests: diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/__init__.py b/src/sardana/taurus/qt/qtgui/extra_sardana/__init__.py index e5f31d23e4..a311815733 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/__init__.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -37,5 +37,3 @@ except: from taurus.qt.qtgui.display import create_taurus_fallback as __create SardanaEditor = __create("SardanaEditor") - - diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/cmdline.py b/src/sardana/taurus/qt/qtgui/extra_sardana/cmdline.py index e07f463f92..8c85078b34 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/cmdline.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/cmdline.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -35,6 +35,7 @@ class CommandLineHistory(list): pass + class CommandLine(Qt.QComboBox): def __init__(self, qt_parent=None, designMode=False): @@ -42,6 +43,7 @@ def __init__(self, qt_parent=None, designMode=False): self.setEditable(True) self.setFrame(False) + class TaurusCommandLineWidget(Qt.QWidget): def __init__(self, qt_parent=None, designMode=False): @@ -61,7 +63,8 @@ def __init__(self, qt_parent=None, designMode=False): self._cmdLine.setEditable(True) self._applyButton = Qt.QToolButton() - self._applyButton.setIcon(getIcon(":/actions/media_playback_start.svg")) + self._applyButton.setIcon( + getIcon(":/actions/media_playback_start.svg")) self._stopButton = Qt.QToolButton() self._stopButton.setIcon(getIcon(":/actions/media_playback_stop.svg")) @@ -75,14 +78,14 @@ def __init__(self, qt_parent=None, designMode=False): l.addWidget(self._stopButton, 0) l.addWidget(self._clearButton, 0) - - def run(self): pass + def demo(): pass + def main(): import sys import taurus.qt.qtgui.application diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/controllertree.py b/src/sardana/taurus/qt/qtgui/extra_sardana/controllertree.py index ed38336b8a..7445bb772e 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/controllertree.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/controllertree.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -40,7 +40,9 @@ from taurus.qt.qtgui.tree import TaurusBaseTreeWidget from taurus.qt.qtgui.resource import getThemeIcon, getIcon -PoolControllerView = Enumeration("PoolControllerView", ("ControllerModule", "ControllerClass", "Unknown")) +PoolControllerView = Enumeration( + "PoolControllerView", ("ControllerModule", "ControllerClass", "Unknown")) + def getElementTypeIcon(t): if t == PoolControllerView.ControllerModule: @@ -49,9 +51,11 @@ def getElementTypeIcon(t): return getIcon(":/python.png") return getIcon(":/tango.png") + def getElementTypeSize(t): return Qt.QSize(200, 24) + def getElementTypeToolTip(t): """Wrapper to prevent loading qtgui when this module is imported""" if t == PoolControllerView.ControllerModule: @@ -65,7 +69,7 @@ class ControllerBaseTreeItem(TaurusBaseTreeItem): def data(self, index): """Returns the data of this node for the given index - + :return: (object) the data for the given index """ return self._itemData @@ -73,10 +77,10 @@ def data(self, index): def role(self): """Returns the prefered role for the item. This implementation returns taurus.core.taurusbasetypes.TaurusElementType.Unknown - + This method should be able to return any kind of python object as long as the model that is used is compatible. - + :return: (PoolControllerView) the role in form of element type""" return PoolControllerView.Unknown @@ -97,7 +101,7 @@ class ControllerTreeItem(ControllerBaseTreeItem): def data(self, index): """Returns the data of this node for the given index - + :return: (object) the data for the given index """ return self._itemData.name @@ -115,13 +119,16 @@ def icon(self): class ControllerBaseModel(TaurusBaseModel): ColumnNames = "Controllers", - ColumnRoles = (PoolControllerView.ControllerModule, PoolControllerView.ControllerModule, PoolControllerView.ControllerClass), + ColumnRoles = (PoolControllerView.ControllerModule, + PoolControllerView.ControllerModule, PoolControllerView.ControllerClass), def setDataSource(self, pool): if self._data_src is not None: - Qt.QObject.disconnect(self._data_src, Qt.SIGNAL('controllerClassesUpdated'), self.controllerClassesUpdated) + Qt.QObject.disconnect(self._data_src, Qt.SIGNAL( + 'controllerClassesUpdated'), self.controllerClassesUpdated) if pool is not None: - Qt.QObject.connect(pool, Qt.SIGNAL('controllerClassesUpdated'), self.controllerClassesUpdated) + Qt.QObject.connect(pool, Qt.SIGNAL( + 'controllerClassesUpdated'), self.controllerClassesUpdated) TaurusBaseModel.setDataSource(self, pool) def controllerClassesUpdated(self): @@ -157,7 +164,8 @@ def mimeData(self, indexes): ret = Qt.QMimeData() data = [] for index in indexes: - if not index.isValid(): continue + if not index.isValid(): + continue tree_item = index.internalPointer() mime_data_item = tree_item.mimeData(index) if mime_data_item is None: @@ -184,7 +192,7 @@ def pyData(self, index, role): ret = item.icon() elif role == Qt.Qt.ToolTipRole: ret = item.toolTip() - #elif role == Qt.Qt.SizeHintRole: + # elif role == Qt.Qt.SizeHintRole: # ret = self.columnSize(column) elif role == Qt.Qt.FontRole: ret = self.DftFont @@ -198,7 +206,7 @@ def setupModelData(self, data): ctrl_modules = {} # TODO #ctrl_class_dict = pool.getControllerClasses() - #for ctrl_class_name, ctrl_class in ctrl_class_dict.items(): + # for ctrl_class_name, ctrl_class in ctrl_class_dict.items(): # module_name = ctrl_class.module_name # moduleNode = ctrl_modules.get(module_name) # if moduleNode is None: @@ -216,7 +224,8 @@ class ControllerModuleModel(ControllerBaseModel): class PlainControllerModel(ControllerBaseModel): ColumnNames = "Controller classes", - ColumnRoles = (PoolControllerView.ControllerClass, PoolControllerView.ControllerClass), + ColumnRoles = (PoolControllerView.ControllerClass, + PoolControllerView.ControllerClass), def setupModelData(self, data): pool = self.dataSource() @@ -226,9 +235,9 @@ def setupModelData(self, data): # TODO #ctrl_class_dict = pool.getControllerClasses() #ctrl_classes = ctrl_class_dict.keys() - #ctrl_classes.sort() + # ctrl_classes.sort() #self.debug("Found %d controller classes", len(ctrl_classes)) - #for ctrl_class_name in ctrl_classes: + # for ctrl_class_name in ctrl_classes: # ctrl_class = ctrl_class_dict[ctrl_class_name] # ctrlNode = ControllerTreeItem(self, ctrl_class, root) # root.appendChild(ctrlNode) @@ -248,18 +257,18 @@ class PlainControllerModelProxy(ControllerBaseModelProxy): class ControllerClassTreeWidget(TaurusBaseTreeWidget): - KnownPerspectives = { PoolControllerView.ControllerModule : { - "label" : "By module", - "icon" : ":/python-file.png", - "tooltip" : "View by controller module", - "model" : [ControllerModuleModelProxy, ControllerModuleModel], - }, - PoolControllerView.ControllerClass : { - "label" : "By controller", - "icon" : ":/python.png", - "tooltip" : "View by controller class", - "model" : [PlainControllerModelProxy, PlainControllerModel], - } + KnownPerspectives = {PoolControllerView.ControllerModule: { + "label": "By module", + "icon": ":/python-file.png", + "tooltip": "View by controller module", + "model": [ControllerModuleModelProxy, ControllerModuleModel], + }, + PoolControllerView.ControllerClass: { + "label": "By controller", + "icon": ":/python.png", + "tooltip": "View by controller class", + "model": [PlainControllerModelProxy, PlainControllerModel], + } } DftPerspective = PoolControllerView.ControllerModule @@ -295,27 +304,33 @@ def selectedItems(self): return self._panel.selectedItems() def getSelectedMacros(self): - return [ i.itemData() for i in self.selectedItems() ] + return [i.itemData() for i in self.selectedItems()] def main_ControllerClassSelecionDialog(pool, perspective=PoolControllerView.ControllerClass): - w = ControllerClassSelectionDialog(model_name=pool, perspective=perspective) + w = ControllerClassSelectionDialog( + model_name=pool, perspective=perspective) if w.result() == Qt.QDialog.Accepted: print w.getSelectedMacros() return w + def main_ControllerClassTreeWidget(pool, perspective=PoolControllerView.ControllerClass): - w = ControllerClassTreeWidget(perspective=perspective, with_navigation_bar=False) + w = ControllerClassTreeWidget( + perspective=perspective, with_navigation_bar=False) w.setModel(pool) w.show() return w + def demo(poolname="Pool_BL98"): """ControllerClassTreeWidget""" - w = main_ControllerClassSelecionDialog(poolname, PoolControllerView.ControllerClass) + w = main_ControllerClassSelecionDialog( + poolname, PoolControllerView.ControllerClass) return w + def main(): import sys import taurus.qt.qtgui.application diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/elementtree.py b/src/sardana/taurus/qt/qtgui/extra_sardana/elementtree.py index 82fa43076c..6849a065a1 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/elementtree.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/elementtree.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -38,12 +38,12 @@ class SardanaElementTreeWidget(TaurusBaseTreeWidget): - KnownPerspectives = { "Type" : { - "label" : "By type", - "icon" : ":/python-file.png", - "tooltip" : "View elements by type", - "model" : [SardanaBaseProxyModel, SardanaElementTypeModel], - }, + KnownPerspectives = {"Type": { + "label": "By type", + "icon": ":/python-file.png", + "tooltip": "View elements by type", + "model": [SardanaBaseProxyModel, SardanaElementTypeModel], + }, } DftPerspective = "Type" @@ -67,11 +67,13 @@ def main_SardanaTreeWidget(device): w.show() return w + def demo(device="V3"): """""" w = main_SardanaTreeWidget(device) return w + def main(): import sys import taurus.qt.qtgui.application diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/environment.py b/src/sardana/taurus/qt/qtgui/extra_sardana/environment.py index c3b194f2aa..19b1509e82 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/environment.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/environment.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -38,12 +38,12 @@ class SardanaEnvironmentTreeWidget(TaurusBaseTreeWidget): - KnownPerspectives = { "Type" : { - "label" : "By key", - "icon" : ":/python-file.png", - "tooltip" : "View elements by key", - "model" : [SardanaEnvironmentModel], - }, + KnownPerspectives = {"Type": { + "label": "By key", + "icon": ":/python-file.png", + "tooltip": "View elements by key", + "model": [SardanaEnvironmentModel], + }, } DftPerspective = "Type" @@ -67,11 +67,13 @@ def main_SardanaTreeWidget(device): w.show() return w + def demo(device="V3"): """""" w = main_SardanaTreeWidget(device) return w + def main(): import sys import taurus.qt.qtgui.application @@ -98,5 +100,3 @@ def main(): if __name__ == "__main__": main() - - diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/expdescription.py b/src/sardana/taurus/qt/qtgui/extra_sardana/expdescription.py index fd81a8d551..bd7195bdca 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/expdescription.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/expdescription.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -37,21 +37,22 @@ from sardana.taurus.qt.qtcore.tango.sardana.model import SardanaBaseProxyModel, SardanaTypeTreeItem from taurus.qt.qtgui.util.ui import UILoadable -## Using a plain model and filtering and checking 'Acquirable' in item.itemData().interfaces is more elegant, but things don't get properly sorted... +# Using a plain model and filtering and checking 'Acquirable' in item.itemData().interfaces is more elegant, but things don't get properly sorted... #from taurus.qt.qtcore.tango.sardana.model import SardanaElementPlainModel + class SardanaAcquirableProxyModel(SardanaBaseProxyModel): -# ALLOWED_TYPES = 'Acquirable' -# -# def filterAcceptsRow(self, sourceRow, sourceParent): -# sourceModel = self.sourceModel() -# idx = sourceModel.index(sourceRow, 0, sourceParent) -# item = idx.internalPointer() -# return 'Acquirable' in item.itemData().interfaces - -# ALLOWED_TYPES = ['Motor', 'CTExpChannel', 'ZeroDExpChannel', 'OneDExpChannel', -# 'TwoDExpChannel', 'ComChannel', 'IORegister', 'PseudoMotor', -# 'PseudoCounter'] + # ALLOWED_TYPES = 'Acquirable' + # + # def filterAcceptsRow(self, sourceRow, sourceParent): + # sourceModel = self.sourceModel() + # idx = sourceModel.index(sourceRow, 0, sourceParent) + # item = idx.internalPointer() + # return 'Acquirable' in item.itemData().interfaces + + # ALLOWED_TYPES = ['Motor', 'CTExpChannel', 'ZeroDExpChannel', 'OneDExpChannel', + # 'TwoDExpChannel', 'ComChannel', 'IORegister', 'PseudoMotor', + # 'PseudoCounter'] from sardana.sardanadefs import ElementType, TYPE_ACQUIRABLE_ELEMENTS ALLOWED_TYPES = [ElementType[t] for t in TYPE_ACQUIRABLE_ELEMENTS] @@ -70,42 +71,59 @@ class ExpDescriptionEditor(Qt.QWidget, TaurusBaseWidget): ''' A widget for editing the configuration of a experiment (measurement groups, plot and storage parameters, etc). - + It receives a Sardana Door name as its model and gets/sets the configuration using the `ExperimentConfiguration` environmental variable for that Door. ''' + def __init__(self, parent=None, door=None, plotsButton=True): Qt.QWidget.__init__(self, parent) TaurusBaseWidget.__init__(self, 'ExpDescriptionEditor') self.loadUi() - self.ui.buttonBox.setStandardButtons(Qt.QDialogButtonBox.Reset | Qt.QDialogButtonBox.Apply) - newperspectivesDict = copy.deepcopy(self.ui.sardanaElementTree.KnownPerspectives) + self.ui.buttonBox.setStandardButtons( + Qt.QDialogButtonBox.Reset | Qt.QDialogButtonBox.Apply) + newperspectivesDict = copy.deepcopy( + self.ui.sardanaElementTree.KnownPerspectives) #newperspectivesDict[self.ui.sardanaElementTree.DftPerspective]['model'] = [SardanaAcquirableProxyModel, SardanaElementPlainModel] - newperspectivesDict[self.ui.sardanaElementTree.DftPerspective]['model'][0] = SardanaAcquirableProxyModel - self.ui.sardanaElementTree.KnownPerspectives = newperspectivesDict #assign a copy because if just a key of this class memberwas modified, all instances of this class would be affected - self.ui.sardanaElementTree._setPerspective(self.ui.sardanaElementTree.DftPerspective) + newperspectivesDict[self.ui.sardanaElementTree.DftPerspective][ + 'model'][0] = SardanaAcquirableProxyModel + # assign a copy because if just a key of this class memberwas modified, + # all instances of this class would be affected + self.ui.sardanaElementTree.KnownPerspectives = newperspectivesDict + self.ui.sardanaElementTree._setPerspective( + self.ui.sardanaElementTree.DftPerspective) self._localConfig = None self._originalConfiguration = None self._dirty = False self._dirtyMntGrps = set() - self.connect(self.ui.activeMntGrpCB, Qt.SIGNAL('activated (QString)'), self.changeActiveMntGrp) - self.connect(self.ui.createMntGrpBT, Qt.SIGNAL('clicked ()'), self.createMntGrp) - self.connect(self.ui.deleteMntGrpBT, Qt.SIGNAL('clicked ()'), self.deleteMntGrp) - self.connect(self.ui.compressionCB, Qt.SIGNAL('currentIndexChanged (int)'), self.onCompressionCBChanged) - self.connect(self.ui.pathLE, Qt.SIGNAL('textEdited (QString)'), self.onPathLEEdited) - self.connect(self.ui.filenameLE, Qt.SIGNAL('textEdited (QString)'), self.onFilenameLEEdited) - self.connect(self.ui.channelEditor.getQModel(), Qt.SIGNAL('dataChanged (QModelIndex, QModelIndex)'), self._updateButtonBox) - self.connect(self.ui.channelEditor.getQModel(), Qt.SIGNAL('modelReset ()'), self._updateButtonBox) + self.connect(self.ui.activeMntGrpCB, Qt.SIGNAL( + 'activated (QString)'), self.changeActiveMntGrp) + self.connect(self.ui.createMntGrpBT, Qt.SIGNAL( + 'clicked ()'), self.createMntGrp) + self.connect(self.ui.deleteMntGrpBT, Qt.SIGNAL( + 'clicked ()'), self.deleteMntGrp) + self.connect(self.ui.compressionCB, Qt.SIGNAL( + 'currentIndexChanged (int)'), self.onCompressionCBChanged) + self.connect(self.ui.pathLE, Qt.SIGNAL( + 'textEdited (QString)'), self.onPathLEEdited) + self.connect(self.ui.filenameLE, Qt.SIGNAL( + 'textEdited (QString)'), self.onFilenameLEEdited) + self.connect(self.ui.channelEditor.getQModel(), Qt.SIGNAL( + 'dataChanged (QModelIndex, QModelIndex)'), self._updateButtonBox) + self.connect(self.ui.channelEditor.getQModel(), Qt.SIGNAL( + 'modelReset ()'), self._updateButtonBox) preScanList = self.ui.preScanList self.connect(preScanList, Qt.SIGNAL('dataChanged'), self.onPreScanSnapshotChanged) - #TODO: For Taurus 4 compatibility + # TODO: For Taurus 4 compatibility if hasattr(preScanList, "dataChangedSignal"): - preScanList.dataChangedSignal.connect(self.onPreScanSnapshotChanged) - self.connect(self.ui.choosePathBT, Qt.SIGNAL('clicked ()'), self.onChooseScanDirButtonClicked) - + preScanList.dataChangedSignal.connect( + self.onPreScanSnapshotChanged) + self.connect(self.ui.choosePathBT, Qt.SIGNAL( + 'clicked ()'), self.onChooseScanDirButtonClicked) + self.__plotManager = None icon = resource.getIcon(":/actions/view.svg") self.togglePlotsAction = Qt.QAction(icon, "Show/Hide plots", self) @@ -113,15 +131,16 @@ def __init__(self, parent=None, door=None, plotsButton=True): self.togglePlotsAction.setChecked(False) self.togglePlotsAction.setEnabled(plotsButton) self.addAction(self.togglePlotsAction) - self.connect(self.togglePlotsAction, Qt.SIGNAL("toggled(bool)"), + self.connect(self.togglePlotsAction, Qt.SIGNAL("toggled(bool)"), self.onPlotsButtonToggled) self.ui.plotsButton.setDefaultAction(self.togglePlotsAction) - + if door is not None: self.setModel(door) - self.connect(self.ui.buttonBox, Qt.SIGNAL("clicked(QAbstractButton *)"), self.onDialogButtonClicked) + self.connect(self.ui.buttonBox, Qt.SIGNAL( + "clicked(QAbstractButton *)"), self.onDialogButtonClicked) - #Taurus Configuration properties and delegates + # Taurus Configuration properties and delegates self.registerConfigDelegate(self.ui.channelEditor) def getModelClass(self): @@ -129,7 +148,8 @@ def getModelClass(self): return taurus.core.taurusdevice.TaurusDevice def onChooseScanDirButtonClicked(self): - ret = Qt.QFileDialog.getExistingDirectory (self, 'Choose directory for saving files', self.ui.pathLE.text()) + ret = Qt.QFileDialog.getExistingDirectory( + self, 'Choose directory for saving files', self.ui.pathLE.text()) if ret: self.ui.pathLE.setText(ret) self.ui.pathLE.emit(Qt.SIGNAL('textEdited (QString)'), ret) @@ -151,10 +171,12 @@ def setModel(self, model): '''reimplemented from :class:`TaurusBaseWidget`''' TaurusBaseWidget.setModel(self, model) self._reloadConf(force=True) - #set the model of some child widgets + # set the model of some child widgets door = self.getModelObj() - if door is None: return - tghost = taurus.Database().getNormalName() #@todo: get the tghost from the door model instead + if door is None: + return + # @todo: get the tghost from the door model instead + tghost = taurus.Database().getNormalName() msname = door.macro_server.getFullName() self.ui.taurusModelTree.setModel(tghost) self.ui.sardanaElementTree.setModel(msname) @@ -162,23 +184,24 @@ def setModel(self, model): def _reloadConf(self, force=False): if not force and self.isDataChanged(): op = Qt.QMessageBox.question(self, "Reload info from door", - "If you reload, all current experiment configuration changes will be lost. Reload?", - Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) + "If you reload, all current experiment configuration changes will be lost. Reload?", + Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return door = self.getModelObj() - if door is None: return + if door is None: + return conf = door.getExperimentConfiguration() self._originalConfiguration = copy.deepcopy(conf) self.setLocalConfig(conf) self._setDirty(False) self._dirtyMntGrps = set() - #set a list of available channels + # set a list of available channels avail_channels = {} for ch_info in door.macro_server.getExpChannelElements().values(): avail_channels[ch_info.full_name] = ch_info.getData() self.ui.channelEditor.getQModel().setAvailableChannels(avail_channels) - #set a list of available triggers + # set a list of available triggers avail_triggers = {'software': {"name": "software"}} tg_elements = door.macro_server.getElementsOfType('TriggerGate') for tg_info in tg_elements.values(): @@ -191,7 +214,7 @@ def _setDirty(self, dirty): def isDataChanged(self): """Tells if the local data has been modified since it was last refreshed - + :return: (bool) True if he local data has been modified since it was last refreshed """ return bool(self._dirty or self.ui.channelEditor.getQModel().isDataChanged() or self._dirtyMntGrps) @@ -207,13 +230,13 @@ def setLocalConfig(self, conf): self._localConfig = conf - #set the Channel Editor + # set the Channel Editor activeMntGrpName = self._localConfig['ActiveMntGrp'] or '' if activeMntGrpName in self._localConfig['MntGrpConfigs']: mgconfig = self._localConfig['MntGrpConfigs'][activeMntGrpName] self.ui.channelEditor.getQModel().setDataSource(mgconfig) - #set the measurement group ComboBox + # set the measurement group ComboBox self.ui.activeMntGrpCB.clear() mntGrpLabels = [] for _, mntGrpConf in self._localConfig['MntGrpConfigs'].items(): @@ -225,8 +248,9 @@ def setLocalConfig(self, conf): Qt.Qt.MatchFixedString) self.ui.activeMntGrpCB.setCurrentIndex(idx) - #set the system snapshot list - psl = self._localConfig.get('PreScanSnapshot') #I get it before clearing because clear() changes the _localConfig + # set the system snapshot list + # I get it before clearing because clear() changes the _localConfig + psl = self._localConfig.get('PreScanSnapshot') # TODO: For Taurus 4 compatibility psl_fullname = [] for name, display in psl: @@ -234,37 +258,38 @@ def setLocalConfig(self, conf): self.ui.preScanList.clear() self.ui.preScanList.addModels(psl_fullname) - #other settings + # other settings self.ui.filenameLE.setText(", ".join(self._localConfig['ScanFile'])) self.ui.pathLE.setText(self._localConfig['ScanDir'] or '') - self.ui.compressionCB.setCurrentIndex(self._localConfig['DataCompressionRank'] + 1) + self.ui.compressionCB.setCurrentIndex( + self._localConfig['DataCompressionRank'] + 1) def writeExperimentConfiguration(self, ask=True): '''sends the current local configuration to the door - + :param ask: (bool) If True (default) prompts the user before saving. ''' if ask: op = Qt.QMessageBox.question(self, "Save configuration?", - 'Do you want to save the current configuration?\n(if not, any changes will be lost)', - Qt.QMessageBox.Yes | Qt.QMessageBox.No) + 'Do you want to save the current configuration?\n(if not, any changes will be lost)', + Qt.QMessageBox.Yes | Qt.QMessageBox.No) if op != Qt.QMessageBox.Yes: return False conf = self.getLocalConfig() - #make sure that no empty measurement groups are written + # make sure that no empty measurement groups are written for mgname, mgconfig in conf.get('MntGrpConfigs', {}).items(): if mgconfig is not None and not mgconfig.get('controllers'): mglabel = mgconfig['label'] Qt.QMessageBox.information(self, "Empty Measurement group", - "The measurement group '%s' is empty. Fill it (or delete it) before applying" % mglabel, - Qt.QMessageBox.Ok) + "The measurement group '%s' is empty. Fill it (or delete it) before applying" % mglabel, + Qt.QMessageBox.Ok) self.changeActiveMntGrp(mgname) return False - #check if the currently displayed mntgrp is changed + # check if the currently displayed mntgrp is changed if self.ui.channelEditor.getQModel().isDataChanged(): self._dirtyMntGrps.add(self._localConfig['ActiveMntGrp']) @@ -274,7 +299,8 @@ def writeExperimentConfiguration(self, ask=True): self._dirtyMntGrps = set() self.ui.channelEditor.getQModel().setDataChanged(False) self._setDirty(False) - self.emit(Qt.SIGNAL('experimentConfigurationChanged'), copy.deepcopy(conf)) + self.emit(Qt.SIGNAL('experimentConfigurationChanged'), + copy.deepcopy(conf)) return True def changeActiveMntGrp(self, activeMntGrpName): @@ -282,11 +308,12 @@ def changeActiveMntGrp(self, activeMntGrpName): if self._localConfig is None: return if activeMntGrpName == self._localConfig['ActiveMntGrp']: - return #nothing changed + return # nothing changed if activeMntGrpName not in self._localConfig['MntGrpConfigs']: raise KeyError('Unknown measurement group "%s"' % activeMntGrpName) - #add the previous measurement group to the list of "dirty" groups if something was changed + # add the previous measurement group to the list of "dirty" groups if + # something was changed if self.ui.channelEditor.getQModel().isDataChanged(): self._dirtyMntGrps.add(self._localConfig['ActiveMntGrp']) @@ -308,45 +335,48 @@ def createMntGrp(self): mntGrpName, ok = Qt.QInputDialog.getText(self, "New Measurement Group", "Enter a name for the new measurement Group") - if not ok: return + if not ok: + return mntGrpName = str(mntGrpName) - #check that the given name is not an existing pool element + # check that the given name is not an existing pool element ms = self.getModelObj().macro_server - poolElementNames = [v.name for v in ms.getElementsWithInterface("PoolElement").values()] + poolElementNames = [ + v.name for v in ms.getElementsWithInterface("PoolElement").values()] while mntGrpName in poolElementNames: Qt.QMessageBox.warning(self, "Cannot create Measurement group", - "The name '%s' already is used for another pool element. Please Choose a different one." % mntGrpName, - Qt.QMessageBox.Ok) + "The name '%s' already is used for another pool element. Please Choose a different one." % mntGrpName, + Qt.QMessageBox.Ok) mntGrpName, ok = Qt.QInputDialog.getText(self, "New Measurement Group", "Enter a name for the new measurement Group", Qt.QLineEdit.Normal, mntGrpName) - if not ok: return + if not ok: + return mntGrpName = str(mntGrpName) - #check that the measurement group is not already in the localConfig + # check that the measurement group is not already in the localConfig if mntGrpName in self._localConfig['MntGrpConfigs']: Qt.QMessageBox.warning(self, "%s already exists" % mntGrpName, - 'A measurement group named "%s" already exists. A new one will not be created' % mntGrpName) + 'A measurement group named "%s" already exists. A new one will not be created' % mntGrpName) return - #add an empty configuration dictionary to the local config - mgconfig = {'label': mntGrpName, 'controllers':{} } + # add an empty configuration dictionary to the local config + mgconfig = {'label': mntGrpName, 'controllers': {}} self._localConfig['MntGrpConfigs'][mntGrpName] = mgconfig - #add the new measurement group to the list of "dirty" groups + # add the new measurement group to the list of "dirty" groups self._dirtyMntGrps.add(mntGrpName) - #add the name to the combobox + # add the name to the combobox self.ui.activeMntGrpCB.addItem(mntGrpName) - #make it the Active MntGrp + # make it the Active MntGrp self.changeActiveMntGrp(mntGrpName) def deleteMntGrp(self): '''creates a new Measurement Group''' activeMntGrpName = str(self.ui.activeMntGrpCB.currentText()) op = Qt.QMessageBox.question(self, "Delete Measurement Group", - "Remove the measurement group '%s'?" % activeMntGrpName, - Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) + "Remove the measurement group '%s'?" % activeMntGrpName, + Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return currentIndex = self.ui.activeMntGrpCB.currentIndex() @@ -355,7 +385,7 @@ def deleteMntGrp(self): if activeMntGrpName not in self._localConfig['MntGrpConfigs']: raise KeyError('Unknown measurement group "%s"' % activeMntGrpName) - #add the current measurement group to the list of "dirty" groups + # add the current measurement group to the list of "dirty" groups self._dirtyMntGrps.add(activeMntGrpName) self._localConfig['MntGrpConfigs'][activeMntGrpName] = None @@ -365,7 +395,8 @@ def deleteMntGrp(self): self._setDirty(True) def onCompressionCBChanged(self, idx): - if self._localConfig is None: return + if self._localConfig is None: + return self._localConfig['DataCompressionRank'] = idx - 1 self._setDirty(True) @@ -374,7 +405,8 @@ def onPathLEEdited(self, text): self._setDirty(True) def onFilenameLEEdited(self, text): - self._localConfig['ScanFile'] = [v.strip() for v in str(text).split(',')] + self._localConfig['ScanFile'] = [v.strip() + for v in str(text).split(',')] self._setDirty(True) def onPreScanSnapshotChanged(self, items): @@ -384,31 +416,33 @@ def onPreScanSnapshotChanged(self, items): for e in items: nfo = ms.getElementInfo(e.src) if nfo is None: - full_name = e.src; display = e.display + full_name = e.src + display = e.display else: - full_name = nfo.full_name; display = nfo.name + full_name = nfo.full_name + display = nfo.name # TODO: For Taurus 4 compatibility if full_name.startswith("tango://"): full_name = full_name[8:] preScanList.append((full_name, display)) self._localConfig['PreScanSnapshot'] = preScanList self._setDirty(True) - + def onPlotsButtonToggled(self, checked): if checked: from taurus.qt.qtgui.taurusgui.macrolistener import \ - DynamicPlotManager + DynamicPlotManager self.__plotManager = DynamicPlotManager(self) self.__plotManager.setModel(self.getModelName()) - self.connect(self, Qt.SIGNAL('experimentConfigurationChanged'), + self.connect(self, Qt.SIGNAL('experimentConfigurationChanged'), self.__plotManager.onExpConfChanged) else: - self.disconnect(self, Qt.SIGNAL('experimentConfigurationChanged'), + self.disconnect(self, Qt.SIGNAL('experimentConfigurationChanged'), self.__plotManager.onExpConfChanged) self.__plotManager.removePanels() self.__plotManager.setModel(None) self.__plotManager = None - + def demo(model=None): """Experiment configuration""" @@ -425,6 +459,7 @@ def demo(model=None): w.setModel(model) return w + def main(): import sys import taurus.qt.qtgui.application diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/macrotree.py b/src/sardana/taurus/qt/qtgui/extra_sardana/macrotree.py index f090965767..4c55726d8b 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/macrotree.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/macrotree.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -44,6 +44,7 @@ MacroView = Enumeration("MacroView", ("MacroModule", "Macro", "Unknown")) + def getElementTypeIcon(t): if t == MacroView.MacroModule: return getIcon(":/python-file.png") @@ -51,9 +52,11 @@ def getElementTypeIcon(t): return getIcon(":/python.png") return getIcon(":/tango.png") + def getElementTypeSize(t): return Qt.QSize(200, 24) + def getElementTypeToolTip(t): """Wrapper to prevent loading qtgui when this module is imported""" if t == MacroView.MacroModule: @@ -68,7 +71,7 @@ class MacroTreeBaseItem(TaurusBaseTreeItem): def data(self, index): """Returns the data of this node for the given index - + :return: (object) the data for the given index """ return self._itemData @@ -76,10 +79,10 @@ def data(self, index): def role(self): """Returns the prefered role for the item. This implementation returns taurus.core.taurusbasetypes.TaurusElementType.Unknown - + This method should be able to return any kind of python object as long as the model that is used is compatible. - + :return: (MacroView) the role in form of element type""" return MacroView.Unknown @@ -100,7 +103,7 @@ class MacroTreeItem(MacroTreeBaseItem): def data(self, index): """Returns the data of this node for the given index - + :return: (object) the data for the given index """ return self._itemData.name @@ -118,13 +121,16 @@ def icon(self, index): class MacroBaseModel(TaurusBaseModel): ColumnNames = "Macros", - ColumnRoles = (MacroView.MacroModule, MacroView.MacroModule, MacroView.Macro), + ColumnRoles = (MacroView.MacroModule, + MacroView.MacroModule, MacroView.Macro), def setDataSource(self, ms): if self._data_src is not None: - Qt.QObject.disconnect(self._data_src, Qt.SIGNAL('macrosUpdated'), self.macrosUpdated) + Qt.QObject.disconnect(self._data_src, Qt.SIGNAL( + 'macrosUpdated'), self.macrosUpdated) if ms is not None: - Qt.QObject.connect(ms, Qt.SIGNAL('macrosUpdated'), self.macrosUpdated) + Qt.QObject.connect(ms, Qt.SIGNAL( + 'macrosUpdated'), self.macrosUpdated) TaurusBaseModel.setDataSource(self, ms) def macrosUpdated(self): @@ -160,7 +166,8 @@ def mimeData(self, indexes): ret = Qt.QMimeData() data = [] for index in indexes: - if not index.isValid(): continue + if not index.isValid(): + continue tree_item = index.internalPointer() mime_data_item = tree_item.mimeData(index) if mime_data_item is None: @@ -172,8 +179,6 @@ def mimeData(self, indexes): ret.setData(TAURUS_MODEL_MIME_TYPE, str(data[0])) return ret - - def setupModelData(self, data): ms = self.dataSource() if ms is None: @@ -230,18 +235,18 @@ class MacroPlainMacroModelProxy(MacroBaseModelProxy): class MacroTreeWidget(TaurusBaseTreeWidget): - KnownPerspectives = { MacroView.MacroModule : { - "label" : "By module", - "icon" : ":/python-file.png", - "tooltip" : "View by macro module", - "model" : [MacroModuleModelProxy, MacroModuleModel], - }, - MacroView.Macro : { - "label" : "By macro", - "icon" : ":/python.png", - "tooltip" : "View by macro", - "model" : [MacroPlainMacroModelProxy, MacroPlainMacroModel], - } + KnownPerspectives = {MacroView.MacroModule: { + "label": "By module", + "icon": ":/python-file.png", + "tooltip": "View by macro module", + "model": [MacroModuleModelProxy, MacroModuleModel], + }, + MacroView.Macro: { + "label": "By macro", + "icon": ":/python.png", + "tooltip": "View by macro", + "model": [MacroPlainMacroModelProxy, MacroPlainMacroModel], + } } DftPerspective = MacroView.MacroModule @@ -276,7 +281,7 @@ def selectedItems(self): return self._panel.selectedItems() def getSelectedMacros(self): - return [ i.itemData() for i in self.selectedItems() ] + return [i.itemData() for i in self.selectedItems()] def main_MacroSelecionDialog(ms, perspective=MacroView.MacroModule): @@ -286,17 +291,20 @@ def main_MacroSelecionDialog(ms, perspective=MacroView.MacroModule): print w.getSelectedMacros() return w + def main_MacroTreeWidget(ms, perspective=MacroView.MacroModule): w = MacroTreeWidget(perspective=perspective, with_navigation_bar=False) w.setModel(ms) w.show() return w + def demo(): """MacroTreeWidget""" w = main_MacroSelecionDialog("MS_BL98", MacroView.Macro) return w + def main(): import sys import taurus.qt.qtgui.application diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/measurementgroup.py b/src/sardana/taurus/qt/qtgui/extra_sardana/measurementgroup.py index 459df8641b..fce02a093c 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/measurementgroup.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/measurementgroup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -44,7 +44,7 @@ from sardana.pool.pooldefs import AcqSynchType from sardana.taurus.core.tango.sardana.pool import getChannelConfigs -#=============================================================================== +#========================================================================= # some dummydict for developing the "Experimental Configuration widget" # This block is to be removed and the dictionaries will be defined and # initialized in Sardana's Door code @@ -79,8 +79,10 @@ # - 'description' : measurement group description -#=============================================================================== -DEFAULT_STRING_LENGTH = 80 #just an arbitrary value to use as default string length... +#========================================================================= +# just an arbitrary value to use as default string length... +DEFAULT_STRING_LENGTH = 80 + def createChannelDict(channel, index=None, **kwargs): from taurus.core.tango import FROM_TANGO_TO_STR_TYPE @@ -111,22 +113,27 @@ def createChannelDict(channel, index=None, **kwargs): source = channel['source'] ret = { - 'name' : name, - 'label': label, - 'full_name': full_name, - 'enabled': True, # bool. Whether this channel is enabled (if not enabled, it won't be used for output or plot) - 'output': True, # bool. Whether to show output in the stdout - 'data_type':'float64', - 'data_units': 'No unit', -# 'timer': '', #should contain a channel name -# 'monitor': '', #should contain a channel name -# 'trigger': '', #should contain a channel name - 'conditioning': '', #this is a python expresion to be evaluated for conditioning the data. The data for this channel can be referred as 'x' and data from other channels can be referred by channel name - 'normalization': Normalization.No, # one of the Normalization enumeration members - 'nexus_path': '', #string indicating the location of the data of this channel within the nexus tree - } - - #If the channel is a Tango one, try to guess data_type, shape and data_units + 'name': name, + 'label': label, + 'full_name': full_name, + # bool. Whether this channel is enabled (if not enabled, it won't be + # used for output or plot) + 'enabled': True, + 'output': True, # bool. Whether to show output in the stdout + 'data_type': 'float64', + 'data_units': 'No unit', + # 'timer': '', #should contain a channel name + # 'monitor': '', #should contain a channel name + # 'trigger': '', #should contain a channel name + 'conditioning': '', # this is a python expresion to be evaluated for conditioning the data. The data for this channel can be referred as 'x' and data from other channels can be referred by channel name + 'normalization': Normalization.No, # one of the Normalization enumeration members + # string indicating the location of the data of this channel within + # the nexus tree + 'nexus_path': '', + } + + # If the channel is a Tango one, try to guess data_type, shape and + # data_units attrproxy = attrconf = value = None dtype = shape = None try: @@ -146,44 +153,51 @@ def createChannelDict(channel, index=None, **kwargs): if attrconf.data_format == PyTango.AttrDataFormat.SCALAR: shape = [] else: - shape = [n for n in (attrconf.max_dim_x, attrconf.max_dim_y) if n > 0] + shape = [n for n in (attrconf.max_dim_x, + attrconf.max_dim_y) if n > 0] dtype = FROM_TANGO_TO_STR_TYPE[attrconf.data_type] ret['data_units'] = attrconf.unit if dtype is not None: -# if dtype.startswith('str'): -# dtype='char' -# shape = list(shape)+[DEFAULT_STRING_LENGTH] -# elif dtype == 'bool': -# dtype='int8' + # if dtype.startswith('str'): + # dtype='char' + # shape = list(shape)+[DEFAULT_STRING_LENGTH] + # elif dtype == 'bool': + # dtype='int8' ret['data_type'] = dtype if shape is not None: ret['shape'] = shape - #now overwrite using the arguments + # now overwrite using the arguments ret.update(kwargs) - #Calculate the index + # Calculate the index if index is not None: - ret['index'] = index #an integer used for ordering the channel in this measurement group + # an integer used for ordering the channel in this measurement group + ret['index'] = index - #Choose a default plot_type for the channel + # Choose a default plot_type for the channel if 'plot_type' not in ret: - default_plot_type = {0:PlotType.Spectrum, 2:PlotType.Image, None:PlotType.No} - try: rank = len(ret['shape']) + default_plot_type = {0: PlotType.Spectrum, + 2: PlotType.Image, None: PlotType.No} + try: + rank = len(ret['shape']) except KeyError: - rank = None #if shape is not known, use the default plot_type + rank = None # if shape is not known, use the default plot_type ret['plot_type'] = default_plot_type.get(rank, PlotType.No) - #And a default value for plot_axes + # And a default value for plot_axes if 'plot_axes' not in ret: - default_axes = {PlotType.No:[], PlotType.Spectrum:[''], PlotType.Image:['', '']} - ret['plot_axes'] = default_axes[ret['plot_type']] # a string defining a colon-separated list of axis names. An axis can be a channel name or "". This shares the syntax of the NeXus @axes attribute + default_axes = {PlotType.No: [], PlotType.Spectrum: [ + ''], PlotType.Image: ['', '']} + # a string defining a colon-separated list of axis names. An axis can + # be a channel name or "". This shares the syntax of the NeXus + # @axes attribute + ret['plot_axes'] = default_axes[ret['plot_type']] return ret - def getElementTypeIcon(t): if t == ChannelView.Channel: return getIcon(":/actions/system-shutdown.svg") @@ -258,6 +272,7 @@ def getElementTypeToolTip(t): class BaseMntGrpChannelItem(TaurusBaseTreeItem): """ """ + def data(self, index): """Returns the data of this node for the given index @@ -278,19 +293,19 @@ def role(self): class MntGrpChannelItem(BaseMntGrpChannelItem): - itemdata_keys_map = {ChannelView.Channel:'label', - ChannelView.Enabled:'enabled', - ChannelView.Output:'output', - ChannelView.Shape:'shape', - ChannelView.DataType:'data_type', - ChannelView.PlotType:'plot_type', - ChannelView.PlotAxes:'plot_axes', -# ChannelView.Timer:'timer', -# ChannelView.Monitor:'monitor', -# ChannelView.Synchronization:'trigger', - ChannelView.Conditioning:'conditioning', - ChannelView.Normalization:'normalization', - ChannelView.NXPath:'nexus_path', + itemdata_keys_map = {ChannelView.Channel: 'label', + ChannelView.Enabled: 'enabled', + ChannelView.Output: 'output', + ChannelView.Shape: 'shape', + ChannelView.DataType: 'data_type', + ChannelView.PlotType: 'plot_type', + ChannelView.PlotAxes: 'plot_axes', + # ChannelView.Timer:'timer', + # ChannelView.Monitor:'monitor', + # ChannelView.Synchronization:'trigger', + ChannelView.Conditioning: 'conditioning', + ChannelView.Normalization: 'normalization', + ChannelView.NXPath: 'nexus_path', } def data(self, index): @@ -316,9 +331,9 @@ def setData(self, index, qvalue): taurus_role = index.model().role(index.column()) str_value = Qt.from_qvariant(qvalue, str) if taurus_role in (ChannelView.Channel, ChannelView.Conditioning, - ChannelView.NXPath, ChannelView.DataType) : + ChannelView.NXPath, ChannelView.DataType): data = str_value - elif taurus_role in (ChannelView.Enabled, ChannelView.Output) : + elif taurus_role in (ChannelView.Enabled, ChannelView.Output): data = Qt.from_qvariant(qvalue, bool) elif taurus_role == ChannelView.PlotType: data = PlotType[str_value] @@ -360,19 +375,19 @@ class MntGrpUnitItem(TaurusBaseTreeItem): class BaseMntGrpChannelModel(TaurusBaseModel): ColumnNames = ("Channel", "enabled", "output", "Shape", "Data Type", "Plot Type", "Plot Axes", "Timer", - "Monitor", "Synchronizer", "Synchronization", "Conditioning", "Normalization", "NeXus Path") + "Monitor", "Synchronizer", "Synchronization", "Conditioning", "Normalization", "NeXus Path") ColumnRoles = ((ChannelView.Channel, ChannelView.Channel), ChannelView.Enabled, - ChannelView.Output, ChannelView.Shape, ChannelView.DataType, ChannelView.PlotType, - ChannelView.PlotAxes, ChannelView.Timer, ChannelView.Monitor, - ChannelView.Synchronizer, ChannelView.Synchronization, ChannelView.Conditioning, - ChannelView.Normalization, ChannelView.NXPath) + ChannelView.Output, ChannelView.Shape, ChannelView.DataType, ChannelView.PlotType, + ChannelView.PlotAxes, ChannelView.Timer, ChannelView.Monitor, + ChannelView.Synchronizer, ChannelView.Synchronization, ChannelView.Conditioning, + ChannelView.Normalization, ChannelView.NXPath) DftFont = Qt.QFont() _availableChannels = {} _availableTriggers = {} - data_keys_map = {ChannelView.Timer:'timer', - ChannelView.Monitor:'monitor', - ChannelView.Synchronization:'synchronization', + data_keys_map = {ChannelView.Timer: 'timer', + ChannelView.Monitor: 'monitor', + ChannelView.Synchronization: 'synchronization', ChannelView.Synchronizer: 'synchronizer' } @@ -416,19 +431,21 @@ def getPyData(self, ctrlname=None, chname=None, key=None): if ctrlname is None: raise ValueError('controller name must be passed') if chname is None: - return self._mgconfig['controllers'][ctrlname] + return self._mgconfig['controllers'][ctrlname] else: - return self._mgconfig['controllers'][ctrlname]['channels'][chname] + return self._mgconfig['controllers'][ctrlname]['channels'][chname] def setupModelData(self, mgconfig): if mgconfig is None: return - root = self._rootItem #@The root could eventually be changed for each unit or controller - channelNodes = [MntGrpChannelItem(self, chcfg, root) for chcfg in getChannelConfigs(mgconfig)] + root = self._rootItem # @The root could eventually be changed for each unit or controller + channelNodes = [MntGrpChannelItem( + self, chcfg, root) for chcfg in getChannelConfigs(mgconfig)] for ch in channelNodes: root.appendChild(ch) self.updateMntGrpChannelIndex(root=root) - #store the whole config object for accessing the info that is not at the channel level + # store the whole config object for accessing the info that is not at + # the channel level self._mgconfig = mgconfig def setDataSource(self, data_src): @@ -449,20 +466,20 @@ def updateMntGrpChannelIndex(self, root=None): def flags(self, index): flags = TaurusBaseModel.flags(self, index) taurus_role = self.role(index.column()) - if taurus_role == ChannelView.Channel: #channel column is not editable + if taurus_role == ChannelView.Channel: # channel column is not editable return flags elif taurus_role == ChannelView.Synchronization: ch_name, ch_data = index.internalPointer().itemData() if not ch_data['_controller_name'].startswith("__"): ch_info = self.getAvailableChannels()[ch_name] - #only timer/monitor columns of counter timers are editable + # only timer/monitor columns of counter timers are editable if ch_info['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): flags |= Qt.Qt.ItemIsEditable elif taurus_role in (ChannelView.Timer, ChannelView.Monitor): ch_name, ch_data = index.internalPointer().itemData() if not ch_data['_controller_name'].startswith("__"): #ch_info = self.getAvailableChannels()[ch_name] - #if 'CTExpChannel' == ch_info['type']: #only timer/monitor columns of counter timers are editable + # if 'CTExpChannel' == ch_info['type']: #only timer/monitor columns of counter timers are editable # flags |= Qt.Qt.ItemIsEditable flags |= Qt.Qt.ItemIsEditable else: @@ -474,12 +491,12 @@ def data(self, index, role=Qt.Qt.DisplayRole): :return: (object) the data for the given index """ - #Try with the normal TaurusBaseModel item-oriented approach + # Try with the normal TaurusBaseModel item-oriented approach try: return TaurusBaseModel.data(self, index, role=role) except: pass - #For those things which are inter-item, we handle them here + # For those things which are inter-item, we handle them here taurus_role = self.role(index.column()) if taurus_role == ChannelView.Synchronization: ch_name, ch_data = index.internalPointer().itemData() @@ -530,7 +547,7 @@ def data(self, index, role=Qt.Qt.DisplayRole): return Qt.QVariant() def setData(self, index, qvalue, role=Qt.Qt.EditRole): - #For those things which are at the unit level, we handle them here + # For those things which are at the unit level, we handle them here taurus_role = self.role(index.column()) if taurus_role in (ChannelView.Timer, ChannelView.Monitor, ChannelView.Synchronization): ch_name, ch_data = index.internalPointer().itemData() @@ -541,7 +558,8 @@ def setData(self, index, qvalue, role=Qt.Qt.EditRole): self._dirty = True self.beginResetModel() - is_settable = ch_info['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel') + is_settable = ch_info['type'] in ( + 'CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel') if taurus_role == ChannelView.Synchronization: data = AcqSynchType[data] if is_settable: @@ -567,8 +585,9 @@ def setData(self, index, qvalue, role=Qt.Qt.EditRole): self._mgconfig[key] = data self.endResetModel() return True - #for the rest, we use the regular TaurusBaseModel item-oriented approach - #ret = self._setData(index, qvalue, role) #@todo we do not use _setData because it is not Qt4.4-compatible + # for the rest, we use the regular TaurusBaseModel item-oriented approach + # ret = self._setData(index, qvalue, role) #@todo we do not use + # _setData because it is not Qt4.4-compatible item = index.internalPointer() item.setData(index, qvalue) self._dirty = True @@ -576,7 +595,8 @@ def setData(self, index, qvalue, role=Qt.Qt.EditRole): index, index) return True - def addChannel(self, chname=None, chinfo=None, ctrlname=None, external=False): #@todo: Very inefficient implementation. We should use {begin|end}InsertRows + # @todo: Very inefficient implementation. We should use {begin|end}InsertRows + def addChannel(self, chname=None, chinfo=None, ctrlname=None, external=False): if chname is None: chname = chinfo['full_name'] @@ -585,11 +605,11 @@ def addChannel(self, chname=None, chinfo=None, ctrlname=None, external=False): desc = self.getAvailableChannels()[chname] ctrlname = desc['controller'] - #update the internal data - self.beginResetModel() #we are altering the internal data here, so we need to protect it + # update the internal data + self.beginResetModel() # we are altering the internal data here, so we need to protect it ctrlsdict = self.dataSource()['controllers'] if not ctrlsdict.has_key(ctrlname): - ctrlsdict[ctrlname] = ctrl = {'channels':{}} + ctrlsdict[ctrlname] = ctrl = {'channels': {}} if not external and chinfo['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): ctrl['timer'] = chname ctrl['monitor'] = chname @@ -599,7 +619,8 @@ def addChannel(self, chname=None, chinfo=None, ctrlname=None, external=False): ctrl = ctrlsdict[ctrlname] channelsdict = ctrl['channels'] if channelsdict.has_key(chname): - self.error('Channel "%s" is already in the measurement group. It will not be added again' % chname) + self.error( + 'Channel "%s" is already in the measurement group. It will not be added again' % chname) return self._dirty = True @@ -607,16 +628,17 @@ def addChannel(self, chname=None, chinfo=None, ctrlname=None, external=False): channelsdict[chname] = createChannelDict(chname) else: channelsdict[chname] = createChannelDict(chinfo) - self.endResetModel() #we are altering the internal data here, so we need to protect it - self.refresh() #note that another reset will be done here... + self.endResetModel() # we are altering the internal data here, so we need to protect it + self.refresh() # note that another reset will be done here... #import pprint - #pprint.pprint(self.dataSource()) + # pprint.pprint(self.dataSource()) - def removeChannels(self, chnames): #@todo: Very inefficient implementation. We should use {begin|end}InsertRows - #update the internal data + # @todo: Very inefficient implementation. We should use {begin|end}InsertRows + def removeChannels(self, chnames): + # update the internal data self._dirty = True - self.beginResetModel() #we are altering the internal data here, so we need to protect it + self.beginResetModel() # we are altering the internal data here, so we need to protect it for chname in chnames: avail_channels = self.getAvailableChannels() if chname in avail_channels: @@ -626,7 +648,8 @@ def removeChannels(self, chnames): #@todo: Very inefficient implementation. We #@todo: This assumes that if it is not in the list of avail_channels, it must be an external tango channel ctrlname = '__tango__' try: - self.dataSource()['controllers'][ctrlname]['channels'].pop(chname) + self.dataSource()['controllers'][ctrlname][ + 'channels'].pop(chname) try: if not self.dataSource()['controllers'][ctrlname]['channels']: self.dataSource()['controllers'].pop(ctrlname) @@ -635,10 +658,11 @@ def removeChannels(self, chnames): #@todo: Very inefficient implementation. We except: self.error('cannot find "%s" for removing' % chname) - self.endResetModel() #we are altering the internal data here, so we need to protect it - self.refresh() #note that another reset will be done here... + self.endResetModel() # we are altering the internal data here, so we need to protect it + self.refresh() # note that another reset will be done here... - def swapChannels(self, root, row1, row2): #@todo: Very inefficient implementation. We should use {begin|end}MoveRows + # @todo: Very inefficient implementation. We should use {begin|end}MoveRows + def swapChannels(self, root, row1, row2): self._dirty = True n1, d1 = root.child(row1).itemData() n2, d2 = root.child(row2).itemData() @@ -652,15 +676,18 @@ def isDataChanged(self): def setDataChanged(self, datachanged): self._dirty = datachanged + class MntGrpChannelModel(BaseMntGrpChannelModel): '''A BaseMntGrpChannelModel that communicates with a MntGrp device for setting and reading the configuration ''' def setDataSource(self, mg): if self._data_src is not None: - Qt.QObject.disconnect(self._data_src, Qt.SIGNAL('configurationChanged'), self.configurationChanged) + Qt.QObject.disconnect(self._data_src, Qt.SIGNAL( + 'configurationChanged'), self.configurationChanged) if mg is not None: - Qt.QObject.connect(mg, Qt.SIGNAL('configurationChanged'), self.configurationChanged) + Qt.QObject.connect(mg, Qt.SIGNAL( + 'configurationChanged'), self.configurationChanged) BaseMntGrpChannelModel.setDataSource(self, mg) def configurationChanged(self): @@ -689,6 +716,7 @@ def getLocalData(self): class AxesSelector(Qt.QWidget): + def __init__(self, parent, n=0, choices=None): '''Shows n comboboxes populated with choices. If n is 0, it just shows a LineEdit instead''' Qt.QWidget.__init__(self, parent) @@ -730,6 +758,7 @@ def setCurrentChoices(self, choice): class ChannelDelegate(Qt.QStyledItemDelegate): + def createEditor(self, parent, option, index): model = index.model() taurus_role = model.role(index.column()) @@ -748,7 +777,8 @@ def createEditor(self, parent, option, index): return None ret = AxesSelector(parent, n=n) else: - ret = Qt.QStyledItemDelegate.createEditor(self, parent, option, index) + ret = Qt.QStyledItemDelegate.createEditor( + self, parent, option, index) ret.setAutoFillBackground(True) return ret @@ -773,13 +803,15 @@ def setEditorData(self, editor, index): # if it is a timer capable type of element if all_channels[ch_name]['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): for full_name, channel_data in ctrl_dict: - editor.addItem(channel_data['name'], Qt.QVariant(full_name)) + editor.addItem( + channel_data['name'], Qt.QVariant(full_name)) current = Qt.from_qvariant(model.data(index), str) editor.setCurrentIndex(editor.findText(current)) else: for ctrl_data in dataSource['controllers'].values(): for channel in ctrl_data['channels']: - editor.addItem(channel['name'], Qt.QVariant(channel['full_name'])) + editor.addItem(channel['name'], Qt.QVariant( + channel['full_name'])) current = dataSource.get(key) # current global timer/monitor editor.setCurrentIndex(editor.findData(Qt.QVariant(current))) elif taurus_role == ChannelView.Synchronization: @@ -787,7 +819,8 @@ def setEditorData(self, editor, index): current = Qt.from_qvariant(model.data(index), str) editor.setCurrentIndex(editor.findText(current)) elif taurus_role == ChannelView.PlotAxes: - selectables = ['', ''] + [n for n, d in getChannelConfigs(dataSource)] + selectables = ['', ''] + \ + [n for n, d in getChannelConfigs(dataSource)] editor.setChoices(selectables) current = Qt.from_qvariant(model.data(index), str) editor.setCurrentChoices(current) @@ -813,12 +846,14 @@ def setModelData(self, editor, model, index): if new_value == old_value: return ch_name, ch_data = index.internalPointer().itemData() - channels = getChannelConfigs(dataSource, ctrls=[ch_data['_controller_name']]) + channels = getChannelConfigs( + dataSource, ctrls=[ch_data['_controller_name']]) affected = [d['name'] for n, d in channels] if len(affected) > 1: op = Qt.QMessageBox.question(editor, "Caution: multiple channels affected", - "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join(affected), - Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) + "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join( + affected), + Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return data = Qt.QVariant(new_value) @@ -836,8 +871,10 @@ def setModelData(self, editor, model, index): selected_master = editor.itemData(editor.currentIndex()) if ch_info['type'] in ('CTExpChannel', 'OneDExpChannel', 'TwoDExpChannel'): affected = [] - ctrl_data = model.getPyData(ctrlname=ch_data['_controller_name']) - channels = getChannelConfigs(dataSource, ctrls=[ch_data['_controller_name']]) + ctrl_data = model.getPyData( + ctrlname=ch_data['_controller_name']) + channels = getChannelConfigs( + dataSource, ctrls=[ch_data['_controller_name']]) for n, d in channels: affected.append(d['name']) # if old timer/monitor was also the global, then non @@ -853,8 +890,9 @@ def setModelData(self, editor, model, index): if len(affected) > 1: op = Qt.QMessageBox.question(editor, "Caution: multiple channels affected", - "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join(affected), - Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) + "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join( + affected), + Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return else: @@ -869,8 +907,9 @@ def setModelData(self, editor, model, index): affected.append(d['name']) if len(affected) > 1: op = Qt.QMessageBox.question(editor, "Caution: multiple channels affected", - "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join(affected), - Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) + "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join( + affected), + Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return model.setData(index, selected_master) @@ -894,8 +933,9 @@ def setModelData(self, editor, model, index): if len(affected) > 1: op = Qt.QMessageBox.question(editor, "Caution: multiple channels affected", - "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join(affected), - Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) + "This change will also affect the following channels:\n- %s \nContinue?" % "\n- ".join( + affected), + Qt.QMessageBox.Yes | Qt.QMessageBox.Cancel) if op != Qt.QMessageBox.Yes: return @@ -910,16 +950,17 @@ class MntGrpChannelEditor(TaurusBaseTableWidget): """ KnownPerspectives = { - "Channel" : { - "label" : "Channels", - "icon" : ":/actions/system-shutdown.svg", - "tooltip" : "View by channel", - "model" : [BaseMntGrpChannelModel, ], + "Channel": { + "label": "Channels", + "icon": ":/actions/system-shutdown.svg", + "tooltip": "View by channel", + "model": [BaseMntGrpChannelModel, ], }, } DftPerspective = "Channel" - _simpleViewColumns = (ChannelView.Channel, ChannelView.Output, ChannelView.Shape, ChannelView.PlotType, ChannelView.PlotAxes) + _simpleViewColumns = (ChannelView.Channel, ChannelView.Output, + ChannelView.Shape, ChannelView.PlotType, ChannelView.PlotAxes) _simpleView = False def __init__(self, parent=None, designMode=False, with_filter_widget=True, perspective=None): @@ -929,9 +970,11 @@ def __init__(self, parent=None, designMode=False, with_filter_widget=True, persp self.setContextMenuPolicy(Qt.Qt.ActionsContextMenu) self._simpleViewAction = Qt.QAction("Simple View", self) self._simpleViewAction.setCheckable(True) - self.connect(self._simpleViewAction, Qt.SIGNAL("toggled(bool)"), self.setSimpleView) + self.connect(self._simpleViewAction, Qt.SIGNAL( + "toggled(bool)"), self.setSimpleView) self.addAction(self._simpleViewAction) - self.registerConfigProperty(self.isSimpleView, self.setSimpleView, "simpleView") + self.registerConfigProperty( + self.isSimpleView, self.setSimpleView, "simpleView") def isSimpleView(self): return self._simpleView @@ -940,7 +983,9 @@ def setSimpleView(self, simpleview): if simpleview == self.isSimpleView(): return columnRoles = list(self.getQModel().ColumnRoles) - columnRoles[0] = columnRoles[0][-1] #account for the fact that the first element is a tuple instead of a role + # account for the fact that the first element is a tuple instead of a + # role + columnRoles[0] = columnRoles[0][-1] columnIndexes = [columnRoles.index(r) for r in self._simpleViewColumns] for i in range(self.getQModel().columnCount()): hide = simpleview and (i not in columnIndexes) @@ -954,29 +999,36 @@ def resetSimpleView(self): def createViewWidget(self): tableView = TaurusBaseTableWidget.createViewWidget(self) self._delegate = ChannelDelegate(self) - #self._delegate.setItemEditorFactory(Qt.QItemEditorFactory()) #This causes a segfault when calling ChannelDelegate.createEditor + # self._delegate.setItemEditorFactory(Qt.QItemEditorFactory()) #This + # causes a segfault when calling ChannelDelegate.createEditor tableView.setItemDelegate(self._delegate) tableView.setSortingEnabled(False) - self.connect(self._editorBar, Qt.SIGNAL("addTriggered"), self.addChannel) - #TODO: For Taurus 4 compatibility + self.connect(self._editorBar, Qt.SIGNAL( + "addTriggered"), self.addChannel) + # TODO: For Taurus 4 compatibility if hasattr(self._editorBar, "addTriggered"): self._editorBar.addTriggered.connect(self.addChannel) - self.connect(self._editorBar, Qt.SIGNAL("removeTriggered"), self.removeChannels) - #TODO: For Taurus 4 compatibility + self.connect(self._editorBar, Qt.SIGNAL( + "removeTriggered"), self.removeChannels) + # TODO: For Taurus 4 compatibility if hasattr(self._editorBar, "removeTriggered"): self._editorBar.removeTriggered.connect(self.removeChannels) - self.connect(self._editorBar, Qt.SIGNAL("moveUpTriggered"), self.moveUpChannel) - #TODO: For Taurus 4 compatibility + self.connect(self._editorBar, Qt.SIGNAL( + "moveUpTriggered"), self.moveUpChannel) + # TODO: For Taurus 4 compatibility if hasattr(self._editorBar, "moveUpTriggered"): self._editorBar.moveUpTriggered.connect(self.moveUpChannel) - self.connect(self._editorBar, Qt.SIGNAL("moveDownTriggered"), self.moveDownChannel) - #TODO: For Taurus 4 compatibility + self.connect(self._editorBar, Qt.SIGNAL( + "moveDownTriggered"), self.moveDownChannel) + # TODO: For Taurus 4 compatibility if hasattr(self._editorBar, "moveDownTriggered"): self._editorBar.moveDownTriggered.connect(self.moveDownChannel) - self.connect(self._editorBar, Qt.SIGNAL("moveTopTriggered"), self.moveTopChannel) + self.connect(self._editorBar, Qt.SIGNAL( + "moveTopTriggered"), self.moveTopChannel) if hasattr(self._editorBar, "moveTopTriggered"): self._editorBar.moveTopTriggered.connect(self.moveTopChannel) - self.connect(self._editorBar, Qt.SIGNAL("moveBottomTriggered"), self.moveBottomChannel) + self.connect(self._editorBar, Qt.SIGNAL( + "moveBottomTriggered"), self.moveBottomChannel) if hasattr(self._editorBar, "moveBottomTriggered"): self._editorBar.moveBottomTriggered.connect(self.moveBottomChannel) return tableView @@ -996,10 +1048,11 @@ def addChannel(self, channel=None): if channel is None: shown = [n for n, d in getChannelConfigs(dataSource)] avail_channels = qmodel.getAvailableChannels() - clist = [ ch_info['name'] for ch_name, ch_info in avail_channels.items() - if ch_name not in shown ] + clist = [ch_info['name'] for ch_name, ch_info in avail_channels.items() + if ch_name not in shown] clist = sorted(clist) + ['(Other...)'] - chname, ok = Qt.QInputDialog.getItem(self, "New Channel", "Choose channel:", clist, 0, False) + chname, ok = Qt.QInputDialog.getItem( + self, "New Channel", "Choose channel:", clist, 0, False) if not ok: return chname = str(chname) @@ -1009,7 +1062,8 @@ def addChannel(self, channel=None): if not ok: return for m in models: - qmodel.addChannel(chname=m, ctrlname='__tango__', external=True) + qmodel.addChannel( + chname=m, ctrlname='__tango__', external=True) else: for ch_info in avail_channels.values(): if ch_info['name'] == chname: @@ -1093,6 +1147,5 @@ def getQtDesignerPluginInfo(cls): ret['icon'] = ":/designer/table.png" return ret - simpleView = Qt.pyqtProperty("bool", isSimpleView, setSimpleView, resetSimpleView) - - + simpleView = Qt.pyqtProperty( + "bool", isSimpleView, setSimpleView, resetSimpleView) diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/sardanabasewizard.py b/src/sardana/taurus/qt/qtgui/extra_sardana/sardanabasewizard.py index 3fb402a8cc..5d19af1efe 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/sardanabasewizard.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/sardanabasewizard.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -79,4 +79,3 @@ def setPage(self, id, page): def getPages(self): return self._pages - diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/sardanaeditor.py b/src/sardana/taurus/qt/qtgui/extra_sardana/sardanaeditor.py index fb94638faf..eb81b1707b 100755 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/sardanaeditor.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/sardanaeditor.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -94,6 +94,7 @@ def {macro_name}(self): """ + class NewElementWizard(SardanaBaseWizard): pass @@ -110,7 +111,7 @@ def __init__(self, parent=None): class SardanaLibProxyModel(SardanaBaseProxyModel): - ALLOWED_TYPES = 'MacroLibrary', #'ControllerLibrary', + ALLOWED_TYPES = 'MacroLibrary', # 'ControllerLibrary', def filterAcceptsRow(self, sourceRow, sourceParent): sourceModel = self.sourceModel() @@ -126,12 +127,12 @@ def filterAcceptsRow(self, sourceRow, sourceParent): class SardanaLibTreeWidget(SardanaElementTreeWidget): - KnownPerspectives = { "Type" : { - "label" : "By lib", - "icon" : ":/python-package.png", - "tooltip" : "View elements by library", - "model" : [SardanaLibProxyModel, SardanaElementTypeModel], - }, + KnownPerspectives = {"Type": { + "label": "By lib", + "icon": ":/python-package.png", + "tooltip": "View elements by library", + "model": [SardanaLibProxyModel, SardanaElementTypeModel], + }, } DftPerspective = "Type" @@ -150,10 +151,11 @@ def __init__(self, parent=None, designMode=None): with_filter_widget=False,) elementTree.treeView().setColumnHidden(1, True) try: - self._elementTree.itemDoubleClicked.connect(self.on_element_clicked) + self._elementTree.itemDoubleClicked.connect( + self.on_element_clicked) except AttributeError: self.connect(self._elementTree, Qt.SIGNAL("itemDoubleClicked"), - self.on_element_clicked) + self.on_element_clicked) self.insertWidget(0, self._elementTree) self.setAutoTooltip(False) @@ -169,27 +171,32 @@ def createMenuActions(self): on_save_apply = functools.partial(self.on_save, apply=True) self.new_action = create_action(self, "New...", - icon=Qt.QIcon.fromTheme('document-new'), - tip="Create a new macro or controller class", - triggered=self.on_new, shortcut=Qt.QKeySequence.New) + icon=Qt.QIcon.fromTheme( + 'document-new'), + tip="Create a new macro or controller class", + triggered=self.on_new, shortcut=Qt.QKeySequence.New) self.open_action = create_action(self, "Open...", - icon=Qt.QIcon.fromTheme('document-open'), - tip="Open macro(s) or controller(s)", - triggered=self.on_open, shortcut=Qt.QKeySequence.Open) + icon=Qt.QIcon.fromTheme( + 'document-open'), + tip="Open macro(s) or controller(s)", + triggered=self.on_open, shortcut=Qt.QKeySequence.Open) self.save_action = create_action(self, "Save", - icon=Qt.QIcon.fromTheme('document-save'), - tip="Save the current selected item", - triggered=on_save) + icon=Qt.QIcon.fromTheme( + 'document-save'), + tip="Save the current selected item", + triggered=on_save) self.save_and_apply_action = create_action(self, "Save && apply", - triggered=on_save_apply, - icon=Qt.QIcon.fromTheme('document-save'), - tip="Save the current selected item and apply the new code", - shortcut=Qt.QKeySequence.Save) + triggered=on_save_apply, + icon=Qt.QIcon.fromTheme( + 'document-save'), + tip="Save the current selected item and apply the new code", + shortcut=Qt.QKeySequence.Save) self.revert_action = create_action(self, "Revert", - icon=Qt.QIcon.fromTheme('edit-undo'), - tip="Revert the current selected item code", - triggered=self.on_revert) + icon=Qt.QIcon.fromTheme( + 'edit-undo'), + tip="Revert the current selected item code", + triggered=self.on_revert) io_actions = [self.new_action, self.open_action, self.save_action, self.revert_action] @@ -250,14 +257,15 @@ def new_macro(self, template): macro_lib_names = macro_libraries.keys() macro_lib_names.sort() macro_lib_name, ok = Qt.QInputDialog.getItem(self, "Macro library", msg, - macro_lib_names, current=0, editable=False) + macro_lib_names, current=0, editable=False) if not ok: return macro_lib_name = str(macro_lib_name) macro_lib = macro_libraries[macro_lib_name] fname, path = macro_lib.file_path, macro_lib.path - fname = fname[fname.index(osp.sep) + 1:] # transform into relative path + # transform into relative path + fname = fname[fname.index(osp.sep) + 1:] local_filename = osp.join(self._tmp_dir, fname) msg = "Please give new macro name" @@ -270,10 +278,10 @@ def new_macro(self, template): return if macro_name in macros: res = Qt.QMessageBox.information(self, "Macro already exists", - "A macro named '%s' already exists in '%s'.\n" - "Please give a different macro name" - % (macro_name, macro_lib_name), - Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel, Qt.QMessageBox.Ok) + "A macro named '%s' already exists in '%s'.\n" + "Please give a different macro name" + % (macro_name, macro_lib_name), + Qt.QMessageBox.Ok | Qt.QMessageBox.Cancel, Qt.QMessageBox.Ok) if res == Qt.QMessageBox.Cancel: return continue @@ -288,7 +296,8 @@ def new_macro(self, template): if not self._prepare_path(path): raise Exception("Error trying to prepare path for %s", path) self.debug("Creating local file %s...", local_filename) - fname, lib_code, line = macro_server.GetMacroCode((macro_lib_name,)) + fname, lib_code, line = macro_server.GetMacroCode( + (macro_lib_name,)) fd = file(local_filename, "w") fd.write(lib_code) fd.close() @@ -318,36 +327,37 @@ def new_macro_library(self): ms = self.getModelObj() ms_path = ms.getMacroPathObj() directory, ok = Qt.QInputDialog.getItem(self, "New macro module", - "Select the directory where you want the new macro module to " \ - "be placed", - ms_path.macro_path, current=0, editable=False) + "Select the directory where you want the new macro module to " + "be placed", + ms_path.macro_path, current=0, editable=False) if not ok: return directory = str(directory) ok = 0 while not ok: mod, ok = Qt.QInputDialog.getText(self, "New macro module", - "Module name:", Qt.QLineEdit.Normal, "") + "Module name:", Qt.QLineEdit.Normal, "") if not ok: return mod = str(mod) m, ext = osp.splitext(mod) if len(ext): - if ext != ".py" : + if ext != ".py": Qt.QMessageBox.critical(self, "Wrong extension", - "When given, file extension MUST be .py.") + "When given, file extension MUST be .py.") ok = 0 continue else: mod = mod + ".py" self._prepare_path(directory) filename = osp.join(directory, mod) - rel_filename = filename[filename.index(osp.sep) + 1:] # transform into relative path + # transform into relative path + rel_filename = filename[filename.index(osp.sep) + 1:] local_filename = osp.join(self._tmp_dir, rel_filename) f = file(local_filename, "w") - #TODO: ask for additional imports - #TODO: check if door environment has copyright variable + # TODO: ask for additional imports + # TODO: check if door environment has copyright variable pars = dict(copyright="", non_sardana_imports="", sardana_imports="") @@ -377,26 +387,31 @@ def open_macros(self, macros): for macro_info in macros: name, fname = macro_info.name, macro_info.file_path module = macro_info.module - fname = fname[fname.index(osp.sep) + 1:] # transform into relative path + # transform into relative path + fname = fname[fname.index(osp.sep) + 1:] local_filename = osp.join(self._tmp_dir, fname) idx = editorstack.has_filename(local_filename) if idx is not None and last_answer not in all_any: last_answer = Qt.QMessageBox.question(self, - "Macro file '{0}' already opened".format(module), - "All changes to {0} will be lost." - "
Do you want to revert file from the server ignoring " - "any possible changes you (may) have made?".format(module), - Qt.QMessageBox.Yes | Qt.QMessageBox.YesToAll | \ - Qt.QMessageBox.No | Qt.QMessageBox.NoToAll, - Qt.QMessageBox.No) + "Macro file '{0}' already opened".format( + module), + "All changes to {0} will be lost." + "
Do you want to revert file from the server ignoring " + "any possible changes you (may) have made?".format( + module), + Qt.QMessageBox.Yes | Qt.QMessageBox.YesToAll | + Qt.QMessageBox.No | Qt.QMessageBox.NoToAll, + Qt.QMessageBox.No) if idx is None or last_answer in yes_any: if not self._prepare_path(macro_info.path): Qt.QMessageBox.warning(self, - "Error trying to prepare '{0}'".format(module), - "An error occured trying to prepare '{0}'".format(module), - Qt.QMessageBox.Ok, Qt.QMessageBox.Ok) + "Error trying to prepare '{0}'".format( + module), + "An error occured trying to prepare '{0}'".format( + module), + Qt.QMessageBox.Ok, Qt.QMessageBox.Ok) continue _, code, line = self.get_macro_code(module, name) line = int(line) @@ -425,26 +440,31 @@ def open_macro_libraries(self, macro_libraries): for macro_library in macro_libraries: name, fname = macro_library.name, macro_library.file_path module = macro_library.module - fname = fname[fname.index(osp.sep) + 1:] # transform into relative path + # transform into relative path + fname = fname[fname.index(osp.sep) + 1:] local_filename = osp.join(self._tmp_dir, fname) idx = editorstack.has_filename(local_filename) if idx is not None and last_answer not in all_any: last_answer = Qt.QMessageBox.question(self, - "Macro file '{0}' already opened".format(module), - "All changes to {0} will be lost." - "
Do you want to revert file from the server ignoring " - "any possible changes you (may) have made?".format(module), - Qt.QMessageBox.Yes | Qt.QMessageBox.YesToAll | \ - Qt.QMessageBox.No | Qt.QMessageBox.NoToAll, - Qt.QMessageBox.No) + "Macro file '{0}' already opened".format( + module), + "All changes to {0} will be lost." + "
Do you want to revert file from the server ignoring " + "any possible changes you (may) have made?".format( + module), + Qt.QMessageBox.Yes | Qt.QMessageBox.YesToAll | + Qt.QMessageBox.No | Qt.QMessageBox.NoToAll, + Qt.QMessageBox.No) if idx is None or last_answer in yes_any: if not self._prepare_path(macro_library.path): Qt.QMessageBox.warning(self, - "Error trying to prepare '{0}'".format(module), - "An error occured trying to prepare '{0}'".format(module), - Qt.QMessageBox.Ok, Qt.QMessageBox.Ok) + "Error trying to prepare '{0}'".format( + module), + "An error occured trying to prepare '{0}'".format( + module), + Qt.QMessageBox.Ok, Qt.QMessageBox.Ok) continue _, code, line = self.get_macro_code(module) line = int(line) @@ -495,7 +515,7 @@ def set_macro_code(self, filename, code, apply=True): def get_macro_code(self, module_name, macro_name=None): ms = self.getModelObj() - pars = [ module_name ] + pars = [module_name] if macro_name is not None: pars.append(macro_name) return ms.GetMacroCode(pars) @@ -524,7 +544,8 @@ def prepare_filesystem(self): self.warning("Could not prepare local filesystem to store macros") return False ms_name = ms.getSimpleName().replace('/', '_') - self._tmp_dir = tempfile.mkdtemp(prefix=ms_name, dir=self._base_tmp_dir) + self._tmp_dir = tempfile.mkdtemp( + prefix=ms_name, dir=self._base_tmp_dir) self._is_filesystem_prepared = True return True @@ -537,11 +558,12 @@ def closeEvent(self, event): def demo(model_name="MS_BL98"): test = SardanaEditor() test.resize(1000, 800) - #test.load(__file__) + # test.load(__file__) test.setModel(model_name) test.show() return test + def main(): import sys import taurus.qt.qtgui.application diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/startup.py b/src/sardana/taurus/qt/qtgui/extra_sardana/startup.py index 2d6272ae12..059ff01db1 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/startup.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/startup.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -31,16 +31,19 @@ import sys + def __run_pythonstartup_script(): import os filename = os.environ.get('PYTHONSTARTUP') if filename and os.path.isfile(filename): execfile(filename) + def __run_init_commands(): import os return os.environ.get('PYTHONINITCOMMANDS') + def __remove_from_syspath__(): """Remove this module's path from sys.path""" import os.path as osp @@ -54,10 +57,11 @@ class UserModuleDeleter(object): """ User Module Deleter (UMD) aims at deleting user modules to force Python to deeply reload them during import - + pathlist [list]: blacklist in terms of module path namelist [list]: blacklist in terms of module name """ + def __init__(self, namelist=None, pathlist=None): if namelist is None: namelist = [] @@ -78,7 +82,7 @@ def is_module_blacklisted(self, modname, modpath): def run(self, verbose=False): """ Del user modules to force Python to deeply reload them - + Do not del modules which are considered as system modules, i.e. modules installed in subdirectories of Python interpreter's binary Do not del C modules @@ -101,6 +105,7 @@ def run(self, verbose=False): __umd__ = None + def runfile(filename, args=None, wdir=None): """ Run filename diff --git a/src/sardana/taurus/qt/qtgui/extra_sardana/ui/__init__.py b/src/sardana/taurus/qt/qtgui/extra_sardana/ui/__init__.py index c058d0cbc5..b9f9196959 100644 --- a/src/sardana/taurus/qt/qtgui/extra_sardana/ui/__init__.py +++ b/src/sardana/taurus/qt/qtgui/extra_sardana/ui/__init__.py @@ -2,23 +2,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/test/__init__.py b/src/sardana/test/__init__.py index 7e819af449..102add909c 100644 --- a/src/sardana/test/__init__.py +++ b/src/sardana/test/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/test/test_sardanavalue.py b/src/sardana/test/test_sardanavalue.py index 4188db0089..08a287bb5c 100644 --- a/src/sardana/test/test_sardanavalue.py +++ b/src/sardana/test/test_sardanavalue.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/test/testsuite.py b/src/sardana/test/testsuite.py index f4bdd261b5..087b7192a6 100644 --- a/src/sardana/test/testsuite.py +++ b/src/sardana/test/testsuite.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -59,9 +59,11 @@ def get_sardana_suite(exclude_pattern='(?!)'): """discover all tests in sardana, except those matching `exclude_pattern`""" loader = unittest.defaultTestLoader start_dir = os.path.dirname(sardana.__file__) - suite = loader.discover(start_dir, top_level_dir=os.path.dirname(start_dir)) + suite = loader.discover( + start_dir, top_level_dir=os.path.dirname(start_dir)) return _filter_suite(suite, exclude_pattern) + def get_sardana_unitsuite(): """Provide test suite with only unit tests. These exclude: - functional tests of macros that requires the "sar_demo environment" @@ -70,6 +72,7 @@ def get_sardana_unitsuite(): 'sardana\.tango\.pool\.test*' return get_sardana_suite(exclude_pattern=pattern) + def run(exclude_pattern='(?!)'): '''Runs all tests for the sardana package diff --git a/src/sardana/tools/config/fods_to_sar.py b/src/sardana/tools/config/fods_to_sar.py index 9685f26ede..1ce0e31cde 100644 --- a/src/sardana/tools/config/fods_to_sar.py +++ b/src/sardana/tools/config/fods_to_sar.py @@ -10,13 +10,16 @@ """ -import sys, os, types +import sys +import os +import types from lxml import etree + def transform(f): directory = os.path.dirname(os.path.abspath(__file__)) xslt_filename = os.path.join(directory, "FODS_TO_SAR.xslt") - + t = etree.XSLT(etree.parse(xslt_filename)) if type(f) in types.StringTypes: doc = etree.parse(f) @@ -24,11 +27,12 @@ def transform(f): doc = f return t(doc) + def main(): if len(sys.argv) < 2: print __doc__ sys.exit(1) - + filename = sys.argv[1] t = transform(filename) print etree.tostring(t, pretty_print=True) diff --git a/src/sardana/tools/config/get_pool_config.py b/src/sardana/tools/config/get_pool_config.py index a3a2ee2e88..d2288de19f 100644 --- a/src/sardana/tools/config/get_pool_config.py +++ b/src/sardana/tools/config/get_pool_config.py @@ -5,6 +5,7 @@ import PyTango import taurus + def checkPoolElements(pool): pool_dev = taurus.Device(pool) @@ -12,7 +13,8 @@ def checkPoolElements(pool): pool_ctrl_classes = {} for info in pool_dev['ControllerClassList'].value: info = json.loads(info) - ctrl_class, library_path, ctrl_type = info['name'], info['file_path'], info['type'] + ctrl_class, library_path, ctrl_type = info[ + 'name'], info['file_path'], info['type'] pool_ctrl_classes[ctrl_class] = (library_path, ctrl_type) # GET CONTROLLERS INFO @@ -35,12 +37,13 @@ def checkPoolElements(pool): ctrl_library = pool_ctrl_classes[ctrl_class][0] except KeyError: print ("#WARNING: There is no controller class %s for controller %s" % - (ctrl_class, ctrl_name)) + (ctrl_class, ctrl_name)) continue ctrl_type = str(info['main_type']) # sardana script is not compatible with the new type CTExpChannel # so substitute it by the old type: CounterTimer - if ctrl_type == 'CTExpChannel': ctrl_type = 'CounterTimer' + if ctrl_type == 'CTExpChannel': + ctrl_type = 'CounterTimer' pool_controllers_by_type[ctrl_type].append(ctrl_name) ctrl_properties = {} ctrl_elements = [] @@ -61,14 +64,12 @@ def checkPoolElements(pool): pool_controllers[ctrl_name]['elements'] = ctrl_elements pool_controllers[ctrl_name]['ctrl_pool_elements'] = ctrl_pool_elements - pool_elements = {} pool_elements['ExpChannels'] = pool_dev['ExpChannelList'].value or [] pool_elements['Motors'] = pool_dev['MotorList'].value or [] pool_elements['IORegs'] = pool_dev['IORegisterList'].value or [] pool_instruments = pool_dev['InstrumentList'].value or [] - pool_measurement_groups = {} for info in pool_dev['MeasurementGroupList'].value: info_splitted = json.loads(info) @@ -91,13 +92,13 @@ def checkPoolElements(pool): elements_ordered = [elements[i] for i in indexes] pool_measurement_groups[mg_name] = elements_ordered - ### print '\n' - ### print '----------------------------------------------------------------' - ### print 'ELEMENTS FOR POOL ' + pool - ### print '----------------------------------------------------------------' - ### for element_type in pool_elements.keys(): + # print '\n' + # print '----------------------------------------------------------------' + # print 'ELEMENTS FOR POOL ' + pool + # print '----------------------------------------------------------------' + # for element_type in pool_elements.keys(): ### elements = pool_elements[element_type] - ### print element_type+':',len(elements) + # print element_type+':',len(elements) db = taurus.Database() pool_elements_detail = {} @@ -122,28 +123,28 @@ def checkPoolElements(pool): pool_elements_detail[alias]['pool'] = pool pool_elements_detail[alias]['ctrl'] = ctrl_name pool_elements_detail[alias]['name'] = alias - pool_elements_detail[alias]['axis'] = dev_name.rsplit('/',1)[1] - pool_elements_detail[alias]['instrument'] = element_dev.Instrument.split('(')[0] + pool_elements_detail[alias]['axis'] = dev_name.rsplit('/', 1)[1] + pool_elements_detail[alias]['instrument'] = element_dev.Instrument.split('(')[ + 0] pool_elements_detail[alias]['attr_dicts'] = {} - + normal_name = element_dev.getNormalName() attrs = element_dev.get_attribute_list() for attr, attr_dict in db.get_device_attribute_property( - normal_name, - map(str,attrs) - ).iteritems(): + normal_name, + map(str, attrs) + ).iteritems(): if len(attr_dict) > 0: pool_elements_detail[alias]['attr_dicts'][attr] = attr_dict else: if attr.lower() in ['position', 'value']: - print '***',specific_element_type, alias, attr, 'NO MEMORIZED ATTRIBUTES OR ATTRIBUTE CONFIGURATIONS ***' - + print '***', specific_element_type, alias, attr, 'NO MEMORIZED ATTRIBUTES OR ATTRIBUTE CONFIGURATIONS ***' - ### print '\n' - ### print '----------------------------------------------------------------' - ### print len(pool_instruments),'INSTRUMENTS FOR POOL ' + pool - ### print '----------------------------------------------------------------' - ### print pool_instruments + # print '\n' + # print '----------------------------------------------------------------' + # print len(pool_instruments),'INSTRUMENTS FOR POOL ' + pool + # print '----------------------------------------------------------------' + # print pool_instruments # CHECK ELEMENTS WITHOUT INSTRUMENT for element_type in pool_elements.keys(): @@ -157,57 +158,57 @@ def checkPoolElements(pool): ctrl_axis = info_splitted["axis"] specific_element_type = info_splitted["type"] - # Add info of 'physicals needed' in pseudomotor and pseudocounter controllers + # Add info of 'physicals needed' in pseudomotor and pseudocounter + # controllers try: ctrl = pool_controllers[ctrl_name] except KeyError: print ("#WARNING: There is no controller %s for element %s" % - (ctrl_name, alias)) + (ctrl_name, alias)) continue ctrl['ctrl_pool_elements'].append(alias) if specific_element_type in ['PseudoMotor', 'PseudoCounter']: ctrl['elements'] = ';'.join(info_splitted["elements"]) - element_dev = taurus.Device(alias) if element_dev['Instrument'].value == '': elements_with_no_instrument.append(alias) - ### if len(elements_with_no_instrument) > 0: - ### print '\n***',element_type,'with no Instrument:',elements_with_no_instrument,'***' - - - ### for ctrl_type, controllers in pool_controllers_by_type.iteritems(): - ### if len(controllers) == 0: - ### continue - ### - ### print '\n' - ### print '----------------------------------------------------------------' - ### print len(controllers), ctrl_type, 'CONTROLLERS FOR POOL ' + pool - ### print '----------------------------------------------------------------' - ### - ### for ctrl in controllers: - ### ###print 'Controller',ctrl,':' - ### ###for k, v in details.iteritems(): - ### ### if k == 'ctrl_pool_elements': - ### ### print '\tElements count:\t'+str(len(v)) - ### ### print '\t'+k+':\t'+str(v) + # if len(elements_with_no_instrument) > 0: + # print '\n***',element_type,'with no + # Instrument:',elements_with_no_instrument,'***' + + # for ctrl_type, controllers in pool_controllers_by_type.iteritems(): + # if len(controllers) == 0: + # continue + ### + # print '\n' + # print '----------------------------------------------------------------' + # print len(controllers), ctrl_type, 'CONTROLLERS FOR POOL ' + pool + # print '----------------------------------------------------------------' + ### + # for ctrl in controllers: + # print 'Controller',ctrl,':' + # for k, v in details.iteritems(): + # if k == 'ctrl_pool_elements': + # print '\tElements count:\t'+str(len(v)) + # print '\t'+k+':\t'+str(v) ### ### - ### ###pool_controllers[ctrl_name]['type'] = ctrl_type - ### ###pool_controllers[ctrl_name]['name'] = ctrl_name - ### ###pool_controllers[ctrl_name]['file'] = ctrl_library - ### ###pool_controllers[ctrl_name]['class'] = ctrl_class - ### ###pool_controllers[ctrl_name]['properties'] = ctrl_properties - ### ###pool_controllers[ctrl_name]['elements'] = ctrl_elements - ### ###pool_controllers[ctrl_name]['ctrl_pool_elements'] = ctrl_pool_elements - ### + # pool_controllers[ctrl_name]['type'] = ctrl_type + # pool_controllers[ctrl_name]['name'] = ctrl_name + # pool_controllers[ctrl_name]['file'] = ctrl_library + # pool_controllers[ctrl_name]['class'] = ctrl_class + # pool_controllers[ctrl_name]['properties'] = ctrl_properties + # pool_controllers[ctrl_name]['elements'] = ctrl_elements + # pool_controllers[ctrl_name]['ctrl_pool_elements'] = ctrl_pool_elements + ### ### details = pool_controllers[ctrl] ### pool_elements_summary = '('+str(len(details['ctrl_pool_elements']))+')' - ### print '{type}\t{name}\t{file}\t{class}\t{properties}\t{elements}'.format(**details), pool_elements_summary - - + # print + # '{type}\t{name}\t{file}\t{class}\t{properties}\t{elements}'.format(**details), + # pool_elements_summary - - columns = ['Type', 'Pool', 'Name', 'File', 'Class', 'Properties', 'Elements', 'MOT', 'PMOT', 'IOR', 'CT', 'PC', 'ZD'] + columns = ['Type', 'Pool', 'Name', 'File', 'Class', 'Properties', + 'Elements', 'MOT', 'PMOT', 'IOR', 'CT', 'PC', 'ZD'] controllers_sheet = '' row = '\t'.join(columns) controllers_sheet += row + '\n' @@ -217,29 +218,31 @@ def checkPoolElements(pool): row = '\t'.join(columns) instruments_sheet += row + '\n' - columns = ['Type', 'Pool', 'Controller', 'Name', 'DeviceName', 'Axis', 'Instrument', 'Description', 'Attributes'] + columns = ['Type', 'Pool', 'Controller', 'Name', 'DeviceName', + 'Axis', 'Instrument', 'Description', 'Attributes'] motors_sheet = '' row = '\t'.join(columns) motors_sheet += row + '\n' - + ioregs_sheet = '' row = '\t'.join(columns) ioregs_sheet += row + '\n' - + channels_sheet = '' row = '\t'.join(columns) channels_sheet += row + '\n' - + columns = ['Type', 'Pool', 'Name', 'DeviceName', 'Channels', 'Description'] acquisition_sheet = '' row = '\t'.join(columns) acquisition_sheet += row + '\n' - - columns = ['Pool', 'Element', 'Parameter', 'Label', 'Format', 'Min Value', 'Min Alarm', 'Min Warning', 'Max Warning', 'Max Alarm', 'Max Value', 'Unit', 'Polling Period', 'Change Event', 'Description'] + + columns = ['Pool', 'Element', 'Parameter', 'Label', 'Format', 'Min Value', 'Min Alarm', 'Min Warning', + 'Max Warning', 'Max Alarm', 'Max Value', 'Unit', 'Polling Period', 'Change Event', 'Description'] parameters_sheet = '' row = '\t'.join(columns) parameters_sheet += row + '\n' - + for ctrl_type, controllers in pool_controllers_by_type.iteritems(): if len(controllers) == 0: continue @@ -249,20 +252,22 @@ def checkPoolElements(pool): for element_type in ['Motor', 'PseudoMotor', 'IORegister', 'CounterTimer', 'PseudoCounter', 'ZeroDExpChannel']: ctrl_details[element_type] = 0 if ctrl_type == element_type: - ctrl_details[element_type] = len(ctrl_details['ctrl_pool_elements']) + ctrl_details[element_type] = len( + ctrl_details['ctrl_pool_elements']) if len(ctrl_details['properties']) == 0: ctrl_details['properties'] = '' else: properties = [] - for k,v in ctrl_details['properties'].iteritems(): - properties.append(k+':'+v) + for k, v in ctrl_details['properties'].iteritems(): + properties.append(k + ':' + v) ctrl_details['properties'] = ';'.join(properties) if len(ctrl_details['elements']) == 0: ctrl_details['elements'] = '' else: - ctrl_details['elements'] = ctrl_details['elements'].replace(',',';') + ctrl_details['elements'] = ctrl_details[ + 'elements'].replace(',', ';') ctrl_row_template = '{type}\t{pool}\t{name}\t{file}\t{class}\t{properties}\t{elements}\t{Motor}\t{PseudoMotor}\t{IORegister}\t{CounterTimer}\t{PseudoCounter}\t{ZeroDExpChannel}' row = ctrl_row_template.format(**ctrl_details) @@ -271,7 +276,7 @@ def checkPoolElements(pool): for alias in ctrl_details['ctrl_pool_elements']: elem_details = pool_elements_detail[alias] elem_type = elem_details['type'] - attr_dicts = elem_details['attr_dicts'] + attr_dicts = elem_details['attr_dicts'] attribute_values = [] for attr in attr_dicts.keys(): attr_dict = attr_dicts[attr] @@ -283,27 +288,36 @@ def checkPoolElements(pool): # may still contain the __value property for it - from the # previous versions of Sardana (Pool in C++) if attr.lower() not in ('dialposition', 'position'): - attribute_values.append(attr+':'+attr_dict['__value'][0]) + attribute_values.append( + attr + ':' + attr_dict['__value'][0]) elem_params = {} - ['Pool', 'Element', 'Parameter', 'Label', 'Format', 'Min Value', 'Min Alarm', 'Min Warning', 'Max Warning', 'Max Alarm', 'Max Value', 'Unit', 'Polling Period', 'Change Event', 'Description'] + ['Pool', 'Element', 'Parameter', 'Label', 'Format', 'Min Value', 'Min Alarm', 'Min Warning', + 'Max Warning', 'Max Alarm', 'Max Value', 'Unit', 'Polling Period', 'Change Event', 'Description'] elem_params['pool'] = pool elem_params['element'] = alias elem_params['parameter'] = attr - elem_params['label'] = attr_dict.get('label',[''])[0] - elem_params['format'] = attr_dict.get('format',[''])[0] - elem_params['min_value'] = attr_dict.get('min_value',[''])[0] - elem_params['min_alarm'] = attr_dict.get('min_alarm',[''])[0] - elem_params['min_warning'] = attr_dict.get('min_warning',[''])[0] - elem_params['max_warning'] = attr_dict.get('max_warning',[''])[0] - elem_params['max_alarm'] = attr_dict.get('max_alarm',[''])[0] - elem_params['max_value'] = attr_dict.get('max_value',[''])[0] - elem_params['unit'] = attr_dict.get('unit',[''])[0] - elem_params['polling'] = attr_dict.get('event_period',[''])[0] - elem_params['event'] = attr_dict.get('abs_change',[''])[0] - - for k,v in elem_params.iteritems(): - if v != '' and k not in ['pool','element', 'parameter']: + elem_params['label'] = attr_dict.get('label', [''])[0] + elem_params['format'] = attr_dict.get('format', [''])[0] + elem_params['min_value'] = attr_dict.get( + 'min_value', [''])[0] + elem_params['min_alarm'] = attr_dict.get( + 'min_alarm', [''])[0] + elem_params['min_warning'] = attr_dict.get( + 'min_warning', [''])[0] + elem_params['max_warning'] = attr_dict.get( + 'max_warning', [''])[0] + elem_params['max_alarm'] = attr_dict.get( + 'max_alarm', [''])[0] + elem_params['max_value'] = attr_dict.get( + 'max_value', [''])[0] + elem_params['unit'] = attr_dict.get('unit', [''])[0] + elem_params['polling'] = attr_dict.get( + 'event_period', [''])[0] + elem_params['event'] = attr_dict.get('abs_change', [''])[0] + + for k, v in elem_params.iteritems(): + if v != '' and k not in ['pool', 'element', 'parameter']: params_row_template = '{pool}\t{element}\t{parameter}\t{label}\t{format}\t{min_value}\t{min_alarm}\t{min_warning}\t{max_warning}\t{max_alarm}\t{max_value}\t{unit}\t{polling}\t{event}' row = params_row_template.format(**elem_params) parameters_sheet += row + '\n' @@ -340,39 +354,36 @@ def checkPoolElements(pool): row = acq_row_template.format(**mg_details) acquisition_sheet += row + '\n' - print '\n'*2 - print '################################ CONTROLLERS ################################\n'*4 - print '\n'*2 + print '\n' * 2 + print '################################ CONTROLLERS ################################\n' * 4 + print '\n' * 2 print controllers_sheet - print '\n'*2 - print '################################ INSTRUMENTS ################################\n'*4 - print '\n'*2 + print '\n' * 2 + print '################################ INSTRUMENTS ################################\n' * 4 + print '\n' * 2 print instruments_sheet - print '\n'*2 - print '################################ MOTORS ################################\n'*4 - print '\n'*2 + print '\n' * 2 + print '################################ MOTORS ################################\n' * 4 + print '\n' * 2 print motors_sheet - print '\n'*2 - print '################################ IOREGS ################################\n'*4 - print '\n'*2 + print '\n' * 2 + print '################################ IOREGS ################################\n' * 4 + print '\n' * 2 print ioregs_sheet - print '\n'*2 - print '################################ CHANNELS ################################\n'*4 - print '\n'*2 + print '\n' * 2 + print '################################ CHANNELS ################################\n' * 4 + print '\n' * 2 print channels_sheet - print '\n'*2 - print '################################ ACQUISITION ################################\n'*4 - print '\n'*2 + print '\n' * 2 + print '################################ ACQUISITION ################################\n' * 4 + print '\n' * 2 print acquisition_sheet - print '\n'*2 - print '################################ PARAMETERS ################################\n'*4 - print '\n'*2 + print '\n' * 2 + print '################################ PARAMETERS ################################\n' * 4 + print '\n' * 2 print parameters_sheet - - - if __name__ == '__main__': if len(sys.argv) != 2 or sys.argv[1] == '?': print '----------------------------------------' @@ -384,6 +395,5 @@ def checkPoolElements(pool): print ' where pool is the device name of the pool' print '----------------------------------------' - pool = sys.argv[1] checkPoolElements(pool) diff --git a/src/sardana/tools/config/pexpect23.py b/src/sardana/tools/config/pexpect23.py index 67c6389faa..6f7349670e 100644 --- a/src/sardana/tools/config/pexpect23.py +++ b/src/sardana/tools/config/pexpect23.py @@ -64,7 +64,9 @@ """ try: - import os, sys, time + import os + import sys + import time import select import string import re @@ -87,9 +89,11 @@ __version__ = '2.3' __revision__ = '$Revision: 399 $' __all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'run', 'which', - 'split_command_line', '__version__', '__revision__'] + 'split_command_line', '__version__', '__revision__'] # Exception classes used by this module. + + class ExceptionPexpect(Exception): """Base class for all exceptions raised by this module. @@ -104,7 +108,6 @@ def __str__(self): return str(self.value) def get_trace(self): - """This returns an abbreviated stack trace with lines that only concern the caller. In other words, the stack trace inside the Pexpect module is not included. """ @@ -116,7 +119,6 @@ def get_trace(self): return ''.join(tblist) def __filter_not_pexpect(self, trace_list_item): - """This returns True if list item 0 the string 'pexpect.py' in it. """ if trace_list_item[0].find('pexpect.py') == -1: @@ -124,25 +126,27 @@ def __filter_not_pexpect(self, trace_list_item): else: return False + class EOF(ExceptionPexpect): """Raised when EOF is read from a child. This usually means the child has exited.""" + class TIMEOUT(ExceptionPexpect): """Raised when a read time exceeds the timeout. """ -##class TIMEOUT_PATTERN(TIMEOUT): -## """Raised when the pattern match time exceeds the timeout. -## This is different than a read TIMEOUT because the child process may -## give output, thus never give a TIMEOUT, but the output -## may never match a pattern. -## """ -##class MAXBUFFER(ExceptionPexpect): +# class TIMEOUT_PATTERN(TIMEOUT): +# """Raised when the pattern match time exceeds the timeout. +# This is different than a read TIMEOUT because the child process may +# give output, thus never give a TIMEOUT, but the output +# may never match a pattern. +# """ +# class MAXBUFFER(ExceptionPexpect): ## """Raised when a scan buffer fills before matching an expected pattern.""" -def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None, cwd=None, env=None): +def run(command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None, cwd=None, env=None): """ This function runs the given command; waits for it to finish; then returns all output as a string. STDERR is included in output. If the full @@ -218,21 +222,22 @@ def print_ticks(d): if timeout == -1: child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env) else: - child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile, cwd=cwd, env=env) + child = spawn(command, timeout=timeout, maxread=2000, + logfile=logfile, cwd=cwd, env=env) if events is not None: patterns = events.keys() responses = events.values() else: - patterns=None # We assume that EOF or TIMEOUT will save us. - responses=None + patterns = None # We assume that EOF or TIMEOUT will save us. + responses = None child_result_list = [] event_count = 0 while 1: try: - index = child.expect (patterns) + index = child.expect(patterns) if type(child.after) in types.StringTypes: child_result_list.append(child.before + child.after) - else: # child.after may have been a TIMEOUT or EOF, so don't cat those. + else: # child.after may have been a TIMEOUT or EOF, so don't cat those. child_result_list.append(child.before) if type(responses[index]) in types.StringTypes: child.send(responses[index]) @@ -244,7 +249,8 @@ def print_ticks(d): elif callback_result: break else: - raise TypeError ('The callback must be a string or function type.') + raise TypeError( + 'The callback must be a string or function type.') event_count = event_count + 1 except TIMEOUT, e: child_result_list.append(child.before) @@ -259,13 +265,13 @@ def print_ticks(d): else: return child_result + class spawn (object): """This is the main class interface for Pexpect. Use this class to start and control child applications. """ def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None): - """This is the constructor. The command parameter may be a string that includes a command and any arguments to the command. For example:: @@ -336,12 +342,12 @@ def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize= the input from the child and output sent to the child. Sometimes you don't want to see everything you write to the child. You only want to log what the child sends back. For example:: - + child = pexpect.spawn('some_command') child.logfile_read = sys.stdout To separately log output sent to the child use logfile_send:: - + self.logfile_send = fout The delaybeforesend helps overcome a weird behavior that many users @@ -390,46 +396,55 @@ def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize= self.terminated = True self.exitstatus = None self.signalstatus = None - self.status = None # status returned by os.waitpid + self.status = None # status returned by os.waitpid self.flag_eof = False self.pid = None - self.child_fd = -1 # initially closed + self.child_fd = -1 # initially closed self.timeout = timeout self.delimiter = EOF self.logfile = logfile - self.logfile_read = None # input from child (read_nonblocking) - self.logfile_send = None # output to send (send, sendline) - self.maxread = maxread # max bytes to read at one time into buffer - self.buffer = '' # This is the read buffer. See maxread. - self.searchwindowsize = searchwindowsize # Anything before searchwindowsize point is preserved, but not searched. - # Most Linux machines don't like delaybeforesend to be below 0.03 (30 ms). - self.delaybeforesend = 0.05 # Sets sleep time used just before sending data to child. Time in seconds. - self.delayafterclose = 0.1 # Sets delay in close() method to allow kernel time to update process status. Time in seconds. - self.delayafterterminate = 0.1 # Sets delay in terminate() method to allow kernel time to update process status. Time in seconds. - self.softspace = False # File-like object. - self.name = '<' + repr(self) + '>' # File-like object. - self.encoding = None # File-like object. - self.closed = True # File-like object. + self.logfile_read = None # input from child (read_nonblocking) + self.logfile_send = None # output to send (send, sendline) + self.maxread = maxread # max bytes to read at one time into buffer + self.buffer = '' # This is the read buffer. See maxread. + # Anything before searchwindowsize point is preserved, but not + # searched. + self.searchwindowsize = searchwindowsize + # Most Linux machines don't like delaybeforesend to be below 0.03 (30 + # ms). + # Sets sleep time used just before sending data to child. Time in + # seconds. + self.delaybeforesend = 0.05 + # Sets delay in close() method to allow kernel time to update process + # status. Time in seconds. + self.delayafterclose = 0.1 + # Sets delay in terminate() method to allow kernel time to update + # process status. Time in seconds. + self.delayafterterminate = 0.1 + self.softspace = False # File-like object. + self.name = '<' + repr(self) + '>' # File-like object. + self.encoding = None # File-like object. + self.closed = True # File-like object. self.cwd = cwd self.env = env - self.__irix_hack = (sys.platform.lower().find('irix')>=0) # This flags if we are running on irix + # This flags if we are running on irix + self.__irix_hack = (sys.platform.lower().find('irix') >= 0) # Solaris uses internal __fork_pty(). All others use pty.fork(). - if (sys.platform.lower().find('solaris')>=0) or (sys.platform.lower().find('sunos5')>=0): + if (sys.platform.lower().find('solaris') >= 0) or (sys.platform.lower().find('sunos5') >= 0): self.use_native_pty_fork = False else: self.use_native_pty_fork = True - - # allow dummy instances for subclasses that may not use command or args. + # allow dummy instances for subclasses that may not use command or + # args. if command is None: self.command = None self.args = None self.name = '' else: - self._spawn (command, args) + self._spawn(command, args) def __del__(self): - """This makes sure that no system resources are left open. Python only garbage collects Python objects. OS file descriptors are not Python objects, so they must be handled explicitly. If the child file @@ -447,7 +462,6 @@ def __del__(self): pass def __str__(self): - """This returns a human-readable string that represents the state of the object. """ @@ -480,8 +494,7 @@ def __str__(self): s.append('delayafterterminate: ' + str(self.delayafterterminate)) return '\n'.join(s) - def _spawn(self,command,args=[]): - + def _spawn(self, command, args=[]): """This starts the given command in a child process. This does all the fork/exec type of stuff for a pty. This is called by __init__. If args is empty then command will be parsed (split on spaces) and args will be @@ -498,26 +511,28 @@ def _spawn(self,command,args=[]): # If command is an int type then it may represent a file descriptor. if type(command) == type(0): - raise ExceptionPexpect ('Command is an int type. If this is a file descriptor then maybe you want to use fdpexpect.fdspawn which takes an existing file descriptor instead of a command string.') + raise ExceptionPexpect( + 'Command is an int type. If this is a file descriptor then maybe you want to use fdpexpect.fdspawn which takes an existing file descriptor instead of a command string.') - if type (args) != type([]): - raise TypeError ('The argument, args, must be a list.') + if type(args) != type([]): + raise TypeError('The argument, args, must be a list.') if args == []: self.args = split_command_line(command) self.command = self.args[0] else: - self.args = args[:] # work with a copy - self.args.insert (0, command) + self.args = args[:] # work with a copy + self.args.insert(0, command) self.command = command command_with_path = which(self.command) if command_with_path is None: - raise ExceptionPexpect ('The command was not found or was not executable: %s.' % self.command) + raise ExceptionPexpect( + 'The command was not found or was not executable: %s.' % self.command) self.command = command_with_path self.args[0] = self.command - self.name = '<' + ' '.join (self.args) + '>' + self.name = '<' + ' '.join(self.args) + '>' assert self.pid is None, 'The pid member should be None.' assert self.command is not None, 'The command member should not be None.' @@ -527,12 +542,12 @@ def _spawn(self,command,args=[]): self.pid, self.child_fd = pty.fork() except OSError, e: raise ExceptionPexpect('Error! pty.fork() failed: ' + str(e)) - else: # Use internal __fork_pty + else: # Use internal __fork_pty self.pid, self.child_fd = self.__fork_pty() - if self.pid == 0: # Child + if self.pid == 0: # Child try: - self.child_fd = sys.stdout.fileno() # used by setwinsize() + self.child_fd = sys.stdout.fileno() # used by setwinsize() self.setwinsize(24, 80) except: # Some platforms do not like setwinsize (Cygwin). @@ -542,9 +557,9 @@ def _spawn(self,command,args=[]): pass # Do not allow child to inherit open file descriptors from parent. max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0] - for i in range (3, max_fd): + for i in range(3, max_fd): try: - os.close (i) + os.close(i) except OSError: pass @@ -565,7 +580,6 @@ def _spawn(self,command,args=[]): self.closed = False def __fork_pty(self): - """This implements a substitute for the forkpty system call. This should be more portable than the pty.fork() function. Specifically, this should work on Solaris. @@ -604,7 +618,6 @@ def __fork_pty(self): return pid, parent_fd def __pty_make_controlling_tty(self, tty_fd): - """This makes the pseudo-terminal the controlling tty. This should be more portable than the pty.fork() function. Specifically, this should work on Solaris. """ @@ -612,7 +625,7 @@ def __pty_make_controlling_tty(self, tty_fd): child_name = os.ttyname(tty_fd) # Disconnect from controlling tty if still connected. - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY); + fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) if fd >= 0: os.close(fd) @@ -620,7 +633,7 @@ def __pty_make_controlling_tty(self, tty_fd): # Verify we are disconnected from controlling tty try: - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY); + fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) if fd >= 0: os.close(fd) raise ExceptionPexpect, "Error! We are not disconnected from a controlling tty." @@ -629,7 +642,7 @@ def __pty_make_controlling_tty(self, tty_fd): pass # Verify we can open child pty. - fd = os.open(child_name, os.O_RDWR); + fd = os.open(child_name, os.O_RDWR) if fd < 0: raise ExceptionPexpect, "Error! Could not open child pty, " + child_name else: @@ -642,15 +655,13 @@ def __pty_make_controlling_tty(self, tty_fd): else: os.close(fd) - def fileno (self): # File-like object. - + def fileno(self): # File-like object. """This returns the file descriptor of the pty for the child. """ return self.child_fd - def close (self, force=True): # File-like object. - + def close(self, force=True): # File-like object. """This closes the connection with the child application. Note that calling close() more than once is valid. This emulates standard Python behavior with files. Set force to True if you want to make sure that @@ -659,31 +670,30 @@ def close (self, force=True): # File-like object. if not self.closed: self.flush() - os.close (self.child_fd) - time.sleep(self.delayafterclose) # Give kernel time to update process status. + os.close(self.child_fd) + # Give kernel time to update process status. + time.sleep(self.delayafterclose) if self.isalive(): if not self.terminate(force): - raise ExceptionPexpect ('close() could not terminate the child using terminate()') + raise ExceptionPexpect( + 'close() could not terminate the child using terminate()') self.child_fd = -1 self.closed = True #self.pid = None - def flush (self): # File-like object. - + def flush(self): # File-like object. """This does nothing. It is here to support the interface for a File-like object. """ pass - def isatty (self): # File-like object. - + def isatty(self): # File-like object. """This returns True if the file descriptor is open and connected to a tty(-like) device, else False. """ return os.isatty(self.child_fd) - def waitnoecho (self, timeout=-1): - + def waitnoecho(self, timeout=-1): """This waits until the terminal ECHO flag is set False. This returns True if the echo mode is off. This returns False if the ECHO flag was not set False before the timeout. This can be used to detect when the @@ -704,7 +714,7 @@ def waitnoecho (self, timeout=-1): if timeout == -1: timeout = self.timeout if timeout is not None: - end_time = time.time() + timeout + end_time = time.time() + timeout while True: if not self.getecho(): return True @@ -714,8 +724,7 @@ def waitnoecho (self, timeout=-1): timeout = end_time - time.time() time.sleep(0.1) - def getecho (self): - + def getecho(self): """This returns the terminal echo mode. This returns True if echo is on or False if echo is off. Child applications that are expecting you to enter a password often set ECHO False. See waitnoecho(). """ @@ -725,8 +734,7 @@ def getecho (self): return True return False - def setecho (self, state): - + def setecho(self, state): """This sets the terminal echo mode on or off. Note that anything the child sent before the echo will be lost, so you should be sure that your input buffer is empty before you call setecho(). For example, the @@ -763,11 +771,11 @@ def setecho (self, state): else: attr[3] = attr[3] & ~termios.ECHO # I tried TCSADRAIN and TCSAFLUSH, but these were inconsistent - # and blocked on some platforms. TCSADRAIN is probably ideal if it worked. + # and blocked on some platforms. TCSADRAIN is probably ideal if it + # worked. termios.tcsetattr(self.child_fd, termios.TCSANOW, attr) - def read_nonblocking (self, size = 1, timeout = -1): - + def read_nonblocking(self, size=1, timeout=-1): """This reads at most size characters from the child application. It includes a timeout. If the read does not complete within the timeout period then a TIMEOUT exception is raised. If the end of file is read @@ -789,7 +797,8 @@ def read_nonblocking (self, size = 1, timeout = -1): implement the timeout. """ if self.closed: - raise ValueError ('I/O operation on closed file in read_nonblocking().') + raise ValueError( + 'I/O operation on closed file in read_nonblocking().') if timeout == -1: timeout = self.timeout @@ -800,52 +809,60 @@ def read_nonblocking (self, size = 1, timeout = -1): # For this case, I test isalive() before doing any reading. # If isalive() is false, then I pretend that this is the same as EOF. if not self.isalive(): - r,w,e = self.__select([self.child_fd], [], [], 0) # timeout of 0 means "poll" + # timeout of 0 means "poll" + r, w, e = self.__select([self.child_fd], [], [], 0) if not r: self.flag_eof = True - raise EOF ('End Of File (EOF) in read_nonblocking(). Braindead platform.') + raise EOF( + 'End Of File (EOF) in read_nonblocking(). Braindead platform.') elif self.__irix_hack: # This is a hack for Irix. It seems that Irix requires a long delay before checking isalive. - # This adds a 2 second delay, but only when the child is terminated. + # This adds a 2 second delay, but only when the child is + # terminated. r, w, e = self.__select([self.child_fd], [], [], 2) if not r and not self.isalive(): self.flag_eof = True - raise EOF ('End Of File (EOF) in read_nonblocking(). Pokey platform.') + raise EOF( + 'End Of File (EOF) in read_nonblocking(). Pokey platform.') - r,w,e = self.__select([self.child_fd], [], [], timeout) + r, w, e = self.__select([self.child_fd], [], [], timeout) if not r: if not self.isalive(): # Some platforms, such as Irix, will claim that their processes are alive; - # then timeout on the select; and then finally admit that they are not alive. + # then timeout on the select; and then finally admit that they + # are not alive. self.flag_eof = True - raise EOF ('End of File (EOF) in read_nonblocking(). Very pokey platform.') + raise EOF( + 'End of File (EOF) in read_nonblocking(). Very pokey platform.') else: - raise TIMEOUT ('Timeout exceeded in read_nonblocking().') + raise TIMEOUT('Timeout exceeded in read_nonblocking().') if self.child_fd in r: try: s = os.read(self.child_fd, size) - except OSError, e: # Linux does this + except OSError, e: # Linux does this self.flag_eof = True - raise EOF ('End Of File (EOF) in read_nonblocking(). Exception style platform.') - if s == '': # BSD style + raise EOF( + 'End Of File (EOF) in read_nonblocking(). Exception style platform.') + if s == '': # BSD style self.flag_eof = True - raise EOF ('End Of File (EOF) in read_nonblocking(). Empty string style platform.') + raise EOF( + 'End Of File (EOF) in read_nonblocking(). Empty string style platform.') if self.logfile is not None: - self.logfile.write (s) + self.logfile.write(s) self.logfile.flush() if self.logfile_read is not None: - self.logfile_read.write (s) + self.logfile_read.write(s) self.logfile_read.flush() return s - raise ExceptionPexpect ('Reached an unexpected state in read_nonblocking().') - - def read (self, size = -1): # File-like object. + raise ExceptionPexpect( + 'Reached an unexpected state in read_nonblocking().') + def read(self, size=-1): # File-like object. """This reads at most "size" bytes from the file (less if the read hits EOF before obtaining size bytes). If the size argument is negative or omitted, read all data until EOF is reached. The bytes are returned as @@ -855,7 +872,7 @@ def read (self, size = -1): # File-like object. if size == 0: return '' if size < 0: - self.expect (self.delimiter) # delimiter default is EOF + self.expect(self.delimiter) # delimiter default is EOF return self.before # I could have done this more directly by not using expect(), but @@ -866,13 +883,12 @@ def read (self, size = -1): # File-like object. # Note, it's OK if size==-1 in the regex. That just means it # will never match anything in which case we stop only on EOF. cre = re.compile('.{%d}' % size, re.DOTALL) - index = self.expect ([cre, self.delimiter]) # delimiter default is EOF + index = self.expect([cre, self.delimiter]) # delimiter default is EOF if index == 0: - return self.after ### self.before should be ''. Should I assert this? + return self.after # self.before should be ''. Should I assert this? return self.before - def readline (self, size = -1): # File-like object. - + def readline(self, size=-1): # File-like object. """This reads and returns one entire line. A trailing newline is kept in the string, but may be absent when a file ends with an incomplete line. Note: This readline() looks for a \\r\\n pair even on UNIX @@ -884,21 +900,20 @@ def readline (self, size = -1): # File-like object. if size == 0: return '' - index = self.expect (['\r\n', self.delimiter]) # delimiter default is EOF + # delimiter default is EOF + index = self.expect(['\r\n', self.delimiter]) if index == 0: return self.before + '\r\n' else: return self.before - def __iter__ (self): # File-like object. - + def __iter__(self): # File-like object. """This is to support iterators over a file-like object. """ return self - def next (self): # File-like object. - + def next(self): # File-like object. """This is to support iterators over a file-like object. """ @@ -907,8 +922,7 @@ def next (self): # File-like object. raise StopIteration return result - def readlines (self, sizehint = -1): # File-like object. - + def readlines(self, sizehint=-1): # File-like object. """This reads until EOF using readline() and returns a list containing the lines thus read. The optional "sizehint" argument is ignored. """ @@ -921,49 +935,44 @@ def readlines (self, sizehint = -1): # File-like object. return lines def write(self, s): # File-like object. - """This is similar to send() except that there is no return value. """ - self.send (s) - - def writelines (self, sequence): # File-like object. + self.send(s) + def writelines(self, sequence): # File-like object. """This calls write() for each element in the sequence. The sequence can be any iterable object producing strings, typically a list of strings. This does not add line separators There is no return value. """ for s in sequence: - self.write (s) + self.write(s) def send(self, s): - """This sends a string to the child process. This returns the number of bytes written. If a log file was set then the data is also written to the log. """ time.sleep(self.delaybeforesend) if self.logfile is not None: - self.logfile.write (s) + self.logfile.write(s) self.logfile.flush() if self.logfile_send is not None: - self.logfile_send.write (s) + self.logfile_send.write(s) self.logfile_send.flush() c = os.write(self.child_fd, s) return c def sendline(self, s=''): - """This is like send(), but it adds a line feed (os.linesep). This returns the number of bytes written. """ n = self.send(s) - n = n + self.send (os.linesep) + n = n + self.send(os.linesep) return n def sendcontrol(self, char): - """This sends a control character to the child such as Ctrl-C or Ctrl-D. For example, to send a Ctrl-G (ASCII 7):: @@ -974,22 +983,21 @@ def sendcontrol(self, char): char = char.lower() a = ord(char) - if a>=97 and a<=122: + if a >= 97 and a <= 122: a = a - ord('a') + 1 - return self.send (chr(a)) - d = {'@':0, '`':0, - '[':27, '{':27, - '\\':28, '|':28, - ']':29, '}': 29, - '^':30, '~':30, - '_':31, - '?':127} + return self.send(chr(a)) + d = {'@': 0, '`': 0, + '[': 27, '{': 27, + '\\': 28, '|': 28, + ']': 29, '}': 29, + '^': 30, '~': 30, + '_': 31, + '?': 127} if char not in d: return 0 - return self.send (chr(d[char])) + return self.send(chr(d[char])) def sendeof(self): - """This sends an EOF to the child. This sends a character which causes the pending parent output buffer to be sent to the waiting child program without waiting for end-of-line. If it is the first character @@ -999,21 +1007,21 @@ def sendeof(self): It is the responsibility of the caller to ensure the eof is sent at the beginning of a line. """ - ### Hmmm... how do I send an EOF? - ###C if ((m = write(pty, *buf, p - *buf)) < 0) - ###C return (errno == EWOULDBLOCK) ? n : -1; + # Hmmm... how do I send an EOF? + # C if ((m = write(pty, *buf, p - *buf)) < 0) + # C return (errno == EWOULDBLOCK) ? n : -1; #fd = sys.stdin.fileno() - #old = termios.tcgetattr(fd) # remember current state + # old = termios.tcgetattr(fd) # remember current state #attr = termios.tcgetattr(fd) - #attr[3] = attr[3] | termios.ICANON # ICANON must be set to recognize EOF - #try: # use try/finally to ensure state gets restored + # attr[3] = attr[3] | termios.ICANON # ICANON must be set to recognize EOF + # try: # use try/finally to ensure state gets restored # termios.tcsetattr(fd, termios.TCSADRAIN, attr) # if hasattr(termios, 'CEOF'): # os.write (self.child_fd, '%c' % termios.CEOF) # else: # # Silly platform does not define CEOF so assume CTRL-D # os.write (self.child_fd, '%c' % 4) - #finally: # restore state + # finally: # restore state # termios.tcsetattr(fd, termios.TCSADRAIN, old) if hasattr(termios, 'VEOF'): char = termios.tcgetattr(self.child_fd)[6][termios.VEOF] @@ -1023,7 +1031,6 @@ def sendeof(self): self.send(char) def sendintr(self): - """This sends a SIGINT to the child. It does not require the SIGINT to be the first character on a line. """ @@ -1032,17 +1039,15 @@ def sendintr(self): else: # platform does not define VINTR so assume CTRL-C char = chr(3) - self.send (char) - - def eof (self): + self.send(char) + def eof(self): """This returns True if the EOF exception was ever raised. """ return self.flag_eof def terminate(self, force=False): - """This forces a child process to terminate. It starts nicely with SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This returns True if the child was terminated. This returns False if the @@ -1083,7 +1088,6 @@ def terminate(self, force=False): return False def wait(self): - """This waits until the child exits. This is a blocking call. This will not read any data from the child, so this will block forever if the child has unread output and has terminated. In other words, the child @@ -1093,24 +1097,24 @@ def wait(self): if self.isalive(): pid, status = os.waitpid(self.pid, 0) else: - raise ExceptionPexpect ('Cannot wait for dead child process.') + raise ExceptionPexpect('Cannot wait for dead child process.') self.exitstatus = os.WEXITSTATUS(status) - if os.WIFEXITED (status): + if os.WIFEXITED(status): self.status = status self.exitstatus = os.WEXITSTATUS(status) self.signalstatus = None self.terminated = True - elif os.WIFSIGNALED (status): + elif os.WIFSIGNALED(status): self.status = status self.exitstatus = None self.signalstatus = os.WTERMSIG(status) self.terminated = True - elif os.WIFSTOPPED (status): - raise ExceptionPexpect ('Wait was called for a child process that is stopped. This is not supported. Is some other process attempting job control with our child pid?') + elif os.WIFSTOPPED(status): + raise ExceptionPexpect( + 'Wait was called for a child process that is stopped. This is not supported. Is some other process attempting job control with our child pid?') return self.exitstatus def isalive(self): - """This tests if the child process is running or not. This is non-blocking. If the child was terminated then this will read the exitstatus or signalstatus of the child. This returns True if the child @@ -1130,9 +1134,10 @@ def isalive(self): try: pid, status = os.waitpid(self.pid, waitpid_options) - except OSError, e: # No child processes + except OSError, e: # No child processes if e[0] == errno.ECHILD: - raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?') + raise ExceptionPexpect( + 'isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?') else: raise e @@ -1141,39 +1146,42 @@ def isalive(self): # report, and the value of status is undefined. if pid == 0: try: - pid, status = os.waitpid(self.pid, waitpid_options) ### os.WNOHANG) # Solaris! - except OSError, e: # This should never happen... + # os.WNOHANG) # Solaris! + pid, status = os.waitpid(self.pid, waitpid_options) + except OSError, e: # This should never happen... if e[0] == errno.ECHILD: - raise ExceptionPexpect ('isalive() encountered condition that should never happen. There was no child process. Did someone else call waitpid() on our process?') + raise ExceptionPexpect( + 'isalive() encountered condition that should never happen. There was no child process. Did someone else call waitpid() on our process?') else: raise e # If pid is still 0 after two calls to waitpid() then # the process really is alive. This seems to work on all platforms, except # for Irix which seems to require a blocking call on waitpid or select, so I let read_nonblocking - # take care of this situation (unfortunately, this requires waiting through the timeout). + # take care of this situation (unfortunately, this requires waiting + # through the timeout). if pid == 0: return True if pid == 0: return True - if os.WIFEXITED (status): + if os.WIFEXITED(status): self.status = status self.exitstatus = os.WEXITSTATUS(status) self.signalstatus = None self.terminated = True - elif os.WIFSIGNALED (status): + elif os.WIFSIGNALED(status): self.status = status self.exitstatus = None self.signalstatus = os.WTERMSIG(status) self.terminated = True - elif os.WIFSTOPPED (status): - raise ExceptionPexpect ('isalive() encountered condition where child process is stopped. This is not supported. Is some other process attempting job control with our child pid?') + elif os.WIFSTOPPED(status): + raise ExceptionPexpect( + 'isalive() encountered condition where child process is stopped. This is not supported. Is some other process attempting job control with our child pid?') return False def kill(self, sig): - """This sends the given signal to the child application. In keeping with UNIX tradition it has a misleading name. It does not necessarily kill the child unless you send the right signal. """ @@ -1183,7 +1191,6 @@ def kill(self, sig): os.kill(self.pid, sig) def compile_pattern_list(self, patterns): - """This compiles a pattern-string or a list of pattern-strings. Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of those. Patterns may also be None which results in an empty list (you @@ -1212,7 +1219,7 @@ def compile_pattern_list(self, patterns): if type(patterns) is not types.ListType: patterns = [patterns] - compile_flags = re.DOTALL # Allow dot to match \n + compile_flags = re.DOTALL # Allow dot to match \n if self.ignorecase: compile_flags = compile_flags | re.IGNORECASE compiled_pattern_list = [] @@ -1226,12 +1233,12 @@ def compile_pattern_list(self, patterns): elif type(p) is type(re.compile('')): compiled_pattern_list.append(p) else: - raise TypeError ('Argument must be one of StringTypes, EOF, TIMEOUT, SRE_Pattern, or a list of those type. %s' % str(type(p))) + raise TypeError( + 'Argument must be one of StringTypes, EOF, TIMEOUT, SRE_Pattern, or a list of those type. %s' % str(type(p))) return compiled_pattern_list - def expect(self, pattern, timeout = -1, searchwindowsize=None): - + def expect(self, pattern, timeout=-1, searchwindowsize=None): """This seeks through the stream until a pattern is matched. The pattern is overloaded and may take several types. The pattern can be a StringType, EOF, a compiled re, or a list of any of those types. @@ -1310,8 +1317,7 @@ def expect(self, pattern, timeout = -1, searchwindowsize=None): compiled_pattern_list = self.compile_pattern_list(pattern) return self.expect_list(compiled_pattern_list, timeout, searchwindowsize) - def expect_list(self, pattern_list, timeout = -1, searchwindowsize = -1): - + def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1): """This takes a list of compiled regular expressions and returns the index into the pattern_list that matched the child output. The list may also contain EOF or TIMEOUT (which are not compiled regular @@ -1324,8 +1330,7 @@ def expect_list(self, pattern_list, timeout = -1, searchwindowsize = -1): return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize) - def expect_exact(self, pattern_list, timeout = -1, searchwindowsize = -1): - + def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1): """This is similar to expect(), but uses plain string matching instead of compiled regular expressions in 'pattern_list'. The 'pattern_list' may be a string; a list or other sequence of strings; or TIMEOUT and @@ -1342,8 +1347,7 @@ def expect_exact(self, pattern_list, timeout = -1, searchwindowsize = -1): pattern_list = [pattern_list] return self.expect_loop(searcher_string(pattern_list), timeout, searchwindowsize) - def expect_loop(self, searcher, timeout = -1, searchwindowsize = -1): - + def expect_loop(self, searcher, timeout=-1, searchwindowsize=-1): """This is the common loop used inside expect. The 'searcher' should be an instance of searcher_re or searcher_string, which describes how and what to search for in the input. @@ -1355,29 +1359,29 @@ def expect_loop(self, searcher, timeout = -1, searchwindowsize = -1): if timeout == -1: timeout = self.timeout if timeout is not None: - end_time = time.time() + timeout + end_time = time.time() + timeout if searchwindowsize == -1: searchwindowsize = self.searchwindowsize try: incoming = self.buffer freshlen = len(incoming) - while True: # Keep reading until exception or return. + while True: # Keep reading until exception or return. index = searcher.search(incoming, freshlen, searchwindowsize) if index >= 0: - self.buffer = incoming[searcher.end : ] - self.before = incoming[ : searcher.start] - self.after = incoming[searcher.start : searcher.end] + self.buffer = incoming[searcher.end:] + self.before = incoming[: searcher.start] + self.after = incoming[searcher.start: searcher.end] self.match = searcher.match self.match_index = index return self.match_index # No match at this point if timeout < 0 and timeout is not None: - raise TIMEOUT ('Timeout exceeded in expect_any().') + raise TIMEOUT('Timeout exceeded in expect_any().') # Still have time left, so read more data - c = self.read_nonblocking (self.maxread, timeout) + c = self.read_nonblocking(self.maxread, timeout) freshlen = len(c) - time.sleep (0.0001) + time.sleep(0.0001) incoming = incoming + c if timeout is not None: timeout = end_time - time.time() @@ -1393,7 +1397,7 @@ def expect_loop(self, searcher, timeout = -1, searchwindowsize = -1): else: self.match = None self.match_index = None - raise EOF (str(e) + '\n' + str(self)) + raise EOF(str(e) + '\n' + str(self)) except TIMEOUT, e: self.buffer = incoming self.before = incoming @@ -1406,7 +1410,7 @@ def expect_loop(self, searcher, timeout = -1, searchwindowsize = -1): else: self.match = None self.match_index = None - raise TIMEOUT (str(e) + '\n' + str(self)) + raise TIMEOUT(str(e) + '\n' + str(self)) except: self.before = incoming self.after = None @@ -1415,7 +1419,6 @@ def expect_loop(self, searcher, timeout = -1, searchwindowsize = -1): raise def getwinsize(self): - """This returns the terminal window size of the child tty. The return value is a tuple of (rows, cols). """ @@ -1425,7 +1428,6 @@ def getwinsize(self): return struct.unpack('HHHH', x)[0:2] def setwinsize(self, r, c): - """This sets the terminal window size of the child tty. This will cause a SIGWINCH signal to be sent to the child. This does not change the physical window size. It changes the size reported to TTY-aware @@ -1441,14 +1443,13 @@ def setwinsize(self, r, c): # Newer versions of Linux have totally different values for TIOCSWINSZ. # Note that this fix is a hack. TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) - if TIOCSWINSZ == 2148037735L: # L is not required in Python >= 2.2. - TIOCSWINSZ = -2146929561 # Same bits, but with sign. + if TIOCSWINSZ == 2148037735L: # L is not required in Python >= 2.2. + TIOCSWINSZ = -2146929561 # Same bits, but with sign. # Note, assume ws_xpixel and ws_ypixel are zero. s = struct.pack('HHHH', r, c, 0, 0) fcntl.ioctl(self.fileno(), TIOCSWINSZ, s) - def interact(self, escape_character = chr(29), input_filter = None, output_filter = None): - + def interact(self, escape_character=chr(29), input_filter=None, output_filter=None): """This gives control of the child process to the interactive user (the human at the keyboard). Keystrokes are sent to the child process, and the stdout and stderr output of the child process is printed. This @@ -1483,7 +1484,7 @@ def sigwinch_passthrough (sig, data): """ # Flush the buffer. - self.stdout.write (self.buffer) + self.stdout.write(self.buffer) self.stdout.flush() self.buffer = '' mode = tty.tcgetattr(self.STDIN_FILENO) @@ -1494,7 +1495,6 @@ def sigwinch_passthrough (sig, data): tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode) def __interact_writen(self, fd, data): - """This is used by the interact() method. """ @@ -1503,29 +1503,29 @@ def __interact_writen(self, fd, data): data = data[n:] def __interact_read(self, fd): - """This is used by the interact() method. """ return os.read(fd, 1000) - def __interact_copy(self, escape_character = None, input_filter = None, output_filter = None): - + def __interact_copy(self, escape_character=None, input_filter=None, output_filter=None): """This is used by the interact() method. """ while self.isalive(): - r,w,e = self.__select([self.child_fd, self.STDIN_FILENO], [], []) + r, w, e = self.__select([self.child_fd, self.STDIN_FILENO], [], []) if self.child_fd in r: data = self.__interact_read(self.child_fd) - if output_filter: data = output_filter(data) + if output_filter: + data = output_filter(data) if self.logfile is not None: - self.logfile.write (data) + self.logfile.write(data) self.logfile.flush() os.write(self.STDOUT_FILENO, data) if self.STDIN_FILENO in r: data = self.__interact_read(self.STDIN_FILENO) - if input_filter: data = input_filter(data) + if input_filter: + data = input_filter(data) i = data.rfind(escape_character) if i != -1: data = data[:i] @@ -1533,8 +1533,7 @@ def __interact_copy(self, escape_character = None, input_filter = None, output_f break self.__interact_writen(self.child_fd, data) - def __select (self, iwtd, owtd, ewtd, timeout=None): - + def __select(self, iwtd, owtd, ewtd, timeout=None): """This is a wrapper around select.select() that ignores signals. If select.select raises a select.error exception and errno is an EINTR error then it is ignored. Mainly this is used to ignore sigwinch @@ -1546,38 +1545,40 @@ def __select (self, iwtd, owtd, ewtd, timeout=None): end_time = time.time() + timeout while True: try: - return select.select (iwtd, owtd, ewtd, timeout) + return select.select(iwtd, owtd, ewtd, timeout) except select.error, e: if e[0] == errno.EINTR: - # if we loop back we have to subtract the amount of time we already waited. + # if we loop back we have to subtract the amount of time we + # already waited. if timeout is not None: timeout = end_time - time.time() if timeout < 0: - return ([],[],[]) - else: # something else caused the select.error, so this really is an exception + return ([], [], []) + else: # something else caused the select.error, so this really is an exception raise ############################################################################## # The following methods are no longer supported or allowed. - def setmaxread (self, maxread): - + def setmaxread(self, maxread): """This method is no longer supported or allowed. I don't like getters and setters without a good reason. """ - raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the maxread member variable.') - - def setlog (self, fileobject): + raise ExceptionPexpect( + 'This method is no longer supported or allowed. Just assign a value to the maxread member variable.') + def setlog(self, fileobject): """This method is no longer supported or allowed. """ - raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the logfile member variable.') + raise ExceptionPexpect( + 'This method is no longer supported or allowed. Just assign a value to the logfile member variable.') ############################################################################## # End of spawn class ############################################################################## + class searcher_string (object): """This is a plain string search helper for the spawn.expect_any() method. @@ -1596,7 +1597,6 @@ class searcher_string (object): """ def __init__(self, strings): - """This creates an instance of searcher_string. This argument 'strings' may be a list; a sequence of strings; or the EOF or TIMEOUT types. """ @@ -1613,22 +1613,21 @@ def __init__(self, strings): self._strings.append((n, s)) def __str__(self): - """This returns a human-readable string that represents the state of the object.""" - ss = [ (ns[0],' %d: "%s"' % ns) for ns in self._strings ] - ss.append((-1,'searcher_string:')) + ss = [(ns[0], ' %d: "%s"' % ns) for ns in self._strings] + ss.append((-1, 'searcher_string:')) if self.eof_index >= 0: - ss.append ((self.eof_index,' %d: EOF' % self.eof_index)) + ss.append((self.eof_index, ' %d: EOF' % self.eof_index)) if self.timeout_index >= 0: - ss.append ((self.timeout_index,' %d: TIMEOUT' % self.timeout_index)) + ss.append((self.timeout_index, ' %d: TIMEOUT' % + self.timeout_index)) ss.sort() ss = zip(*ss)[1] return '\n'.join(ss) def search(self, buffer, freshlen, searchwindowsize=None): - """This searches 'buffer' for the first occurence of one of the search strings. 'freshlen' must indicate the number of bytes at the end of 'buffer' which have not been searched before. It helps to avoid @@ -1653,12 +1652,12 @@ def search(self, buffer, freshlen, searchwindowsize=None): # rescanning until we've read three more bytes. # # Sadly, I don't know enough about this interesting topic. /grahn - + for index, s in self._strings: if searchwindowsize is None: # the match, if any, can only be in the fresh data, # or at the very end of the old data - offset = -(freshlen+len(s)) + offset = -(freshlen + len(s)) else: # better obey searchwindowsize offset = -searchwindowsize @@ -1673,6 +1672,7 @@ def search(self, buffer, freshlen, searchwindowsize=None): self.end = self.start + len(self.match) return best_index + class searcher_re (object): """This is regular expression string search helper for the @@ -1693,7 +1693,6 @@ class searcher_re (object): """ def __init__(self, patterns): - """This creates an instance that searches for 'patterns' Where 'patterns' may be a list or other sequence of compiled regular expressions, or the EOF or TIMEOUT types.""" @@ -1711,28 +1710,28 @@ def __init__(self, patterns): self._searches.append((n, s)) def __str__(self): - """This returns a human-readable string that represents the state of the object.""" - ss = [ (n,' %d: re.compile("%s")' % (n,str(s.pattern))) for n,s in self._searches] - ss.append((-1,'searcher_re:')) + ss = [(n, ' %d: re.compile("%s")' % (n, str(s.pattern))) + for n, s in self._searches] + ss.append((-1, 'searcher_re:')) if self.eof_index >= 0: - ss.append ((self.eof_index,' %d: EOF' % self.eof_index)) + ss.append((self.eof_index, ' %d: EOF' % self.eof_index)) if self.timeout_index >= 0: - ss.append ((self.timeout_index,' %d: TIMEOUT' % self.timeout_index)) + ss.append((self.timeout_index, ' %d: TIMEOUT' % + self.timeout_index)) ss.sort() ss = zip(*ss)[1] return '\n'.join(ss) def search(self, buffer, freshlen, searchwindowsize=None): - """This searches 'buffer' for the first occurence of one of the regular expressions. 'freshlen' must indicate the number of bytes at the end of 'buffer' which have not been searched before. See class spawn for the 'searchwindowsize' argument. - + If there is a match this returns the index of that string, and sets 'start', 'end' and 'match'. Otherwise, returns -1.""" @@ -1743,7 +1742,7 @@ def search(self, buffer, freshlen, searchwindowsize=None): if searchwindowsize is None: searchstart = 0 else: - searchstart = max(0, len(buffer)-searchwindowsize) + searchstart = max(0, len(buffer) - searchwindowsize) for index, s in self._searches: match = s.search(buffer, searchstart) if match is None: @@ -1760,15 +1759,15 @@ def search(self, buffer, freshlen, searchwindowsize=None): self.end = self.match.end() return best_index -def which (filename): +def which(filename): """This takes a given filename; tries to find it in the environment path; then checks if it is executable. This returns the full path to the filename if found and executable. Otherwise this returns None.""" # Special case where filename already contains a path. if os.path.dirname(filename) != '': - if os.access (filename, os.X_OK): + if os.access(filename, os.X_OK): return filename if not os.environ.has_key('PATH') or os.environ['PATH'] == '': @@ -1779,7 +1778,7 @@ def which (filename): # Oddly enough this was the one line that made Pexpect # incompatible with Python 1.5.2. #pathlist = p.split (os.pathsep) - pathlist = string.split (p, os.pathsep) + pathlist = string.split(p, os.pathsep) for path in pathlist: f = os.path.join(path, filename) @@ -1787,8 +1786,8 @@ def which (filename): return f return None -def split_command_line(command_line): +def split_command_line(command_line): """This splits a command line into a list of arguments. It splits arguments on spaces, but handles embedded quotes, doublequotes, and escaped characters. It's impossible to do this with a regular expression, so I @@ -1802,21 +1801,21 @@ def split_command_line(command_line): state_esc = 1 state_singlequote = 2 state_doublequote = 3 - state_whitespace = 4 # The state of consuming whitespace between commands. + state_whitespace = 4 # The state of consuming whitespace between commands. state = state_basic for c in command_line: if state == state_basic or state == state_whitespace: - if c == '\\': # Escape the next character + if c == '\\': # Escape the next character state = state_esc - elif c == r"'": # Handle single quote + elif c == r"'": # Handle single quote state = state_singlequote - elif c == r'"': # Handle double quote + elif c == r'"': # Handle double quote state = state_doublequote elif c.isspace(): # Add arg to arg_list if we aren't in the middle of whitespace. if state == state_whitespace: - None # Do nothing. + None # Do nothing. else: arg_list.append(arg) arg = '' diff --git a/src/sardana/tools/config/sar_to_fods.py b/src/sardana/tools/config/sar_to_fods.py index 4191557036..af46c270b1 100644 --- a/src/sardana/tools/config/sar_to_fods.py +++ b/src/sardana/tools/config/sar_to_fods.py @@ -1,8 +1,10 @@ #!/usr/bin/env python -import sys,types +import sys +import types from lxml import etree + def transform(f): t = etree.XSLT(etree.parse("SAR_TO_FODS.xslt")) if type(f) in types.StringTypes: @@ -11,6 +13,7 @@ def transform(f): doc = f return t(doc) + def main(): filename = sys.argv[1] t = transform(filename) diff --git a/src/sardana/tools/config/sardana.py b/src/sardana/tools/config/sardana.py index 06a7f04bc0..285fde7b37 100644 --- a/src/sardana/tools/config/sardana.py +++ b/src/sardana/tools/config/sardana.py @@ -30,12 +30,14 @@ import PyTango import sys import os -import time, datetime +import time +import datetime import exceptions import imp import traceback import logging -import types, operator +import types +import operator import json from taurus.core.util import CodecFactory @@ -84,6 +86,7 @@ SAR_NS = 'http://sardana.cells.es/client/framework/config' + class Process: ReadyMsg = "Ready to accept request" @@ -126,6 +129,7 @@ def getMaxStartupTime(self): def getMaxShutdownTime(self): return Process.MaxShutdownTime + class PEProcess(Process): def __init__(self, executable, args, name="PEProcess", instance=None, logfile=None, env=None): @@ -133,15 +137,17 @@ def __init__(self, executable, args, name="PEProcess", instance=None, logfile=No def start(self): self._start_time = datetime.datetime.now() - self.o("Starting '%s %s' (%s, %s)... " % (self._name, self._instance, self._exec, self._args)) + self.o("Starting '%s %s' (%s, %s)... " % + (self._name, self._instance, self._exec, self._args)) try: - self._process = pexpect.spawn(self._exec, args=self._args, logfile=self._logfile, env=self._env) + self._process = pexpect.spawn( + self._exec, args=self._args, logfile=self._logfile, env=self._env) #self.o("%s, %s, %s" % (self._exec, self._args, self._logfile)) #self._process.logfile = sys.stderr idx = self._process.expect([Process.ReadyMsg, Process.AlreadyRunning, pexpect.EOF, pexpect.TIMEOUT], - timeout=self.getMaxStartupTime()) + timeout=self.getMaxStartupTime()) except Exception, e: self.on("[FAILED]") raise e @@ -155,11 +161,14 @@ def start(self): self.on("[FAILED]") if idx == 1: - raise Exception("%s %s already running" % (self._name, self._instance)) + raise Exception("%s %s already running" % + (self._name, self._instance)) elif idx == 2: - raise Exception("%s %s terminated unexpectedly" % (self._name, self._instance)) + raise Exception("%s %s terminated unexpectedly" % + (self._name, self._instance)) elif idx == 3: - raise Exception("%s %s startup time exceeded" % (self._name, self._instance)) + raise Exception("%s %s startup time exceeded" % + (self._name, self._instance)) def terminate(self): if self._process is None: @@ -238,7 +247,8 @@ def stop(self, max_shutdown_time=None): if idx == 0: runtime = self._stop_time - self._start_time stopped = datetime.datetime.now() - self._stop_time - self.on(". (ran for %s ;took %s) [DONE]" % (str(runtime), str(stopped))) + self.on(". (ran for %s ;took %s) [DONE]" % ( + str(runtime), str(stopped))) elif idx == 1: self.o(" (shutdown time exceeded). Forcing... ") self.kill() @@ -261,7 +271,8 @@ def run(self, timeout=0): pass except pexpect.EOF: # The process terminated. Maybe to something about it in the future - self.on("%s %s terminated before expected: (EOF)" % (self._name, self._instance)) + self.on("%s %s terminated before expected: (EOF)" % + (self._name, self._instance)) self._process = None @@ -271,18 +282,21 @@ def __init__(self, executable, args, name="PEDeviceServerProcess", instance=None db = db or PyTango.Database() env = os.environ.copy() env["TANGO_HOST"] = "%s:%s" % (db.get_db_host(), db.get_db_port()) - PEProcess.__init__(self, executable, args, name, instance, logfile, env) + PEProcess.__init__(self, executable, args, + name, instance, logfile, env) def getServerName(self): return os.path.splitext(os.path.basename(self._exec))[0] def terminate(self): tango_host_port = self._env['TANGO_HOST'] - dserver_device_name = "%s/dserver/%s/%s" % (tango_host_port, self.getServerName(), self._instance) + dserver_device_name = "%s/dserver/%s/%s" % ( + tango_host_port, self.getServerName(), self._instance) dserver_device = PyTango.DeviceProxy(dserver_device_name) dserver_device.command_inout("Kill") PEProcess.terminate(self) + class PEPythonDeviceServerProcess(PEDeviceServerProcess): def getServerName(self): @@ -296,9 +310,11 @@ def __init__(self, instname, db=None, logfile=None): # Make sure the python device server code is reachable try: f, fname, desc = imp.find_module('SimuMotorCtrl') - if f: f.close() + if f: + f.close() f, path, desc = imp.find_module('SimuMotor') - if f: f.close() + if f: + f.close() except exceptions.ImportError, e: msg = "Could not find %s executable.\n" \ "Make sure PYTHONPATH points to the directory(ies) where " \ @@ -307,7 +323,8 @@ def __init__(self, instname, db=None, logfile=None): fname = os.path.join(fname, 'SimuMotorCtrl.py') - PEDeviceServerProcess.__init__(self, "/usr/bin/python", [fname, instname], name, instname, db, logfile) + PEDeviceServerProcess.__init__( + self, "/usr/bin/python", [fname, instname], name, instname, db, logfile) class PESimuCounterTimerProcess(PEPythonDeviceServerProcess): @@ -317,7 +334,8 @@ def __init__(self, instname, db=None, logfile=None): # Make sure the python device server code is reachable try: f, fname, desc = imp.find_module('SimuCoTiCtrl') - if f: f.close() + if f: + f.close() except exceptions.ImportError, e: msg = "Could not find %s executable.\n" \ "Make sure PYTHONPATH points to the directory(ies) where " \ @@ -326,7 +344,8 @@ def __init__(self, instname, db=None, logfile=None): fname = os.path.join(fname, 'SimuCoTiCtrl.py') - PEDeviceServerProcess.__init__(self, "/usr/bin/python", [fname, instname], name, instname, db, logfile) + PEDeviceServerProcess.__init__( + self, "/usr/bin/python", [fname, instname], name, instname, db, logfile) class PEPySignalSimulatorProcess(PEPythonDeviceServerProcess): @@ -336,7 +355,8 @@ def __init__(self, instname, db=None, logfile=None): # Make sure the python device server code is reachable try: f, fname, desc = imp.find_module('PySignalSimulator') - if f: f.close() + if f: + f.close() except exceptions.ImportError, e: msg = "Could not find %s executable.\n" \ "Make sure PYTHONPATH points to the directory where " \ @@ -345,7 +365,8 @@ def __init__(self, instname, db=None, logfile=None): fname = os.path.join(fname, 'PySignalSimulator.py') - PEDeviceServerProcess.__init__(self, "/usr/bin/python", [fname, instname], name, instname, db, logfile) + PEDeviceServerProcess.__init__( + self, "/usr/bin/python", [fname, instname], name, instname, db, logfile) class PEDevicePoolProcess(PEDeviceServerProcess): @@ -363,7 +384,8 @@ def __init__(self, instname, db=None, logfile=None): raise Exception("Could not find %s executable" % name) args = [instname, "--log-level=info"] - PEDeviceServerProcess.__init__(self, ex, args, name, instname, db, logfile) + PEDeviceServerProcess.__init__( + self, ex, args, name, instname, db, logfile) class PEMacroServerProcess(PEDeviceServerProcess): @@ -382,7 +404,8 @@ def __init__(self, instname, db=None, logfile=None): raise Exception("Could not find %s executable" % name) args = [instname, "--log-level=info"] - PEDeviceServerProcess.__init__(self, ex, args, name, instname, db, logfile) + PEDeviceServerProcess.__init__( + self, ex, args, name, instname, db, logfile) SimuMotorProcess = PESimuMotorProcess @@ -391,7 +414,9 @@ def __init__(self, instname, db=None, logfile=None): DevicePoolProcess = PEDevicePoolProcess MacroServerProcess = PEMacroServerProcess -#____________________________________________________________________TangoServer +# ____________________________________________________________________TangoServer + + class TangoServer: klassName = "DeviceServer" @@ -410,8 +435,7 @@ def __init__(self, servNode, bl, createProc=False, log=False): self.on("Preparing %s" % self._complete_name) self._klass_name, self._inst_name = self._complete_name.split("/") - - ########################################################################## + ####################################################################### # To prevent some disaster, just make sure the user knows that the # hostname where the server will be deleted and created. server_host = self._db.get_db_host() @@ -419,19 +443,21 @@ def __init__(self, servNode, bl, createProc=False, log=False): server_tango_host = server_host + ':' + server_port pytango_tango_host = PyTango.ApiUtil.get_env_var('TANGO_HOST') pytango_host, pytango_port = pytango_tango_host.split(':') - # Using socket to get ip addresses because one of the two hostnames could have domain + # Using socket to get ip addresses because one of the two hostnames + # could have domain import socket server_host_ip = socket.gethostbyname_ex(server_host)[2][0] pytango_host_ip = socket.gethostbyname_ex(pytango_host)[2][0] if (server_host_ip != pytango_host_ip) or (server_port != pytango_port): print '\t!!! WARNING !!! %s TANGO_HOST is not the PyTango default. You may erase the WRONG sardana definition.' % self._complete_name - print '\tServer: %s PyTango: %s' % (server_tango_host , pytango_tango_host) + print '\tServer: %s PyTango: %s' % (server_tango_host, pytango_tango_host) ans = raw_input('\tDo you _really_ want to continue? [y|N] ') if ans.lower() not in ['y', 'yes']: - raise Exception('User cancelled the creation of %s server' % self._complete_name) - ########################################################################## + raise Exception( + 'User cancelled the creation of %s server' % self._complete_name) + ####################################################################### - ########################################################################## + ####################################################################### # Before erasing the content in the database, we will also create a backup # of all the tango devices's properties and memorized attributes "a-la jive". # There's an script called jive-save-config that given the parameters @@ -439,20 +465,23 @@ def __init__(self, servNode, bl, createProc=False, log=False): # same way you can right-click an instance within jive and select the # option 'Save server data'. try: - config_file_name = self._klass_name + '-' + self._inst_name + '-' + time.strftime('%Y%m%d_%H%M%S') + '.jive' - cmd = 'TANGO_HOST=%s jive-save-config %s %s &>/dev/null' % (server_tango_host, self._complete_name, config_file_name) + config_file_name = self._klass_name + '-' + self._inst_name + \ + '-' + time.strftime('%Y%m%d_%H%M%S') + '.jive' + cmd = 'TANGO_HOST=%s jive-save-config %s %s &>/dev/null' % ( + server_tango_host, self._complete_name, config_file_name) os.system(cmd) print 'There is a backup of the deleted server config in: %s' % config_file_name except: pass - ########################################################################## - + ####################################################################### if self.klassName != self._klass_name: - raise Exception("Node name differs from expeced '%s' != '%s'" % (self._klass_name, self.klassName)) + raise Exception("Node name differs from expeced '%s' != '%s'" % ( + self._klass_name, self.klassName)) if log: - self._logfile = open("Log_%s_%s" % (self.klassName, self._inst_name), "w") + self._logfile = open("Log_%s_%s" % + (self.klassName, self._inst_name), "w") else: self._logfile = None @@ -496,7 +525,7 @@ def deleteServerFromDB(self): server_name = self._klass_name.lower() server_instance = self._inst_name.lower() server = self._complete_name.lower() - servers = [ s.lower() for s in db.get_server_list(server_name + '/*') ] + servers = [s.lower() for s in db.get_server_list(server_name + '/*')] if server in servers: devices = db.get_device_name(server, '*') @@ -516,7 +545,8 @@ def createServerInDB(self): dev_name = node.get("deviceName") if not dev_name: - raise Exception("%s does not have valid deviceName" % self._node) + raise Exception( + "%s does not have valid deviceName" % self._node) # Create the device in the database info = PyTango.DbDevInfo() @@ -552,7 +582,8 @@ def run(self, step=True, timeout=0): """Run""" while 1: self._proc.run(timeout=timeout) - if step: return + if step: + return def _createProcess(self): raise Exception("Must overwrite in subclass") @@ -632,14 +663,16 @@ def stop(self): self._proc.stop(max_shutdown_time) def _item_node_to_value(self, attr_info, node): - v = node.text or [i.text or [ j.text for j in i.findall("Item") ] for i in node.findall("Item")] + v = node.text or [i.text or [j.text for j in i.findall( + "Item")] for i in node.findall("Item")] return PyTango.seqStr_2_obj(v, attr_info.data_type, attr_info.data_format) def handle_attributes(self, dev_name, node): attrs = node.findall('Attribute') if not len(attrs): return - # Take into account the possibility to have the device in another Tango Host... + # Take into account the possibility to have the device in another Tango + # Host... dev_name = self._tghost + '/' + dev_name dev = PyTango.DeviceProxy(dev_name) tango_attrs = dev.attribute_list_query_ex() @@ -665,29 +698,41 @@ def handle_attributes(self, dev_name, node): if not c_node is None: disp_node = c_node.find("Display") if not disp_node is None: - attr_info.label = disp_node.get("label") or attr_info.label - attr_info.format = disp_node.get("format") or attr_info.format + attr_info.label = disp_node.get( + "label") or attr_info.label + attr_info.format = disp_node.get( + "format") or attr_info.format units_node = c_node.find("Units") if not units_node is None: - attr_info.unit = units_node.get("unit") or attr_info.unit - attr_info.display_unit = units_node.get("display_unit") or attr_info.display_unit - attr_info.standard_unit = units_node.get("standard_unit") or attr_info.standard_unit + attr_info.unit = units_node.get( + "unit") or attr_info.unit + attr_info.display_unit = units_node.get( + "display_unit") or attr_info.display_unit + attr_info.standard_unit = units_node.get( + "standard_unit") or attr_info.standard_unit range_node = c_node.find("Range") if not range_node is None: - attr_info.min_value = range_node.get("min") or attr_info.min_value - attr_info.max_value = range_node.get("max") or attr_info.max_value + attr_info.min_value = range_node.get( + "min") or attr_info.min_value + attr_info.max_value = range_node.get( + "max") or attr_info.max_value alarms_node = c_node.find("Alarms") if not alarms_node is None: - attr_info.alarms.min_warning = alarms_node.get("min_warning") or attr_info.alarms.min_warning - attr_info.alarms.max_warning = alarms_node.get("max_warning") or attr_info.alarms.max_warning - attr_info.alarms.min_alarm = alarms_node.get("min_alarm") or attr_info.alarms.min_alarm - attr_info.alarms.max_alarm = alarms_node.get("max_alarm") or attr_info.alarms.max_alarm + attr_info.alarms.min_warning = alarms_node.get( + "min_warning") or attr_info.alarms.min_warning + attr_info.alarms.max_warning = alarms_node.get( + "max_warning") or attr_info.alarms.max_warning + attr_info.alarms.min_alarm = alarms_node.get( + "min_alarm") or attr_info.alarms.min_alarm + attr_info.alarms.max_alarm = alarms_node.get( + "max_alarm") or attr_info.alarms.max_alarm e_node = attr.find("Events") if not e_node is None: ch_node = e_node.find("ChangeEvent") if not ch_node is None: - attr_info.events.ch_event.abs_change = ch_node.get("absolute") or attr_info.events.ch_event.abs_change + attr_info.events.ch_event.abs_change = ch_node.get( + "absolute") or attr_info.events.ch_event.abs_change rel = ch_node.get("relative") if rel: rel = rel.rstrip('%') @@ -696,7 +741,8 @@ def handle_attributes(self, dev_name, node): p_node = attr.find("Polling") if not p_node is None: polled = p_node.get("polled") or 'False' - polled = not (polled.lower() in ('false', 'no', 'n', '0')) + polled = not (polled.lower() in ( + 'false', 'no', 'n', '0')) if polled: try: period = int(p_node.get("period") or 0) @@ -722,14 +768,13 @@ def handle_attributes(self, dev_name, node): print 'SOME PROBLEMS SETTING INSTRUMENT VALUE FOR DEVICE', dev_name, 'VALUE', value print 'EXCEPTION:', ex - def loadPool(self): start_load_time = datetime.datetime.now() self.on(" Loading 'Device Pool %s'..." % self._inst_name) try: tgHost = self._node.get("tangoHost") or \ - ("%s:%s" % (self._db.get_db_host(), self._db.get_db_port())) + ("%s:%s" % (self._db.get_db_host(), self._db.get_db_port())) pool = self._node.find(self.klassName) @@ -738,7 +783,8 @@ def loadPool(self): pool_dp = PyTango.DeviceProxy(pool_dev_name) factory = CodecFactory() - elements = factory.decode(pool_dp.elements, ensure_ascii='True')['new'] + elements = factory.decode( + pool_dp.elements, ensure_ascii='True')['new'] ctrl_classes_info = {} for elem in elements: @@ -769,7 +815,8 @@ def loadPool(self): raise self.on(" (%d) [DONE]" % count) - ctrls = pool.xpath("Controller[@type != 'PseudoMotor' and @type != 'PseudoCounter']") + ctrls = pool.xpath( + "Controller[@type != 'PseudoMotor' and @type != 'PseudoCounter']") self.o(" Creating controllers ") count = 0 self.dev_count = 0 @@ -793,10 +840,12 @@ def loadPool(self): props = ctrl.findall("Property") for p in props: pars.append(p.get("name")) - pars.append(p.text or '\n'.join([i.text for i in p.findall("Item")])) + pars.append(p.text or '\n'.join( + [i.text for i in p.findall("Item")])) pars = map(str.strip, pars) pool_dp.command_inout("CreateController", pars) - self.run(step=True) # to flush any output generated by the pool + # to flush any output generated by the pool + self.run(step=True) count += 1 except: self.on("[FAILED]") @@ -809,7 +858,8 @@ def loadPool(self): for ctrl in ctrls: name = ctrl.get("name") elems = ctrl.findall("Motor") - # skip motor creation for controllers which name starts with '#' + # skip motor creation for controllers which name starts with + # '#' if name.startswith('#'): elems = [] for e in elems: @@ -831,7 +881,8 @@ def loadPool(self): self.handle_attributes(aliasName, e) - self.run(step=True) # to flush any output generated by the pool + # to flush any output generated by the pool + self.run(step=True) count += 1 self.dev_count += 1 except: @@ -845,7 +896,8 @@ def loadPool(self): for ctrl in ctrls: name = ctrl.get("name") elems = ctrl.findall("CounterTimer") - # skip counter/timers creation for controllers which name starts with '#' + # skip counter/timers creation for controllers which name + # starts with '#' if name.startswith('#'): elems = [] for e in elems: @@ -853,7 +905,8 @@ def loadPool(self): axis = e.get("axis") aliasName = e.get("name") deviceName = e.get("deviceName") or "" - # skip counter/timers creation for alias starting with '#' + # skip counter/timers creation for alias starting with + # '#' if aliasName.startswith('#'): self.o('x') continue @@ -866,7 +919,8 @@ def loadPool(self): self.handle_attributes(aliasName, e) - self.run(step=True) # to flush any output generated by the pool + # to flush any output generated by the pool + self.run(step=True) count += 1 self.dev_count += 1 except: @@ -903,8 +957,10 @@ def loadPool(self): self.handle_attributes(aliasName, e) except PyTango.DevFailed, df: - self.on("Exception creating %s: %s" % (aliasName, str(df))) - self.run(step=True) # to flush any output generated by the pool + self.on("Exception creating %s: %s" % + (aliasName, str(df))) + # to flush any output generated by the pool + self.run(step=True) count += 1 self.dev_count += 1 except: @@ -939,7 +995,8 @@ def loadPool(self): self.handle_attributes(aliasName, e) - self.run(step=True) # to flush any output generated by the pool + # to flush any output generated by the pool + self.run(step=True) count += 1 self.dev_count += 1 except: @@ -974,7 +1031,8 @@ def loadPool(self): self.handle_attributes(aliasName, e) - self.run(step=True) # to flush any output generated by the pool + # to flush any output generated by the pool + self.run(step=True) count += 1 self.dev_count += 1 except: @@ -988,7 +1046,8 @@ def loadPool(self): for ctrl in ctrls: name = ctrl.get("name") elems = ctrl.findall("IORegister") - # skip IORegisters creation for controllers which name starts with '#' + # skip IORegisters creation for controllers which name starts + # with '#' if name.startswith('#'): elems = [] for e in elems: @@ -1009,7 +1068,8 @@ def loadPool(self): self.handle_attributes(aliasName, e) - self.run(step=True) # to flush any output generated by the pool + # to flush any output generated by the pool + self.run(step=True) count += 1 self.dev_count += 1 except: @@ -1051,7 +1111,8 @@ def loadPool(self): pars.append("%s=%s" % (motor_roles[i], e.text)) for i, e in enumerate(ctrl.findall("PseudoMotor")): - pars.append("%s=%s" % (pseudo_motor_roles[i], e.get('name'))) + pars.append("%s=%s" % + (pseudo_motor_roles[i], e.get('name'))) pm_count += len(ctrl.findall("PseudoMotor")) self.dev_count += pm_count @@ -1060,7 +1121,8 @@ def loadPool(self): for p in props: pars.append(p.get("name")) - pars.append(p.text or '\n'.join([i.text for i in p.findall("Item")])) + pars.append(p.text or '\n'.join( + [i.text for i in p.findall("Item")])) pars = map(str.strip, pars) @@ -1070,14 +1132,14 @@ def loadPool(self): for e in ctrl.findall('PseudoMotor'): self.handle_attributes(e.get("name"), e) - self.run(step=True) # to flush any output generated by the pool + # to flush any output generated by the pool + self.run(step=True) except: self.on("[FAILED]") print ctrl_class_info raise - self.on(" (%d ctrls; %d pmotors) [DONE]" % (pm_ctrl_count, pm_count)) - - + self.on(" (%d ctrls; %d pmotors) [DONE]" % ( + pm_ctrl_count, pm_count)) ctrls = pool.xpath("Controller[@type = 'PseudoCounter']") @@ -1098,7 +1160,8 @@ def loadPool(self): ctrl_class_info = ctrl_classes_info[kclass] counter_roles = ctrl_class_info['counter_roles'] - pseudo_counter_roles = ctrl_class_info['pseudo_counter_roles'] + pseudo_counter_roles = ctrl_class_info[ + 'pseudo_counter_roles'] pars = [type, lib, kclass, name] @@ -1106,7 +1169,8 @@ def loadPool(self): pars.append("%s=%s" % (counter_roles[i], e.text)) for i, e in enumerate(ctrl.findall("PseudoCounter")): - pars.append("%s=%s" % (pseudo_counter_roles[i], e.get('name'))) + pars.append("%s=%s" % + (pseudo_counter_roles[i], e.get('name'))) pc_count += len(ctrl.findall("PseudoCounter")) self.dev_count += pc_count @@ -1115,7 +1179,8 @@ def loadPool(self): for p in props: pars.append(p.get("name")) - pars.append(p.text or '\n'.join([i.text for i in p.findall("Item")])) + pars.append(p.text or '\n'.join( + [i.text for i in p.findall("Item")])) pars = map(str.strip, pars) @@ -1125,11 +1190,13 @@ def loadPool(self): for e in ctrl.findall('PseudoCounter'): self.handle_attributes(e.get("name"), e) - self.run(step=True) # to flush any output generated by the pool + # to flush any output generated by the pool + self.run(step=True) except: self.on("[FAILED]") raise - self.on("(%d ctrls; %d pcounters) [DONE]" % (pc_ctrl_count, pc_count)) + self.on("(%d ctrls; %d pcounters) [DONE]" % ( + pc_ctrl_count, pc_count)) measurement_groups = pool.findall("MeasurementGroup") self.o(" Creating Measurement Groups ") @@ -1144,7 +1211,7 @@ def loadPool(self): self.o(".") channels = mg.findall("ChannelRef") - pars = [ aliasName ] + pars = [aliasName] for channel in channels: pars.append(channel.get("name")) pars = map(str.strip, pars) @@ -1152,7 +1219,8 @@ def loadPool(self): self.handle_attributes(aliasName, mg) - self.run(step=True) # to flush any output generated by the pool + # to flush any output generated by the pool + self.run(step=True) count += 1 self.dev_count += 1 except: @@ -1162,7 +1230,8 @@ def loadPool(self): end_load_time = datetime.datetime.now() dt = end_load_time - start_load_time - self.on(" Loading 'Device Pool %s'... (took %s) [DONE]" % (self._inst_name, str(dt))) + self.on(" Loading 'Device Pool %s'... (took %s) [DONE]" % ( + self._inst_name, str(dt))) except: self.on(" Loading 'Device Pool %s'... [FAILED]" % self._inst_name) raise @@ -1189,24 +1258,24 @@ class Sardana: """Generic Sardana system""" SimulationModes = { - "Basic" : { "Motor" : ("DummyMotorController.py", "DummyMotorController"), - "CounterTimer" : ("DummyCounterTimerController.py", "DummyCounterTimerController"), - "ZeroDExpChannel" : ("DummyZeroDController.py", "DummyZeroDController"), - "OneDExpChannel" : ("Dummy1DController.py", "'Dummy1DController"), - "TwoDExpChannel" : ("Dummy2DController.py", "'Dummy2DController"), - "IORegister" : ("DummyIORController.py", "DummyIORController") }, - "Best" : { "Motor" : ("SimuMotCtrl.py", "SimuMotorController"), - "CounterTimer" : ("SimuCTCtrl.py", "SimuCoTiController"), - "ZeroDExpChannel" : ("Simu0DCtrl.py", "Simu0DController"), - "OneDExpChannel" : ("Simu1DCtrl.py", "Simu1DController"), - "TwoDExpChannel" : ("Simu2DCtrl.py", "Simu2DController"), - "IORegister" : ("SimuIOCtrl.py", "SimuIOController"), }, - "Off" : { "Motor" : (None, None), - "CounterTimer" : (None, None), - "ZeroDExpChannel" : (None, None), - "OneDExpChannel" : (None, None), - "TwoDExpChannel" : (None, None), - "IORegister" : (None, None) }, + "Basic": {"Motor": ("DummyMotorController.py", "DummyMotorController"), + "CounterTimer": ("DummyCounterTimerController.py", "DummyCounterTimerController"), + "ZeroDExpChannel": ("DummyZeroDController.py", "DummyZeroDController"), + "OneDExpChannel": ("Dummy1DController.py", "'Dummy1DController"), + "TwoDExpChannel": ("Dummy2DController.py", "'Dummy2DController"), + "IORegister": ("DummyIORController.py", "DummyIORController")}, + "Best": {"Motor": ("SimuMotCtrl.py", "SimuMotorController"), + "CounterTimer": ("SimuCTCtrl.py", "SimuCoTiController"), + "ZeroDExpChannel": ("Simu0DCtrl.py", "Simu0DController"), + "OneDExpChannel": ("Simu1DCtrl.py", "Simu1DController"), + "TwoDExpChannel": ("Simu2DCtrl.py", "Simu2DController"), + "IORegister": ("SimuIOCtrl.py", "SimuIOController"), }, + "Off": {"Motor": (None, None), + "CounterTimer": (None, None), + "ZeroDExpChannel": (None, None), + "OneDExpChannel": (None, None), + "TwoDExpChannel": (None, None), + "IORegister": (None, None)}, } def __init__(self, source, simulation="Best", cleanup=True, log=False): @@ -1292,12 +1361,18 @@ def _preprocess(self): Simu2DLib, Simu2DClass = simType["TwoDExpChannel"] SimuIOLib, SimuIOClass = simType["IORegister"] - simuMotorLibs = [ mode["Motor"][0] for mode in self.SimulationModes.values()] - simuCoTiLibs = [ mode["CounterTimer"][0] for mode in self.SimulationModes.values()] - simu0DLibs = [ mode["ZeroDExpChannel"][0] for mode in self.SimulationModes.values()] - simu1DLibs = [ mode["OneDExpChannel"][0] for mode in self.SimulationModes.values()] - simu2DLibs = [ mode["TwoDExpChannel"][0] for mode in self.SimulationModes.values()] - simuIOLibs = [ mode["IORegister"][0] for mode in self.SimulationModes.values()] + simuMotorLibs = [mode["Motor"][0] + for mode in self.SimulationModes.values()] + simuCoTiLibs = [mode["CounterTimer"][0] + for mode in self.SimulationModes.values()] + simu0DLibs = [mode["ZeroDExpChannel"][0] + for mode in self.SimulationModes.values()] + simu1DLibs = [mode["OneDExpChannel"][0] + for mode in self.SimulationModes.values()] + simu2DLibs = [mode["TwoDExpChannel"][0] + for mode in self.SimulationModes.values()] + simuIOLibs = [mode["IORegister"][0] + for mode in self.SimulationModes.values()] for poolserver in poolservers: simuMotorList = [] @@ -1317,7 +1392,8 @@ def _preprocess(self): if self._simulation == "Best": # add a SimuMotorServer node to the Sardana node - simuServer = etree.SubElement(self._sarNode, "SimuMotorServer") + simuServer = etree.SubElement( + self._sarNode, "SimuMotorServer") tgHost = poolserver.get("tangoHost") if tgHost: simuServer.set("tangoHost", tgHost) @@ -1326,8 +1402,10 @@ def _preprocess(self): serverName += "%03d" % motSimNb simuServer.set("serverName", serverName) - simuMotCtrl = etree.SubElement(simuServer, "SimuMotorCtrl") - simuMotCtrlName = "%s/simumotctrl/%03d" % (sarName, motSimNb) + simuMotCtrl = etree.SubElement( + simuServer, "SimuMotorCtrl") + simuMotCtrlName = "%s/simumotctrl/%03d" % ( + sarName, motSimNb) simuMotCtrl.set("deviceName", simuMotCtrlName) maxError = etree.SubElement(simuMotCtrl, "Property") maxError.set("name", "MaxError") @@ -1336,8 +1414,10 @@ def _preprocess(self): for m in ctrl.findall("Motor"): m_nb = int(m.get('axis')) - simuMotor = etree.SubElement(simuServer, "SimuMotor") - devName = "%s/simumotctrl%03d/%03d" % (sarName, motSimNb, m_nb) + simuMotor = etree.SubElement( + simuServer, "SimuMotor") + devName = "%s/simumotctrl%03d/%03d" % ( + sarName, motSimNb, m_nb) simuMotor.set("deviceName", devName) simuMotor.set("class", "SimuMotor") simuMotorList.append(simuMotor) @@ -1355,9 +1435,9 @@ def _preprocess(self): devNameV.text = simuMotCtrlName # Process CounterTimer controllers - ctctrls = pool.xpath("Controller[@type = 'CounterTimer' and " \ - "@lib != '%s' and @class != '%s']" \ - % ("UxTimerCtrl.la", "UnixTimer")) + ctctrls = pool.xpath("Controller[@type = 'CounterTimer' and " + "@lib != '%s' and @class != '%s']" + % ("UxTimerCtrl.la", "UnixTimer")) needsServerNumber = len(ctctrls) > 1 for ctrl in ctctrls: lib = ctrl.get("lib") @@ -1370,7 +1450,8 @@ def _preprocess(self): if self._simulation == "Best": # add a SimuCoTiServer node to the Sardana node - simuServer = etree.SubElement(self._sarNode, "SimuCoTiServer") + simuServer = etree.SubElement( + self._sarNode, "SimuCoTiServer") tghost = poolserver.get("tangoHost") if tghost: simuServer.set("tangoHost", tgHost) @@ -1379,18 +1460,23 @@ def _preprocess(self): serverName += "%03d" % ctSimNb simuServer.set("serverName", serverName) - simuCoTiCtrl = etree.SubElement(simuServer, "SimuCoTiCtrl") - simuCoTiCtrlName = "%s/simuctctrl/%03d" % (sarName, ctSimNb) + simuCoTiCtrl = etree.SubElement( + simuServer, "SimuCoTiCtrl") + simuCoTiCtrlName = "%s/simuctctrl/%03d" % ( + sarName, ctSimNb) simuCoTiCtrl.set("deviceName", simuCoTiCtrlName) motRef = 0 for ct in ctrl.findall("CounterTimer"): ct_nb = int(ct.get('axis')) - simuCounter = etree.SubElement(simuServer, "SimuCounter") - devName = "%s/simuctctrl%03d/%03d" % (sarName, ctSimNb, ct_nb) + simuCounter = etree.SubElement( + simuServer, "SimuCounter") + devName = "%s/simuctctrl%03d/%03d" % ( + sarName, ctSimNb, ct_nb) simuCounter.set("deviceName", devName) simuCounter.set("class", "SimuCounter") - pAverage = etree.SubElement(simuCounter, "Property") + pAverage = etree.SubElement( + simuCounter, "Property") pAverage.set("name", "Average") pAverage.set("type", "DevDouble") pAverage.text = "50.0" @@ -1406,10 +1492,12 @@ def _preprocess(self): pSigma.text = "250.0" if simuMotorList: - pMotorName = etree.SubElement(simuCounter, "Property") + pMotorName = etree.SubElement( + simuCounter, "Property") pMotorName.set("name", "MotorName") pMotorName.set("type", "DevString") - pMotorName.text = simuMotorList[motRef].get("deviceName") + pMotorName.text = simuMotorList[ + motRef].get("deviceName") if motRef == len(simuMotorList) - 1: motRef = 0 else: @@ -1429,7 +1517,8 @@ def _preprocess(self): pySigSimNode = None # Process 0D controllers - zerodctrls = pool.xpath("Controller[@type = 'ZeroDExpChannel']") + zerodctrls = pool.xpath( + "Controller[@type = 'ZeroDExpChannel']") for ctrl in zerodctrls: lib = ctrl.get("lib") klass = ctrl.get("class") @@ -1443,26 +1532,31 @@ def _preprocess(self): if self._simulation == "Best": if pySigSimNode is None: # add a PySignalSimulator node to the Sardana node - pySigSimNode = etree.SubElement(self._sarNode, "PySignalSimulatorServer") + pySigSimNode = etree.SubElement( + self._sarNode, "PySignalSimulatorServer") tghost = poolserver.get("tangoHost") if tghost: pySigSimNode.set("tangoHost", tgHost) serverName = "PySignalSimulator/%s" % sarName pySigSimNode.set("serverName", serverName) - simu0DCtrl = etree.SubElement(pySigSimNode, "PySignalSimulator") - simu0DCtrlName = "%s/PySignalSimulator/%03d" % (sarName, pySigSimNb) + simu0DCtrl = etree.SubElement( + pySigSimNode, "PySignalSimulator") + simu0DCtrlName = "%s/PySignalSimulator/%03d" % ( + sarName, pySigSimNb) simu0DCtrl.set("deviceName", simu0DCtrlName) zerods = ctrl.findall("ZeroDExpChannel") if len(zerods) > 0: - pSimAttributes = etree.SubElement(simu0DCtrl, "Property") + pSimAttributes = etree.SubElement( + simu0DCtrl, "Property") pSimAttributes.set("name", "DynamicAttributes") pSimAttributes.set("type", "DevVarStringArray") simAttrTempl = "zerod%03d=float(100.0+10.0*random())" for i in xrange(len(zerods)): - pSimAttributeItem = etree.SubElement(pSimAttributes, "Item") + pSimAttributeItem = etree.SubElement( + pSimAttributes, "Item") pSimAttributeItem.text = simAttrTempl % (i + 1) # change the pool XML nodes to refer to simulator lib @@ -1475,7 +1569,8 @@ def _preprocess(self): attributeNames.set("name", "AttributeNames") simAttrTempl = "%s/zerod%%03d" % simu0DCtrlName for i in xrange(len(zerods)): - attributeNameItem = etree.SubElement(attributeNames, "Item") + attributeNameItem = etree.SubElement( + attributeNames, "Item") attributeNameItem.text = simAttrTempl % (i + 1) # Process 1D controllers @@ -1493,27 +1588,32 @@ def _preprocess(self): if self._simulation == "Best": if pySigSimNode is None: # add a PySignalSimulator node to the Sardana node - pySigSimNode = etree.SubElement(self._sarNode, "PySignalSimulatorServer") + pySigSimNode = etree.SubElement( + self._sarNode, "PySignalSimulatorServer") tghost = poolserver.get("tangoHost") if tghost: pySigSimNode.set("tangoHost", tgHost) serverName = "PySignalSimulator/%s" % sarName pySigSimNode.set("serverName", serverName) - simu1DCtrl = etree.SubElement(pySigSimNode, "PySignalSimulator") - simu1DCtrlName = "%s/PySignalSimulator/%03d" % (sarName, pySigSimNb) + simu1DCtrl = etree.SubElement( + pySigSimNode, "PySignalSimulator") + simu1DCtrlName = "%s/PySignalSimulator/%03d" % ( + sarName, pySigSimNb) simu1DCtrl.set("deviceName", simu1DCtrlName) onedds = ctrl.findall("OneDExpChannel") if len(onedds) > 0: - pSimAttributes = etree.SubElement(simu1DCtrl, "Property") + pSimAttributes = etree.SubElement( + simu1DCtrl, "Property") pSimAttributes.set("name", "DynamicAttributes") pSimAttributes.set("type", "DevVarStringArray") simAttrTempl = "oned%03d=DevVarLongArray([10*sin(0.01*x) for x in xrange(100)])" for i in xrange(len(oneds)): - pSimAttributeItem = etree.SubElement(pSimAttributes, "Item") + pSimAttributeItem = etree.SubElement( + pSimAttributes, "Item") pSimAttributeItem.text = simAttrTempl % (i + 1) # change the pool XML nodes to refer to simulator lib @@ -1524,10 +1624,12 @@ def _preprocess(self): if self._simulation == "Best": attributeNames = etree.SubElement(ctrl, "Property") attributeNames.set("name", "AttributeNames") - attributeNamesV = etree.SubElement(attributeNames, "Item") + attributeNamesV = etree.SubElement( + attributeNames, "Item") simAttrTempl = "%s/oned%%03d" % simu1DCtrlName for i in xrange(len(oneds)): - attributeNameItem = etree.SubElement(attributeNames, "Item") + attributeNameItem = etree.SubElement( + attributeNames, "Item") attributeNameItem.text = simAttrTempl % (i + 1) # Process IORegister controllers @@ -1545,28 +1647,34 @@ def _preprocess(self): if self._simulation == "Best": if pySigSimNode is None: # add a PySignalSimulator node to the Sardana node - pySigSimNode = etree.SubElement(self._sarNode, "PySignalSimulatorServer") + pySigSimNode = etree.SubElement( + self._sarNode, "PySignalSimulatorServer") tghost = poolserver.get("tangoHost") if tghost: pySigSimNode.set("tangoHost", tgHost) serverName = "PySignalSimulator/%s" % sarName pySigSimNode.set("serverName", serverName) - simuIOCtrl = etree.SubElement(pySigSimNode, "PySignalSimulator") - simuIOCtrlName = "%s/PySignalSimulator/%03d" % (sarName, pySigSimNb) + simuIOCtrl = etree.SubElement( + pySigSimNode, "PySignalSimulator") + simuIOCtrlName = "%s/PySignalSimulator/%03d" % ( + sarName, pySigSimNb) simuIOCtrl.set("deviceName", simuIOCtrlName) iors = ctrl.findall("IORegister") if len(iors) > 0: - pSimAttributes = etree.SubElement(simuIOCtrl, "Property") + pSimAttributes = etree.SubElement( + simuIOCtrl, "Property") pSimAttributes.set("name", "DynamicAttributes") pSimAttributes.set("type", "DevVarStringArray") simAttrTempl = "ior%03d=int(READ and VAR('ior%03d') or WRITE and VAR('ior%03d',VALUE))" for i in xrange(len(iors)): - pSimAttributeItem = etree.SubElement(pSimAttributes, "Item") - pSimAttributeItem.text = simAttrTempl % ((i + 1), (i + 1), (i + 1)) + pSimAttributeItem = etree.SubElement( + pSimAttributes, "Item") + pSimAttributeItem.text = simAttrTempl % ( + (i + 1), (i + 1), (i + 1)) # change the pool XML nodes to refer to simulator lib # instead of real lib @@ -1578,7 +1686,8 @@ def _preprocess(self): attributeNames.set("name", "AttributeNames") simAttrTempl = "%s/ior%%03d" % simuIOCtrlName for i in xrange(len(iors)): - attributeNameItem = etree.SubElement(attributeNames, "Item") + attributeNameItem = etree.SubElement( + attributeNames, "Item") attributeNameItem.text = simAttrTempl % (i + 1) end_pp_time = datetime.datetime.now() @@ -1598,7 +1707,8 @@ def prepare(self): sarNodeName = "Sardana" if self._sarNode.tag != sarNodeName: - raise Exception(" root node not found in %s" % self._filename) + raise Exception(" root node not found in %s" % + self._filename) self._preprocess() @@ -1735,7 +1845,8 @@ def getRoot(self): import getopt try: - opts, pargs = getopt.getopt(sys.argv[1:], 'vl', ['simulation=', 'cleanup=']) + opts, pargs = getopt.getopt( + sys.argv[1:], 'vl', ['simulation=', 'cleanup=']) except Exception, e: print "ERROR:", str(e) print @@ -1774,7 +1885,8 @@ def getRoot(self): print 'Sorry, but some problems found when trying to convert to SARDANA xml:' print str(e) - sardana = Sardana(sar_doc, simulation=simulation, log=activate_logging, cleanup=cleanup) + sardana = Sardana(sar_doc, simulation=simulation, + log=activate_logging, cleanup=cleanup) if just_output_and_exit: sardana.prepare() @@ -1792,4 +1904,3 @@ def getRoot(self): print "Shutting down!" sardana.tearDown() - diff --git a/src/sardana/tools/config/to_sar.py b/src/sardana/tools/config/to_sar.py index f3c5eada9a..434e08b33b 100644 --- a/src/sardana/tools/config/to_sar.py +++ b/src/sardana/tools/config/to_sar.py @@ -1,21 +1,23 @@ #!/usr/bin/env python -import sys, types +import sys +import types from lxml import etree SAR_NS = 'http://sardana.cells.es/client/framework/config' + def transform(f): if type(f) in types.StringTypes: doc = etree.parse(f) else: doc = f - + root = doc.getroot() - + if (root.nsmap.get(None) == SAR_NS) or root.tag.endswith("Sardana"): return doc - + # it is either a EXCEL XML or a Flat ODS if root.nsmap.get('ss'): import xls_to_sar @@ -25,6 +27,7 @@ def transform(f): t = fods_to_sar.transform return t(doc) + def main(): filename = sys.argv[1] t = transform(filename) diff --git a/src/sardana/tools/config/xls_to_sar.py b/src/sardana/tools/config/xls_to_sar.py index 0224da30e8..3e53b82c6c 100644 --- a/src/sardana/tools/config/xls_to_sar.py +++ b/src/sardana/tools/config/xls_to_sar.py @@ -10,9 +10,12 @@ """ -import sys, os, types +import sys +import os +import types from lxml import etree + def transform(f): directory = os.path.dirname(os.path.abspath(__file__)) xslt_filename = os.path.join(directory, "XLS_TO_SAR.xslt") @@ -24,11 +27,12 @@ def transform(f): doc = f return t(doc) + def main(): if len(sys.argv) < 2: print __doc__ sys.exit(1) - + filename = sys.argv[1] t = transform(filename) print etree.tostring(t, pretty_print=True) diff --git a/src/sardana/util/__init__.py b/src/sardana/util/__init__.py index 3aedf9ffe2..c84542cfe9 100644 --- a/src/sardana/util/__init__.py +++ b/src/sardana/util/__init__.py @@ -3,26 +3,25 @@ ############################################################################## ## -## This file is part of Sardana -## -## http://www.sardana-controls.org/ +# This file is part of Sardana ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# http://www.sardana-controls.org/ +## +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## """This module provides the sardana utilities""" - diff --git a/src/sardana/util/deepreload.py b/src/sardana/util/deepreload.py index 670e308c9a..5a38302a8f 100644 --- a/src/sardana/util/deepreload.py +++ b/src/sardana/util/deepreload.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -54,10 +54,10 @@ class DeepReload(object): - + def __enter__(self): - __builtin__.reload = reload - + __builtin__.reload = reload + def __exit__(self, etype, evalue, etraceback): __builtin__.reload = original_reload @@ -71,6 +71,7 @@ def replace_import_hook(new_import): finally: __builtin__.__import__ = saved_import + def get_parent(globals, level): """ parent, name = get_parent(globals, level) @@ -144,6 +145,7 @@ def get_parent(globals, level): # If this is violated... Who cares? return parent, name + def load_next(mod, altmod, name, buf): """ mod, name, buf = load_next(mod, altmod, name, buf) @@ -165,7 +167,7 @@ def load_next(mod, altmod, name, buf): next = None else: subname = name[:dot] - next = name[dot+1:] + next = name[dot + 1:] if buf != '': buf += '.' @@ -185,6 +187,7 @@ def load_next(mod, altmod, name, buf): # Need to keep track of what we've already reloaded to prevent cyclic evil found_now = {} + def import_submodule(mod, subname, fullname): """m = import_submodule(mod, subname, fullname)""" # Require: @@ -224,16 +227,18 @@ def import_submodule(mod, subname, fullname): sys.modules[fullname] = oldm raise finally: - if fp: fp.close() + if fp: + fp.close() add_submodule(mod, m, fullname, subname) return m + def add_submodule(mod, submod, fullname, subname): """mod.{subname} = submod""" if mod is None: - return #Nothing to do here. + return # Nothing to do here. if submod is None: submod = sys.modules[fullname] @@ -242,6 +247,7 @@ def add_submodule(mod, submod, fullname, subname): return + def ensure_fromlist(mod, fromlist, buf, recursive): """Handle 'from module import a, b, c' imports.""" if not hasattr(mod, '__path__'): @@ -251,7 +257,7 @@ def ensure_fromlist(mod, fromlist, buf, recursive): raise TypeError("Item in ``from list'' not a string") if item == '*': if recursive: - continue # avoid endless recursion + continue # avoid endless recursion try: all = mod.__all__ except AttributeError: @@ -263,11 +269,13 @@ def ensure_fromlist(mod, fromlist, buf, recursive): elif not hasattr(mod, item): import_submodule(mod, item, buf + '.' + item) + def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1): """Replacement for __import__()""" parent, buf = get_parent(globals, level) - head, name, buf = load_next(parent, None if level < 0 else parent, name, buf) + head, name, buf = load_next( + parent, None if level < 0 else parent, name, buf) tail = head while name: @@ -287,6 +295,7 @@ def deep_import_hook(name, globals=None, locals=None, fromlist=None, level=-1): modules_reloading = {} + def deep_reload_hook(m): """Replacement for reload().""" if not isinstance(m, ModuleType): @@ -312,8 +321,9 @@ def deep_reload_hook(m): parent = sys.modules[name[:dot]] except KeyError: modules_reloading.clear() - raise ImportError("reload(): parent %.200s not in sys.modules" % name[:dot]) - subname = name[dot+1:] + raise ImportError( + "reload(): parent %.200s not in sys.modules" % name[:dot]) + subname = name[dot + 1:] path = getattr(parent, "__path__", None) try: @@ -321,7 +331,7 @@ def deep_reload_hook(m): # tries to import standard libraries (like io) itself, and we don't # want them to be processed by our deep_import_hook. with replace_import_hook(original_import): - fp, filename, stuff = imp.find_module(subname, path) + fp, filename, stuff = imp.find_module(subname, path) finally: modules_reloading.clear() @@ -333,7 +343,8 @@ def deep_reload_hook(m): sys.modules[name] = m raise finally: - if fp: fp.close() + if fp: + fp.close() modules_reloading.clear() return newm @@ -345,6 +356,8 @@ def deep_reload_hook(m): original_reload = imp.reload # Python 3 # Replacement for reload() + + def reload(module, exclude=['sys', 'os.path', '__builtin__', '__main__']): """Recursively reload all modules used in the given module. Optionally takes a list of modules to exclude from reloading. The default exclude diff --git a/src/sardana/util/funcgenerator.py b/src/sardana/util/funcgenerator.py index 3bd17fbbc0..88135595a1 100644 --- a/src/sardana/util/funcgenerator.py +++ b/src/sardana/util/funcgenerator.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -86,7 +86,7 @@ def get_initial_domain_in_use(self): return self._initial_domain_in_use initial_domain_in_use = property(get_initial_domain_in_use, - set_initial_domain_in_use) + set_initial_domain_in_use) def set_active_domain_in_use(self, domain): self._active_domain_in_use = domain @@ -95,7 +95,7 @@ def get_active_domain_in_use(self): return self._active_domain_in_use active_domain_in_use = property(get_active_domain_in_use, - set_active_domain_in_use) + set_active_domain_in_use) def add_active_event(self, event): self._active_events.append(event) @@ -177,11 +177,11 @@ def run(self): def sleep(self, period): if period <= 0: return - necessary_naps = int(math.ceil(period/self.MAX_NAP_TIME)) - if necessary_naps == 0: # avoid zero ZeroDivisionError + necessary_naps = int(math.ceil(period / self.MAX_NAP_TIME)) + if necessary_naps == 0: # avoid zero ZeroDivisionError nap = 0 else: - nap = period/necessary_naps + nap = period / necessary_naps for _ in xrange(necessary_naps): if self.is_stopped(): break @@ -325,5 +325,5 @@ def set_configuration(self, configuration): if self.direction is None: self.direction = direction elif self.direction != direction: - msg= "active values indicate contradictory directions" + msg = "active values indicate contradictory directions" raise ValueError(msg) diff --git a/src/sardana/util/motion/__init__.py b/src/sardana/util/motion/__init__.py index 15173d06c7..9262607008 100644 --- a/src/sardana/util/motion/__init__.py +++ b/src/sardana/util/motion/__init__.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +## +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +## +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +## +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## diff --git a/src/sardana/util/motion/motion.py b/src/sardana/util/motion/motion.py index b5e9050769..8648a0c419 100644 --- a/src/sardana/util/motion/motion.py +++ b/src/sardana/util/motion/motion.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -71,9 +71,9 @@ class MotionPath(object): duration = -1 def __init__(self, motor, - initial_user_pos, - final_user_pos, - active_time=None): + initial_user_pos, + final_user_pos, + active_time=None): """MotionPath constructor - creates and calculates motion path parameters. :param initial_user_pos: position at which constant vel @@ -109,10 +109,10 @@ def _calculateMotionPath(self): final_pos = final_user_pos * motor.step_per_unit displacement = abs(final_pos - initial_pos) - + # in this case active_time forces that the user range # correspond to the constant velocity - # and + # and if self.active_time != None: velocity = displacement / self.active_time self.motor.setMaxVelocity(velocity) @@ -124,7 +124,7 @@ def _calculateMotionPath(self): decel_displacement = decel_time * 0.5 * (velocity - base_vel) initial_pos -= sign * accel_displacement final_pos += sign * decel_displacement - displacement = abs(final_pos - initial_pos) + displacement = abs(final_pos - initial_pos) self.initial_user_pos = initial_pos self.final_user_pos = final_pos @@ -148,7 +148,8 @@ def _calculateMotionPath(self): else: positive_displacement = final_pos > initial_pos - displmnt_not_cnst = motor.displacement_reach_max_vel + motor.displacement_reach_min_vel + displmnt_not_cnst = motor.displacement_reach_max_vel + \ + motor.displacement_reach_min_vel small_motion = displacement < displmnt_not_cnst if positive_displacement: @@ -176,7 +177,8 @@ def _calculateMotionPath(self): max_vel_pos = initial_pos - displacement_reach_max_vel # displacement at maximum velocity - at_max_vel_displacement = displacement - (displacement_reach_max_vel + displacement_reach_min_vel) + at_max_vel_displacement = displacement - \ + (displacement_reach_max_vel + displacement_reach_min_vel) else: # Small movement # position where maximum velocity will be reached @@ -208,7 +210,7 @@ def _calculateMotionPath(self): # time to reach maximum velocity if accel == 0 or delta_vel == float('inf'): - max_vel_time = 0 + max_vel_time = 0 else: max_vel_time = abs(delta_vel / accel) @@ -239,7 +241,7 @@ def _calculateMotionPath(self): self.displacement_reach_max_vel = displacement_reach_max_vel self.displacement_reach_min_vel = displacement_reach_min_vel - self.max_vel = abs(max_vel) #velocity must be a positive value + self.max_vel = abs(max_vel) # velocity must be a positive value self.min_vel = abs(min_vel) self.max_vel_pos = max_vel_pos self.at_max_vel_displacement = at_max_vel_displacement @@ -281,7 +283,8 @@ class Motion(object): final_instant = -1 def __init__(self, motor, initial_user_pos, final_user_pos, start_instant=None): - self.motion_path = mp = MotionPath(motor, initial_user_pos, final_user_pos) + self.motion_path = mp = MotionPath( + motor, initial_user_pos, final_user_pos) start_instant = start_instant or time.time() max_vel_instant = start_instant + mp.max_vel_time @@ -426,7 +429,8 @@ def abortMotion(self, curr_instant=None): def isInMotion(self, curr_instant=None): curr_instant = curr_instant or time.time() - #we call getCurrentPosition because inside it updates the current_motion flag + # we call getCurrentPosition because inside it updates the + # current_motion flag self.getCurrentPosition(curr_instant) return self.current_motion is not None @@ -452,7 +456,8 @@ def getCurrentPosition(self, curr_instant=None): pos -= motion.displacement_reach_max_vel pos -= motion.at_max_vel_displacement dt = curr_instant - motion.min_vel_instant - pos += motion.max_vel * dt + 0.5 * motion.decel * pow(dt, 2) + pos += motion.max_vel * dt + \ + 0.5 * motion.decel * pow(dt, 2) elif curr_instant > motion.max_vel_instant: if motion.positive_displacement: pos += motion.displacement_reach_max_vel @@ -462,7 +467,8 @@ def getCurrentPosition(self, curr_instant=None): pos += motion.max_vel * dt else: dt = curr_instant - motion.start_instant - pos += motion.min_vel * dt + 0.5 * motion.accel * pow(dt, 2) + pos += motion.min_vel * dt + \ + 0.5 * motion.accel * pow(dt, 2) else: pos = self.current_position if pos <= self.lower_ls: @@ -545,10 +551,10 @@ def setMinVelocity(self, vi): self.min_vel = vi - #TODO: consult this solution with others + # TODO: consult this solution with others if self.max_vel < self.min_vel: pass - #self.max_vel = self.min_vel (original version) + # self.max_vel = self.min_vel (original version) # force recalculation of accelerations if self.accel_time >= 0: @@ -564,16 +570,16 @@ def setMaxVelocity(self, vf): vf = float(vf) # jmoldes replaced <= by <, because otherwise failed # (check if this is correct) - if vf < 0: + if vf < 0: raise Exception("Maximum velocity must be >= 0") self.max_vel = vf - #TODO: consult this solution with others + # TODO: consult this solution with others if self.min_vel > self.max_vel: pass - #self.min_vel = self.max_vel #accel set to zero (original version) - #self.setMinVelocity(0) another solution could be to set it to 0 + # self.min_vel = self.max_vel #accel set to zero (original version) + # self.setMinVelocity(0) another solution could be to set it to 0 # force recalculation of accelerations if self.accel_time >= 0: @@ -596,8 +602,6 @@ def setAccelerationTime(self, at): except ZeroDivisionError: self.accel = float('inf') self.__recalculate_acc_constants() - - def getAccelerationTime(self): return self.accel_time @@ -655,13 +659,15 @@ def __recalculate_acc_constants(self): if self.accel_time == 0: self.displacement_reach_max_vel = 0.0 else: - self.displacement_reach_max_vel = 0.5 * self.accel * pow(self.accel_time, 2) + self.displacement_reach_max_vel = 0.5 * \ + self.accel * pow(self.accel_time, 2) self.displacement_reach_max_vel += self.min_vel * self.accel_time if self.decel_time == 0: self.displacement_reach_min_vel = 0.0 else: - self.displacement_reach_min_vel = 0.5 * self.decel * pow(self.decel_time, 2) + self.displacement_reach_min_vel = 0.5 * \ + self.decel * pow(self.decel_time, 2) self.displacement_reach_min_vel += self.max_vel * self.decel_time @staticmethod @@ -675,7 +681,7 @@ def fromMotor(motor): decel_time = motor.getDeceleration() return Motor(min_vel=min_vel, max_vel=max_vel, accel_time=accel_time, decel_time=decel_time) - except Exception, e : + except Exception, e: print e return Motor._fromTangoMotor(motor) @@ -692,7 +698,6 @@ def _fromTangoMotor(motor): return Motor(min_vel=v[0], max_vel=v[1], accel_time=v[2], decel_time=v[3]) - class DemoMotor(Motor): def __init__(self): diff --git a/src/sardana/util/test/test_funcgenerator.py b/src/sardana/util/test/test_funcgenerator.py index de3fa149a3..e7880301b4 100644 --- a/src/sardana/util/test/test_funcgenerator.py +++ b/src/sardana/util/test/test_funcgenerator.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -38,7 +38,7 @@ configuration_negative = [{SynchParam.Initial: {SynchDomain.Position: 0.}, SynchParam.Delay: {SynchDomain.Time: 0.1}, SynchParam.Active: {SynchDomain.Position: -.1, - SynchDomain.Time: .01,}, + SynchDomain.Time: .01, }, SynchParam.Total: {SynchDomain.Position: -.2, SynchDomain.Time: 0.1}, SynchParam.Repeats: 10}] @@ -46,11 +46,12 @@ configuration_positive = [{SynchParam.Initial: {SynchDomain.Position: 0.}, SynchParam.Delay: {SynchDomain.Time: 0.3}, SynchParam.Active: {SynchDomain.Position: .1, - SynchDomain.Time: .01,}, + SynchDomain.Time: .01, }, SynchParam.Total: {SynchDomain.Position: .2, SynchDomain.Time: .02}, SynchParam.Repeats: 10}] + class Position(EventGenerator): def __init__(self): @@ -63,6 +64,7 @@ def run(self, start=0, end=2, step=0.01, sleep=0.01): self.fire_event(EventType("Position"), self) time.sleep(sleep) + class Listener(EventReceiver): def __init__(self): @@ -105,10 +107,10 @@ def test_sleep(self): stmt = "fg.sleep(%f)" % i setup = "from sardana.util.funcgenerator import FunctionGenerator;\ fg = FunctionGenerator()" - period = timeit.timeit(stmt, setup , number=1) + period = timeit.timeit(stmt, setup, number=1) period_ok = i msg = "sleep period: %f, expected: %f +/- %f" % (period, period_ok, - delta) + delta) self.assertAlmostEqual(period, period_ok, delta=0.02, msg=msg) def test_run_time(self): @@ -118,9 +120,9 @@ def test_run_time(self): self.thread_pool.add(self.func_generator.run, self._done) self.event.wait(100) active_event_ids = self.listener.active_event_ids - active_event_ids_ok = range(0,10) + active_event_ids_ok = range(0, 10) msg = "Received active event ids: %s, expected: %s" % (active_event_ids, - active_event_ids_ok) + active_event_ids_ok) self.assertListEqual(active_event_ids, active_event_ids_ok, msg) def test_stop_time(self): @@ -152,9 +154,9 @@ def test_run_position_negative(self): self.event.wait(3) position.remove_listener(self.func_generator) active_event_ids = self.listener.active_event_ids - active_event_ids_ok = range(0,10) + active_event_ids_ok = range(0, 10) msg = "Received active event ids: %s, expected: %s" % (active_event_ids, - active_event_ids_ok) + active_event_ids_ok) self.assertListEqual(active_event_ids, active_event_ids_ok, msg) def test_run_position_positive(self): @@ -172,9 +174,9 @@ def test_run_position_positive(self): self.event.wait(3) position.remove_listener(self.func_generator) active_event_ids = self.listener.active_event_ids - active_event_ids_ok = range(0,10) + active_event_ids_ok = range(0, 10) msg = "Received active event ids: %s, expected: %s" % (active_event_ids, - active_event_ids_ok) + active_event_ids_ok) self.assertListEqual(active_event_ids, active_event_ids_ok, msg) def test_configuration_position(self): @@ -205,7 +207,7 @@ def test_configuration_time(self): passive_events = self.func_generator.passive_events passive_events_ok = numpy.arange(.31, 0.51, 0.02).tolist() msg = ("Passive events mismatch, received: %s, expected: %s" % - (passive_events, passive_events_ok)) + (passive_events, passive_events_ok)) for a, b in zip(passive_events, passive_events_ok): self.assertAlmostEqual(a, b, 10, msg) @@ -220,9 +222,9 @@ def test_configuration_default(self): passive_events = self.func_generator.passive_events passive_events_ok = numpy.arange(.31, .51, 0.02).tolist() msg = ("Passive events mismatch, received: %s, expected: %s" % - (passive_events, passive_events_ok)) + (passive_events, passive_events_ok)) for a, b in zip(passive_events, passive_events_ok): self.assertAlmostEqual(a, b, 10, msg) def tearDown(self): - self.func_generator.remove_listener(self.listener) \ No newline at end of file + self.func_generator.remove_listener(self.listener) diff --git a/src/sardana/util/test/test_thread.py b/src/sardana/util/test/test_thread.py index 730ea1eae2..61e45b3721 100644 --- a/src/sardana/util/test/test_thread.py +++ b/src/sardana/util/test/test_thread.py @@ -1,23 +1,23 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.tango-controls.org/static/sardana/latest/doc/html/index.html +# http://www.tango-controls.org/static/sardana/latest/doc/html/index.html ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -28,9 +28,11 @@ from sardana.util.thread import CountLatch from taurus.external.unittest import TestCase + def job(i, duration): time.sleep(duration) + class CountLatchTestCase(TestCase): def test_countlatch(self): diff --git a/src/sardana/util/thread.py b/src/sardana/util/thread.py index 7239ee2e08..2070afbea9 100644 --- a/src/sardana/util/thread.py +++ b/src/sardana/util/thread.py @@ -1,28 +1,29 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## from threading import Condition + class CountLatch(object): """Synchronization primitive with the capacity to count and latch. Counting up latches, while reaching zero when counting down un-latches. diff --git a/src/sardana/util/tree.py b/src/sardana/util/tree.py index 3fdb33ffbe..4db4b918f5 100644 --- a/src/sardana/util/tree.py +++ b/src/sardana/util/tree.py @@ -1,12 +1,14 @@ class BaseNode: """BaseNode, stores reference to data.""" - + def __init__(self, data): self.data = data + class BranchNode(BaseNode): """BranchNode, apart of reference to data, stores a list of children Nodes.""" + def __init__(self, data): BaseNode.__init__(self, data) self.children = [] @@ -14,15 +16,19 @@ def __init__(self, data): def addChild(self, child): self.children.append(child) + class LeafNode(BaseNode): """LeafMode, just stores reference to data.""" + def __init__(self, data): BaseNode.__init__(self, data) + class Tree: """Base tree class, stores reference to root Node object""" + def __init__(self, root): self._root = root - + def root(self): - return self._root \ No newline at end of file + return self._root diff --git a/src/sardana/util/wrap.py b/src/sardana/util/wrap.py index 0bb1bd6857..bf4bccf73f 100644 --- a/src/sardana/util/wrap.py +++ b/src/sardana/util/wrap.py @@ -2,24 +2,24 @@ ############################################################################## ## -## This file is part of Sardana +# This file is part of Sardana ## -## http://www.sardana-controls.org/ +# http://www.sardana-controls.org/ ## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain +# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain ## -## Sardana is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. +# Sardana is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. ## -## Sardana is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. +# Sardana is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. ## -## You should have received a copy of the GNU Lesser General Public License -## along with Sardana. If not, see . +# You should have received a copy of the GNU Lesser General Public License +# along with Sardana. If not, see . ## ############################################################################## @@ -33,6 +33,7 @@ __WRAPPED = "__wrapped__" __WRAPPER = "__wrapper__" + def wraps(wrapped, *args, **kwargs): """A wrap decorator which stores in the returned function a reference to the wrapped function (in member '__wrapped__')""" @@ -41,14 +42,17 @@ def wraps(wrapped, *args, **kwargs): setattr(wrapped, __WRAPPER, weakref.ref(wrapper)) return wrapper + def is_wrapping(wrapper): """Determines if the given callable is a wrapper for another callable""" return hasattr(wrapper, __WRAPPED) + def is_wrapped(wrapped): """Determines if the given callable is being wrapped by another callable""" return hasattr(wrapped, __WRAPPER) + def wrapped(wrapper, recursive=True): """Returns the wrapped function around the given wrapper. If the given callable is not "wrapping" any function, the wrapper itself is returned""" @@ -60,4 +64,3 @@ def wrapped(wrapper, recursive=True): if recursive: return wrapped(_wrapped) return _wrapped - diff --git a/test/HTMLTestRunner.py b/test/HTMLTestRunner.py index 1657091502..b16e553ea7 100644 --- a/test/HTMLTestRunner.py +++ b/test/HTMLTestRunner.py @@ -107,6 +107,7 @@ class OutputRedirector(object): """ Wrapper to redirect stdout or stderr """ + def __init__(self, fp): self.fp = fp @@ -123,7 +124,6 @@ def flush(self): stderr_redirector = OutputRedirector(sys.stderr) - # ---------------------------------------------------------------------- # Template @@ -168,9 +168,9 @@ class Template_mixin(object): """ STATUS = { - 0: 'pass', - 1: 'fail', - 2: 'error', + 0: 'pass', + 1: 'fail', + 2: 'error', } DEFAULT_TITLE = 'Unit Test Report' @@ -274,7 +274,6 @@ class Template_mixin(object): """ # variables: (title, generator, stylesheet, heading, report, ending) - # ------------------------------------------------------------------------ # Stylesheet # @@ -342,8 +341,6 @@ class Template_mixin(object): """ - - # ------------------------------------------------------------------------ # Heading # @@ -354,12 +351,10 @@ class Template_mixin(object):

%(description)s

-""" # variables: (title, parameters, description) +""" # variables: (title, parameters, description) HEADING_ATTRIBUTE_TMPL = """

%(name)s: %(value)s

-""" # variables: (name, value) - - +""" # variables: (name, value) # ------------------------------------------------------------------------ # Report @@ -398,7 +393,7 @@ class Template_mixin(object):   -""" # variables: (test_list, count, Pass, fail, error) +""" # variables: (test_list, count, Pass, fail, error) REPORT_CLASS_TMPL = r""" @@ -409,30 +404,25 @@ class Template_mixin(object): %(error)s Detail -""" # variables: (style, desc, count, Pass, fail, error, cid) - +""" # variables: (style, desc, count, Pass, fail, error, cid) REPORT_TEST_WITH_OUTPUT_TMPL = r"""
%(desc)s
%(status)s%(script)s -""" # variables: (tid, Class, style, desc, status) - +""" # variables: (tid, Class, style, desc, status) REPORT_TEST_NO_OUTPUT_TMPL = r"""
%(desc)s
%(status)s -""" # variables: (tid, Class, style, desc, status) - +""" # variables: (tid, Class, style, desc, status) REPORT_TEST_OUTPUT_TMPL = r""" -""" # variables: (id, output) - - +""" # variables: (id, output) # ------------------------------------------------------------------------ # ENDING @@ -443,10 +433,9 @@ class Template_mixin(object): # -------------------- The end of the Template class ------------------- - def jsEscapeString(s): """ Escape s for use as a Javascript String """ - return s.replace('\\','\\\\') \ + return s.replace('\\', '\\\\') \ .replace('\r', '\\r') \ .replace('\n', '\\n') \ .replace('"', '\\"') \ @@ -455,14 +444,17 @@ def jsEscapeString(s): .replace("<", '\\x3C') \ .replace(">", '\\x3E') # Note: non-ascii unicode characters do not need to be encoded - # Note: previously we encode < as <, etc. However IE6 fail to treat