cgse 2024.7.0__py3-none-any.whl → 2025.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- README.md +27 -0
- bump.py +85 -0
- cgse-2025.0.2.dist-info/METADATA +38 -0
- cgse-2025.0.2.dist-info/RECORD +5 -0
- {cgse-2024.7.0.dist-info → cgse-2025.0.2.dist-info}/WHEEL +1 -2
- cgse-2024.7.0.dist-info/COPYING +0 -674
- cgse-2024.7.0.dist-info/COPYING.LESSER +0 -165
- cgse-2024.7.0.dist-info/METADATA +0 -144
- cgse-2024.7.0.dist-info/RECORD +0 -660
- cgse-2024.7.0.dist-info/entry_points.txt +0 -75
- cgse-2024.7.0.dist-info/top_level.txt +0 -2
- egse/__init__.py +0 -12
- egse/__main__.py +0 -32
- egse/aeu/aeu.py +0 -5238
- egse/aeu/aeu_awg.yaml +0 -265
- egse/aeu/aeu_crio.yaml +0 -273
- egse/aeu/aeu_cs.py +0 -627
- egse/aeu/aeu_devif.py +0 -321
- egse/aeu/aeu_main_ui.py +0 -903
- egse/aeu/aeu_metrics.py +0 -131
- egse/aeu/aeu_protocol.py +0 -463
- egse/aeu/aeu_psu.yaml +0 -204
- egse/aeu/aeu_ui.py +0 -873
- egse/aeu/arbdata/FccdRead.arb +0 -2
- egse/aeu/arbdata/FccdRead_min_points.arb +0 -2
- egse/aeu/arbdata/HeaterSync_FccdRead.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead25.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead31_25.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead37_50.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead43_75.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead50.arb +0 -2
- egse/aeu/arbdata/Heater_FccdRead_min_points.arb +0 -2
- egse/aeu/arbdata/ccdRead25.arb +0 -2
- egse/aeu/arbdata/ccdRead25_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead31_25.arb +0 -2
- egse/aeu/arbdata/ccdRead31_25_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead37_50.arb +0 -2
- egse/aeu/arbdata/ccdRead37_50_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead43_75.arb +0 -2
- egse/aeu/arbdata/ccdRead43_75_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead50.arb +0 -2
- egse/aeu/arbdata/ccdRead50_150ms.arb +0 -2
- egse/alert/__init__.py +0 -1049
- egse/alert/alertman.yaml +0 -37
- egse/alert/alertman_cs.py +0 -233
- egse/alert/alertman_ui.py +0 -600
- egse/alert/gsm/beaglebone.py +0 -138
- egse/alert/gsm/beaglebone.yaml +0 -51
- egse/alert/gsm/beaglebone_cs.py +0 -108
- egse/alert/gsm/beaglebone_devif.py +0 -122
- egse/alert/gsm/beaglebone_protocol.py +0 -46
- egse/bits.py +0 -318
- egse/camera.py +0 -44
- egse/collimator/__init__.py +0 -0
- egse/collimator/fcul/__init__.py +0 -0
- egse/collimator/fcul/ogse.py +0 -1077
- egse/collimator/fcul/ogse.yaml +0 -14
- egse/collimator/fcul/ogse_cs.py +0 -154
- egse/collimator/fcul/ogse_devif.py +0 -358
- egse/collimator/fcul/ogse_protocol.py +0 -132
- egse/collimator/fcul/ogse_sim.py +0 -431
- egse/collimator/fcul/ogse_ui.py +0 -1108
- egse/command.py +0 -699
- egse/config.py +0 -410
- egse/confman/__init__.py +0 -1058
- egse/confman/confman.yaml +0 -70
- egse/confman/confman_cs.py +0 -240
- egse/confman/confman_ui.py +0 -381
- egse/confman/setup_ui.py +0 -565
- egse/control.py +0 -632
- egse/coordinates/__init__.py +0 -534
- egse/coordinates/avoidance.py +0 -100
- egse/coordinates/cslmodel.py +0 -127
- egse/coordinates/laser_tracker_to_dict.py +0 -122
- egse/coordinates/point.py +0 -707
- egse/coordinates/pyplot.py +0 -194
- egse/coordinates/referenceFrame.py +0 -1279
- egse/coordinates/refmodel.py +0 -737
- egse/coordinates/rotationMatrix.py +0 -85
- egse/coordinates/transform3d_addon.py +0 -419
- egse/csl/__init__.py +0 -50
- egse/csl/commanding.py +0 -78
- egse/csl/icons/hexapod-connected-selected.svg +0 -30
- egse/csl/icons/hexapod-connected.svg +0 -30
- egse/csl/icons/hexapod-homing-selected.svg +0 -68
- egse/csl/icons/hexapod-homing.svg +0 -68
- egse/csl/icons/hexapod-retract-selected.svg +0 -56
- egse/csl/icons/hexapod-retract.svg +0 -51
- egse/csl/icons/hexapod-zero-selected.svg +0 -56
- egse/csl/icons/hexapod-zero.svg +0 -56
- egse/csl/icons/logo-puna.svg +0 -92
- egse/csl/icons/stop.svg +0 -1
- egse/csl/initialisation.py +0 -102
- egse/csl/mech_pos_settings.yaml +0 -18
- egse/das.py +0 -1240
- egse/das.yaml +0 -7
- egse/data/conf/SETUP_CSL_00000_170620_150000.yaml +0 -5
- egse/data/conf/SETUP_CSL_00001_170620_151010.yaml +0 -69
- egse/data/conf/SETUP_CSL_00002_170620_151020.yaml +0 -69
- egse/data/conf/SETUP_CSL_00003_170620_151030.yaml +0 -69
- egse/data/conf/SETUP_CSL_00004_170620_151040.yaml +0 -69
- egse/data/conf/SETUP_CSL_00005_170620_151050.yaml +0 -69
- egse/data/conf/SETUP_CSL_00006_170620_151060.yaml +0 -69
- egse/data/conf/SETUP_CSL_00007_170620_151070.yaml +0 -69
- egse/data/conf/SETUP_CSL_00008_170620_151080.yaml +0 -75
- egse/data/conf/SETUP_CSL_00010_210308_083016.yaml +0 -138
- egse/data/conf/SETUP_INTA_00000_170620_150000.yaml +0 -4
- egse/data/conf/SETUP_SRON_00000_170620_150000.yaml +0 -4
- egse/decorators.py +0 -514
- egse/device.py +0 -269
- egse/dpu/__init__.py +0 -2698
- egse/dpu/ccd_ui.py +0 -514
- egse/dpu/dpu.py +0 -783
- egse/dpu/dpu.yaml +0 -153
- egse/dpu/dpu_cs.py +0 -272
- egse/dpu/dpu_ui.py +0 -671
- egse/dpu/fitsgen.py +0 -2096
- egse/dpu/fitsgen_ui.py +0 -399
- egse/dpu/hdf5_model.py +0 -332
- egse/dpu/hdf5_ui.py +0 -277
- egse/dpu/hdf5_viewer.py +0 -506
- egse/dpu/hk_ui.py +0 -468
- egse/dpu_commands.py +0 -81
- egse/dsi/__init__.py +0 -33
- egse/dsi/_libesl.py +0 -232
- egse/dsi/constants.py +0 -296
- egse/dsi/esl.py +0 -630
- egse/dsi/rmap.py +0 -444
- egse/dsi/rmapci.py +0 -39
- egse/dsi/spw.py +0 -335
- egse/dsi/spw_state.py +0 -29
- egse/dummy.py +0 -318
- egse/dyndummy.py +0 -179
- egse/env.py +0 -278
- egse/exceptions.py +0 -88
- egse/fdir/__init__.py +0 -26
- egse/fdir/fdir_manager.py +0 -85
- egse/fdir/fdir_manager.yaml +0 -37
- egse/fdir/fdir_manager_controller.py +0 -136
- egse/fdir/fdir_manager_cs.py +0 -164
- egse/fdir/fdir_manager_interface.py +0 -15
- egse/fdir/fdir_remote.py +0 -73
- egse/fdir/fdir_remote.yaml +0 -30
- egse/fdir/fdir_remote_controller.py +0 -30
- egse/fdir/fdir_remote_cs.py +0 -94
- egse/fdir/fdir_remote_interface.py +0 -9
- egse/fdir/fdir_remote_popup.py +0 -26
- egse/fee/__init__.py +0 -106
- egse/fee/f_fee_register.yaml +0 -43
- egse/fee/feesim.py +0 -914
- egse/fee/n_fee_hk.py +0 -768
- egse/fee/nfee.py +0 -188
- egse/filterwheel/__init__.py +0 -4
- egse/filterwheel/eksma/__init__.py +0 -49
- egse/filterwheel/eksma/fw8smc4.py +0 -657
- egse/filterwheel/eksma/fw8smc4.yaml +0 -121
- egse/filterwheel/eksma/fw8smc4_cs.py +0 -144
- egse/filterwheel/eksma/fw8smc4_devif.py +0 -473
- egse/filterwheel/eksma/fw8smc4_protocol.py +0 -82
- egse/filterwheel/eksma/fw8smc4_ui.py +0 -940
- egse/filterwheel/eksma/fw8smc5.py +0 -115
- egse/filterwheel/eksma/fw8smc5.yaml +0 -105
- egse/filterwheel/eksma/fw8smc5_controller.py +0 -307
- egse/filterwheel/eksma/fw8smc5_cs.py +0 -141
- egse/filterwheel/eksma/fw8smc5_interface.py +0 -65
- egse/filterwheel/eksma/fw8smc5_simulator.py +0 -29
- egse/filterwheel/eksma/fw8smc5_ui.py +0 -1065
- egse/filterwheel/eksma/testpythonfw.py +0 -215
- egse/fov/__init__.py +0 -65
- egse/fov/fov_hk.py +0 -710
- egse/fov/fov_ui.py +0 -859
- egse/fov/fov_ui_controller.py +0 -140
- egse/fov/fov_ui_model.py +0 -200
- egse/fov/fov_ui_view.py +0 -345
- egse/gimbal/__init__.py +0 -32
- egse/gimbal/symetrie/__init__.py +0 -26
- egse/gimbal/symetrie/alpha.py +0 -586
- egse/gimbal/symetrie/generic_gimbal_ui.py +0 -1521
- egse/gimbal/symetrie/gimbal.py +0 -877
- egse/gimbal/symetrie/gimbal.yaml +0 -168
- egse/gimbal/symetrie/gimbal_cs.py +0 -183
- egse/gimbal/symetrie/gimbal_protocol.py +0 -138
- egse/gimbal/symetrie/gimbal_ui.py +0 -361
- egse/gimbal/symetrie/pmac.py +0 -1006
- egse/gimbal/symetrie/pmac_regex.py +0 -83
- egse/graph.py +0 -132
- egse/gui/__init__.py +0 -47
- egse/gui/buttons.py +0 -378
- egse/gui/focalplane.py +0 -1285
- egse/gui/formatter.py +0 -10
- egse/gui/led.py +0 -162
- egse/gui/limitswitch.py +0 -143
- egse/gui/mechanisms.py +0 -587
- egse/gui/states.py +0 -148
- egse/gui/stripchart.py +0 -729
- egse/gui/styles.qss +0 -48
- egse/gui/switch.py +0 -112
- egse/h5.py +0 -274
- egse/help/__init__.py +0 -0
- egse/help/help_ui.py +0 -126
- egse/hexapod/__init__.py +0 -32
- egse/hexapod/symetrie/__init__.py +0 -137
- egse/hexapod/symetrie/alpha.py +0 -874
- egse/hexapod/symetrie/dynalpha.py +0 -1387
- egse/hexapod/symetrie/hexapod_ui.py +0 -1516
- egse/hexapod/symetrie/pmac.py +0 -1010
- egse/hexapod/symetrie/pmac_regex.py +0 -83
- egse/hexapod/symetrie/puna.py +0 -1167
- egse/hexapod/symetrie/puna.yaml +0 -193
- egse/hexapod/symetrie/puna_cs.py +0 -195
- egse/hexapod/symetrie/puna_protocol.py +0 -134
- egse/hexapod/symetrie/puna_ui.py +0 -433
- egse/hexapod/symetrie/punaplus.py +0 -107
- egse/hexapod/symetrie/zonda.py +0 -872
- egse/hexapod/symetrie/zonda.yaml +0 -337
- egse/hexapod/symetrie/zonda_cs.py +0 -172
- egse/hexapod/symetrie/zonda_devif.py +0 -414
- egse/hexapod/symetrie/zonda_protocol.py +0 -123
- egse/hexapod/symetrie/zonda_ui.py +0 -449
- egse/hk.py +0 -791
- egse/icons/aeu-cs-start.svg +0 -117
- egse/icons/aeu-cs-stop.svg +0 -118
- egse/icons/aeu-cs.svg +0 -107
- egse/icons/aeu_cs-started.svg +0 -112
- egse/icons/aeu_cs-stopped.svg +0 -112
- egse/icons/aeu_cs.svg +0 -55
- egse/icons/alert.svg +0 -1
- egse/icons/arrow-double-left.png +0 -0
- egse/icons/arrow-double-right.png +0 -0
- egse/icons/arrow-up.svg +0 -11
- egse/icons/backward.svg +0 -1
- egse/icons/busy.svg +0 -1
- egse/icons/cleaning.svg +0 -115
- egse/icons/color-scheme.svg +0 -1
- egse/icons/cs-connected-alert.svg +0 -91
- egse/icons/cs-connected-disabled.svg +0 -43
- egse/icons/cs-connected.svg +0 -89
- egse/icons/cs-not-connected.svg +0 -44
- egse/icons/double-left-arrow.svg +0 -1
- egse/icons/double-right-arrow.svg +0 -1
- egse/icons/erase-disabled.svg +0 -19
- egse/icons/erase.svg +0 -59
- egse/icons/fitsgen-start.svg +0 -47
- egse/icons/fitsgen-stop.svg +0 -48
- egse/icons/fitsgen.svg +0 -1
- egse/icons/forward.svg +0 -1
- egse/icons/fov-hk-start.svg +0 -33
- egse/icons/fov-hk-stop.svg +0 -37
- egse/icons/fov-hk.svg +0 -1
- egse/icons/front-desk.svg +0 -1
- egse/icons/home-actioned.svg +0 -15
- egse/icons/home-disabled.svg +0 -15
- egse/icons/home.svg +0 -13
- egse/icons/info.svg +0 -1
- egse/icons/invalid.png +0 -0
- egse/icons/led-green.svg +0 -20
- egse/icons/led-grey.svg +0 -20
- egse/icons/led-orange.svg +0 -20
- egse/icons/led-red.svg +0 -20
- egse/icons/led-square-green.svg +0 -134
- egse/icons/led-square-grey.svg +0 -134
- egse/icons/led-square-orange.svg +0 -134
- egse/icons/led-square-red.svg +0 -134
- egse/icons/limit-switch-all-green.svg +0 -115
- egse/icons/limit-switch-all-red.svg +0 -117
- egse/icons/limit-switch-el+.svg +0 -116
- egse/icons/limit-switch-el-.svg +0 -117
- egse/icons/location-marker.svg +0 -1
- egse/icons/logo-dpu.svg +0 -48
- egse/icons/logo-gimbal.svg +0 -112
- egse/icons/logo-huber.svg +0 -23
- egse/icons/logo-ogse.svg +0 -31
- egse/icons/logo-puna.svg +0 -92
- egse/icons/logo-tcs.svg +0 -29
- egse/icons/logo-zonda.svg +0 -66
- egse/icons/maximize.svg +0 -1
- egse/icons/meter.svg +0 -1
- egse/icons/more.svg +0 -45
- egse/icons/n-fee-hk-start.svg +0 -24
- egse/icons/n-fee-hk-stop.svg +0 -25
- egse/icons/n-fee-hk.svg +0 -83
- egse/icons/observing-off.svg +0 -46
- egse/icons/observing-on.svg +0 -46
- egse/icons/open-document-hdf5.png +0 -0
- egse/icons/open-document-hdf5.svg +0 -21
- egse/icons/ops-mode.svg +0 -1
- egse/icons/play-green.svg +0 -17
- egse/icons/plugged-disabled.svg +0 -27
- egse/icons/plugged.svg +0 -21
- egse/icons/pm_ui.svg +0 -1
- egse/icons/power-button-green.svg +0 -27
- egse/icons/power-button-red.svg +0 -27
- egse/icons/power-button.svg +0 -27
- egse/icons/radar.svg +0 -1
- egse/icons/radioactive.svg +0 -2
- egse/icons/reload.svg +0 -1
- egse/icons/remote-control-off.svg +0 -28
- egse/icons/remote-control-on.svg +0 -28
- egse/icons/repeat-blue.svg +0 -15
- egse/icons/repeat.svg +0 -1
- egse/icons/settings.svg +0 -1
- egse/icons/shrink.svg +0 -1
- egse/icons/shutter.svg +0 -1
- egse/icons/sign-off.svg +0 -1
- egse/icons/sign-on.svg +0 -1
- egse/icons/sim-mode.svg +0 -1
- egse/icons/small-buttons-go.svg +0 -20
- egse/icons/small-buttons-minus.svg +0 -51
- egse/icons/small-buttons-plus.svg +0 -51
- egse/icons/sponge.svg +0 -220
- egse/icons/start-button-disabled.svg +0 -84
- egse/icons/start-button.svg +0 -50
- egse/icons/stop-button-disabled.svg +0 -84
- egse/icons/stop-button.svg +0 -50
- egse/icons/stop-red.svg +0 -17
- egse/icons/stop.svg +0 -1
- egse/icons/switch-disabled-square.svg +0 -87
- egse/icons/switch-disabled.svg +0 -15
- egse/icons/switch-off-square.svg +0 -87
- egse/icons/switch-off.svg +0 -72
- egse/icons/switch-on-square.svg +0 -87
- egse/icons/switch-on.svg +0 -61
- egse/icons/temperature-control.svg +0 -44
- egse/icons/th_ui_logo.svg +0 -1
- egse/icons/unplugged.svg +0 -23
- egse/icons/unvalid.png +0 -0
- egse/icons/user-interface.svg +0 -1
- egse/icons/vacuum.svg +0 -1
- egse/icons/valid.png +0 -0
- egse/icons/zoom-to-pixel-dark.svg +0 -64
- egse/icons/zoom-to-pixel-white.svg +0 -36
- egse/images/big-rotation-stage.png +0 -0
- egse/images/connected-100.png +0 -0
- egse/images/cross.svg +0 -6
- egse/images/disconnected-100.png +0 -0
- egse/images/gui-icon.png +0 -0
- egse/images/home.svg +0 -6
- egse/images/info-icon.png +0 -0
- egse/images/led-black.svg +0 -89
- egse/images/led-green.svg +0 -85
- egse/images/led-orange.svg +0 -85
- egse/images/led-red.svg +0 -85
- egse/images/load-icon.png +0 -0
- egse/images/load-setup.png +0 -0
- egse/images/load.png +0 -0
- egse/images/pause.png +0 -0
- egse/images/play-button.svg +0 -8
- egse/images/play.png +0 -0
- egse/images/process-status.png +0 -0
- egse/images/restart.png +0 -0
- egse/images/search.png +0 -0
- egse/images/sma.png +0 -0
- egse/images/start.png +0 -0
- egse/images/stop-button.svg +0 -8
- egse/images/stop.png +0 -0
- egse/images/switch-off.svg +0 -48
- egse/images/switch-on.svg +0 -48
- egse/images/undo.png +0 -0
- egse/images/update-button.svg +0 -11
- egse/imageviewer/exposureselection.py +0 -475
- egse/imageviewer/imageviewer.py +0 -198
- egse/imageviewer/matchfocalplane.py +0 -179
- egse/imageviewer/subfieldposition.py +0 -133
- egse/lampcontrol/__init__.py +0 -4
- egse/lampcontrol/beaglebone/beaglebone.py +0 -178
- egse/lampcontrol/beaglebone/beaglebone.yaml +0 -62
- egse/lampcontrol/beaglebone/beaglebone_cs.py +0 -106
- egse/lampcontrol/beaglebone/beaglebone_devif.py +0 -150
- egse/lampcontrol/beaglebone/beaglebone_protocol.py +0 -73
- egse/lampcontrol/energetiq/__init__.py +0 -22
- egse/lampcontrol/energetiq/eq99.yaml +0 -98
- egse/lampcontrol/energetiq/lampEQ99.py +0 -283
- egse/lampcontrol/energetiq/lampEQ99_cs.py +0 -128
- egse/lampcontrol/energetiq/lampEQ99_devif.py +0 -158
- egse/lampcontrol/energetiq/lampEQ99_encode_decode_errors.py +0 -73
- egse/lampcontrol/energetiq/lampEQ99_protocol.py +0 -71
- egse/lampcontrol/energetiq/lampEQ99_ui.py +0 -465
- egse/lib/CentOS-7/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/CentOS-8/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/CentOS-8/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Debian/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Debian/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Debian/libetherspacelink_v35_21.dylib +0 -0
- egse/lib/Linux/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Linux/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Ubuntu-20/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Ubuntu-20/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/gssw/python3-gssw_2.2.3+31f63c9f-1_all.deb +0 -0
- egse/lib/ximc/__pycache__/pyximc.cpython-38 2.pyc +0 -0
- egse/lib/ximc/__pycache__/pyximc.cpython-38.pyc +0 -0
- egse/lib/ximc/libximc.framework/Frameworks/libbindy.dylib +0 -0
- egse/lib/ximc/libximc.framework/Frameworks/libxiwrapper.dylib +0 -0
- egse/lib/ximc/libximc.framework/Headers/ximc.h +0 -5510
- egse/lib/ximc/libximc.framework/Resources/Info.plist +0 -42
- egse/lib/ximc/libximc.framework/Resources/keyfile.sqlite +0 -0
- egse/lib/ximc/libximc.framework/libbindy.so +0 -0
- egse/lib/ximc/libximc.framework/libximc +0 -0
- egse/lib/ximc/libximc.framework/libximc.so +0 -0
- egse/lib/ximc/libximc.framework/libximc.so.7.0.0 +0 -0
- egse/lib/ximc/libximc.framework/libxiwrapper.so +0 -0
- egse/lib/ximc/pyximc.py +0 -922
- egse/listener.py +0 -179
- egse/logger/__init__.py +0 -243
- egse/logger/log_cs.py +0 -321
- egse/metrics.py +0 -102
- egse/mixin.py +0 -464
- egse/monitoring.py +0 -95
- egse/ni/alarms/__init__.py +0 -26
- egse/ni/alarms/cdaq9375.py +0 -300
- egse/ni/alarms/cdaq9375.yaml +0 -89
- egse/ni/alarms/cdaq9375_cs.py +0 -130
- egse/ni/alarms/cdaq9375_devif.py +0 -183
- egse/ni/alarms/cdaq9375_protocol.py +0 -48
- egse/obs_inspection.py +0 -165
- egse/observer.py +0 -41
- egse/obsid.py +0 -163
- egse/powermeter/__init__.py +0 -0
- egse/powermeter/ni/__init__.py +0 -38
- egse/powermeter/ni/cdaq9184.py +0 -224
- egse/powermeter/ni/cdaq9184.yaml +0 -73
- egse/powermeter/ni/cdaq9184_cs.py +0 -130
- egse/powermeter/ni/cdaq9184_devif.py +0 -201
- egse/powermeter/ni/cdaq9184_protocol.py +0 -48
- egse/powermeter/ni/cdaq9184_ui.py +0 -544
- egse/powermeter/thorlabs/__init__.py +0 -25
- egse/powermeter/thorlabs/pm100a.py +0 -380
- egse/powermeter/thorlabs/pm100a.yaml +0 -132
- egse/powermeter/thorlabs/pm100a_cs.py +0 -136
- egse/powermeter/thorlabs/pm100a_devif.py +0 -127
- egse/powermeter/thorlabs/pm100a_protocol.py +0 -80
- egse/powermeter/thorlabs/pm100a_ui.py +0 -725
- egse/process.py +0 -451
- egse/procman/__init__.py +0 -834
- egse/procman/cannot_start_process_popup.py +0 -43
- egse/procman/procman.yaml +0 -49
- egse/procman/procman_cs.py +0 -201
- egse/procman/procman_ui.py +0 -2081
- egse/protocol.py +0 -605
- egse/proxy.py +0 -531
- egse/randomwalk.py +0 -140
- egse/reg.py +0 -585
- egse/reload.py +0 -122
- egse/reprocess.py +0 -693
- egse/resource.py +0 -333
- egse/rmap.py +0 -406
- egse/rst.py +0 -135
- egse/search.py +0 -182
- egse/serialdevice.py +0 -190
- egse/services.py +0 -247
- egse/services.yaml +0 -68
- egse/settings.py +0 -379
- egse/settings.yaml +0 -980
- egse/setup.py +0 -1181
- egse/shutter/__init__.py +0 -0
- egse/shutter/thorlabs/__init__.py +0 -19
- egse/shutter/thorlabs/ksc101.py +0 -205
- egse/shutter/thorlabs/ksc101.yaml +0 -105
- egse/shutter/thorlabs/ksc101_cs.py +0 -136
- egse/shutter/thorlabs/ksc101_devif.py +0 -201
- egse/shutter/thorlabs/ksc101_protocol.py +0 -71
- egse/shutter/thorlabs/ksc101_ui.py +0 -548
- egse/shutter/thorlabs/sc10.py +0 -82
- egse/shutter/thorlabs/sc10.yaml +0 -52
- egse/shutter/thorlabs/sc10_controller.py +0 -81
- egse/shutter/thorlabs/sc10_cs.py +0 -108
- egse/shutter/thorlabs/sc10_interface.py +0 -25
- egse/shutter/thorlabs/sc10_simulator.py +0 -30
- egse/simulator.py +0 -41
- egse/slack.py +0 -61
- egse/socketdevice.py +0 -218
- egse/sockets.py +0 -218
- egse/spw.py +0 -1401
- egse/stages/__init__.py +0 -12
- egse/stages/aerotech/ensemble.py +0 -245
- egse/stages/aerotech/ensemble.yaml +0 -205
- egse/stages/aerotech/ensemble_controller.py +0 -275
- egse/stages/aerotech/ensemble_cs.py +0 -110
- egse/stages/aerotech/ensemble_interface.py +0 -132
- egse/stages/aerotech/ensemble_parameters.py +0 -433
- egse/stages/aerotech/ensemble_simulator.py +0 -27
- egse/stages/aerotech/mgse_sim.py +0 -188
- egse/stages/arun/smd3.py +0 -110
- egse/stages/arun/smd3.yaml +0 -68
- egse/stages/arun/smd3_controller.py +0 -470
- egse/stages/arun/smd3_cs.py +0 -112
- egse/stages/arun/smd3_interface.py +0 -53
- egse/stages/arun/smd3_simulator.py +0 -27
- egse/stages/arun/smd3_stop.py +0 -16
- egse/stages/huber/__init__.py +0 -49
- egse/stages/huber/smc9300.py +0 -920
- egse/stages/huber/smc9300.yaml +0 -63
- egse/stages/huber/smc9300_cs.py +0 -178
- egse/stages/huber/smc9300_devif.py +0 -345
- egse/stages/huber/smc9300_protocol.py +0 -113
- egse/stages/huber/smc9300_sim.py +0 -547
- egse/stages/huber/smc9300_ui.py +0 -973
- egse/state.py +0 -173
- egse/statemachine.py +0 -274
- egse/storage/__init__.py +0 -1067
- egse/storage/persistence.py +0 -2295
- egse/storage/storage.yaml +0 -79
- egse/storage/storage_cs.py +0 -231
- egse/styles/dark.qss +0 -343
- egse/styles/default.qss +0 -48
- egse/synoptics/__init__.py +0 -417
- egse/synoptics/syn.yaml +0 -9
- egse/synoptics/syn_cs.py +0 -195
- egse/system.py +0 -1611
- egse/tcs/__init__.py +0 -14
- egse/tcs/tcs.py +0 -879
- egse/tcs/tcs.yaml +0 -14
- egse/tcs/tcs_cs.py +0 -202
- egse/tcs/tcs_devif.py +0 -292
- egse/tcs/tcs_protocol.py +0 -180
- egse/tcs/tcs_sim.py +0 -177
- egse/tcs/tcs_ui.py +0 -543
- egse/tdms.py +0 -171
- egse/tempcontrol/__init__.py +0 -23
- egse/tempcontrol/agilent/agilent34970.py +0 -109
- egse/tempcontrol/agilent/agilent34970.yaml +0 -44
- egse/tempcontrol/agilent/agilent34970_cs.py +0 -114
- egse/tempcontrol/agilent/agilent34970_devif.py +0 -182
- egse/tempcontrol/agilent/agilent34970_protocol.py +0 -96
- egse/tempcontrol/agilent/agilent34972.py +0 -111
- egse/tempcontrol/agilent/agilent34972.yaml +0 -44
- egse/tempcontrol/agilent/agilent34972_cs.py +0 -115
- egse/tempcontrol/agilent/agilent34972_devif.py +0 -189
- egse/tempcontrol/agilent/agilent34972_protocol.py +0 -98
- egse/tempcontrol/beaglebone/beaglebone.py +0 -341
- egse/tempcontrol/beaglebone/beaglebone.yaml +0 -110
- egse/tempcontrol/beaglebone/beaglebone_cs.py +0 -117
- egse/tempcontrol/beaglebone/beaglebone_protocol.py +0 -134
- egse/tempcontrol/beaglebone/beaglebone_ui.py +0 -674
- egse/tempcontrol/digalox/digalox.py +0 -115
- egse/tempcontrol/digalox/digalox.yaml +0 -36
- egse/tempcontrol/digalox/digalox_cs.py +0 -108
- egse/tempcontrol/digalox/digalox_protocol.py +0 -56
- egse/tempcontrol/keithley/__init__.py +0 -33
- egse/tempcontrol/keithley/daq6510.py +0 -662
- egse/tempcontrol/keithley/daq6510.yaml +0 -105
- egse/tempcontrol/keithley/daq6510_cs.py +0 -163
- egse/tempcontrol/keithley/daq6510_devif.py +0 -343
- egse/tempcontrol/keithley/daq6510_protocol.py +0 -79
- egse/tempcontrol/keithley/daq6510_sim.py +0 -186
- egse/tempcontrol/lakeshore/__init__.py +0 -33
- egse/tempcontrol/lakeshore/lsci.py +0 -361
- egse/tempcontrol/lakeshore/lsci.yaml +0 -162
- egse/tempcontrol/lakeshore/lsci_cs.py +0 -174
- egse/tempcontrol/lakeshore/lsci_devif.py +0 -292
- egse/tempcontrol/lakeshore/lsci_protocol.py +0 -76
- egse/tempcontrol/lakeshore/lsci_ui.py +0 -387
- egse/tempcontrol/ni/__init__.py +0 -0
- egse/tempcontrol/spid/spid.py +0 -109
- egse/tempcontrol/spid/spid.yaml +0 -81
- egse/tempcontrol/spid/spid_controller.py +0 -279
- egse/tempcontrol/spid/spid_cs.py +0 -136
- egse/tempcontrol/spid/spid_protocol.py +0 -107
- egse/tempcontrol/spid/spid_ui.py +0 -723
- egse/tempcontrol/srs/__init__.py +0 -22
- egse/tempcontrol/srs/ptc10.py +0 -867
- egse/tempcontrol/srs/ptc10.yaml +0 -227
- egse/tempcontrol/srs/ptc10_cs.py +0 -128
- egse/tempcontrol/srs/ptc10_devif.py +0 -116
- egse/tempcontrol/srs/ptc10_protocol.py +0 -39
- egse/tempcontrol/srs/ptc10_ui.py +0 -906
- egse/ups/apc/apc.py +0 -236
- egse/ups/apc/apc.yaml +0 -45
- egse/ups/apc/apc_cs.py +0 -101
- egse/ups/apc/apc_protocol.py +0 -125
- egse/user.yaml +0 -7
- egse/vacuum/beaglebone/beaglebone.py +0 -149
- egse/vacuum/beaglebone/beaglebone.yaml +0 -44
- egse/vacuum/beaglebone/beaglebone_cs.py +0 -108
- egse/vacuum/beaglebone/beaglebone_devif.py +0 -159
- egse/vacuum/beaglebone/beaglebone_protocol.py +0 -192
- egse/vacuum/beaglebone/beaglebone_ui.py +0 -638
- egse/vacuum/instrutech/igm402.py +0 -91
- egse/vacuum/instrutech/igm402.yaml +0 -90
- egse/vacuum/instrutech/igm402_controller.py +0 -124
- egse/vacuum/instrutech/igm402_cs.py +0 -108
- egse/vacuum/instrutech/igm402_interface.py +0 -49
- egse/vacuum/instrutech/igm402_simulator.py +0 -36
- egse/vacuum/keller/kellerBus.py +0 -256
- egse/vacuum/keller/leo3.py +0 -100
- egse/vacuum/keller/leo3.yaml +0 -38
- egse/vacuum/keller/leo3_controller.py +0 -81
- egse/vacuum/keller/leo3_cs.py +0 -101
- egse/vacuum/keller/leo3_interface.py +0 -33
- egse/vacuum/mks/evision.py +0 -86
- egse/vacuum/mks/evision.yaml +0 -75
- egse/vacuum/mks/evision_cs.py +0 -101
- egse/vacuum/mks/evision_devif.py +0 -313
- egse/vacuum/mks/evision_interface.py +0 -60
- egse/vacuum/mks/evision_simulator.py +0 -24
- egse/vacuum/mks/evision_ui.py +0 -701
- egse/vacuum/pfeiffer/acp40.py +0 -87
- egse/vacuum/pfeiffer/acp40.yaml +0 -60
- egse/vacuum/pfeiffer/acp40_controller.py +0 -117
- egse/vacuum/pfeiffer/acp40_cs.py +0 -109
- egse/vacuum/pfeiffer/acp40_interface.py +0 -40
- egse/vacuum/pfeiffer/acp40_simulator.py +0 -37
- egse/vacuum/pfeiffer/tc400.py +0 -87
- egse/vacuum/pfeiffer/tc400.yaml +0 -83
- egse/vacuum/pfeiffer/tc400_controller.py +0 -136
- egse/vacuum/pfeiffer/tc400_cs.py +0 -109
- egse/vacuum/pfeiffer/tc400_interface.py +0 -70
- egse/vacuum/pfeiffer/tc400_simulator.py +0 -35
- egse/vacuum/pfeiffer/tpg261.py +0 -80
- egse/vacuum/pfeiffer/tpg261.yaml +0 -66
- egse/vacuum/pfeiffer/tpg261_controller.py +0 -150
- egse/vacuum/pfeiffer/tpg261_cs.py +0 -109
- egse/vacuum/pfeiffer/tpg261_interface.py +0 -59
- egse/vacuum/pfeiffer/tpg261_simulator.py +0 -23
- egse/version.py +0 -174
- egse/visitedpositions.py +0 -398
- egse/windowing.py +0 -213
- egse/zmq/__init__.py +0 -28
- egse/zmq/spw.py +0 -160
- egse/zmq_ser.py +0 -41
- scripts/alerts/cold.yaml +0 -278
- scripts/alerts/example_alerts.yaml +0 -54
- scripts/alerts/transition.yaml +0 -14
- scripts/alerts/warm.yaml +0 -49
- scripts/analyse_n_fee_hk_data.py +0 -52
- scripts/check_hdf5_files.py +0 -192
- scripts/check_register_sync.py +0 -47
- scripts/check_tcs_calib_coef.py +0 -90
- scripts/correct_ccd_cold_temperature_cal.py +0 -157
- scripts/create_hdf5_report.py +0 -293
- scripts/csl_model.py +0 -420
- scripts/csl_restore_setup.py +0 -229
- scripts/export-grafana-dashboards.py +0 -49
- scripts/fdir/cs_recovery/fdir_cs_recovery.py +0 -54
- scripts/fdir/fdir_table.yaml +0 -70
- scripts/fdir/fdir_test_recovery.py +0 -10
- scripts/fdir/hw_recovery/fdir_agilent_hw_recovery.py +0 -73
- scripts/fdir/limit_recovery/fdir_agilent_limit.py +0 -61
- scripts/fdir/limit_recovery/fdir_bb_heater_limit.py +0 -59
- scripts/fdir/limit_recovery/fdir_ensemble_limit.py +0 -33
- scripts/fdir/limit_recovery/fdir_pressure_limit_recovery.py +0 -71
- scripts/fix_csv.py +0 -80
- scripts/ias/correct_ccd_temp_cal_elfique.py +0 -43
- scripts/ias/correct_ccd_temp_cal_floreffe.py +0 -43
- scripts/ias/correct_trp_swap_achel.py +0 -199
- scripts/inta/correct_ccd_temp_cal_duvel.py +0 -43
- scripts/inta/correct_ccd_temp_cal_gueuze.py +0 -43
- scripts/n_fee_supply_voltage_calculation.py +0 -92
- scripts/playground.py +0 -30
- scripts/print_hdf5_hk_data.py +0 -68
- scripts/print_register_map.py +0 -43
- scripts/remove_lines_between_matches.py +0 -188
- scripts/sron/commanding/control_heaters.py +0 -44
- scripts/sron/commanding/pumpdown.py +0 -46
- scripts/sron/commanding/set_pid_setpoint.py +0 -19
- scripts/sron/commanding/shutdown_bbb_heaters.py +0 -10
- scripts/sron/commanding/shutdown_pumps.py +0 -33
- scripts/sron/correct_mgse_coordinates_brigand_chimay.py +0 -272
- scripts/sron/correct_trp_swap_brigand.py +0 -204
- scripts/sron/gimbal_conversions.py +0 -75
- scripts/sron/tm_gen/tm_gen_agilent.py +0 -37
- scripts/sron/tm_gen/tm_gen_heaters.py +0 -4
- scripts/sron/tm_gen/tm_gen_spid.py +0 -13
- scripts/update_operational_cgse.py +0 -268
- scripts/update_operational_cgse_old.py +0 -273
egse/fov/fov_ui.py
DELETED
|
@@ -1,859 +0,0 @@
|
|
|
1
|
-
import pickle
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
import sys
|
|
5
|
-
import zmq
|
|
6
|
-
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QThread, QLockFile
|
|
7
|
-
from PyQt5.QtGui import QCloseEvent, QFont, QIcon
|
|
8
|
-
from PyQt5.QtWidgets import QMainWindow, QLabel, QFrame, QHBoxLayout, QGridLayout, QVBoxLayout, QApplication, QAction, \
|
|
9
|
-
QWidget, QSizePolicy, QMessageBox
|
|
10
|
-
from math import tan, radians
|
|
11
|
-
|
|
12
|
-
from egse import coordinates
|
|
13
|
-
from egse.config import find_file
|
|
14
|
-
from egse.control import is_control_server_active
|
|
15
|
-
from egse.coordinates import focal_plane_to_ccd_coordinates
|
|
16
|
-
from egse.gui import VLine
|
|
17
|
-
from egse.gui.focalplane import FocalPlaneWidgetWithSourcePosition
|
|
18
|
-
from egse.gui.mechanisms import ScanMirrorAssemblyWidget, BigRotationStageWidget, FocusPositionWidget
|
|
19
|
-
from egse.help.help_ui import HelpWindow, HELP_TOPICS
|
|
20
|
-
from egse.observer import Observer, Observable
|
|
21
|
-
from egse.resource import get_resource
|
|
22
|
-
from egse.settings import Settings
|
|
23
|
-
from egse.setup import load_setup
|
|
24
|
-
from egse.zmq_ser import connect_address
|
|
25
|
-
|
|
26
|
-
FONT = QFont("Helvetica", 18)
|
|
27
|
-
|
|
28
|
-
STAGES_SETTINGS = Settings.load("Huber Control Server")
|
|
29
|
-
HEXAPOD_SETTINGS = Settings.load("Hexapod PUNA Control Server")
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class MonitoringWorker(QObject):
|
|
33
|
-
|
|
34
|
-
def __init__(self, settings):
|
|
35
|
-
""" Initialisation of a monitoring worker.
|
|
36
|
-
|
|
37
|
-
This monitoring worker will listen on the monitoring port of the Control Server, based on the given settings.
|
|
38
|
-
|
|
39
|
-
Args:
|
|
40
|
-
- settings: Settings with the connection information (which was loaded from the settings file).
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
super(MonitoringWorker, self).__init__()
|
|
44
|
-
|
|
45
|
-
self.active = False
|
|
46
|
-
|
|
47
|
-
self.monitoring_socket = None
|
|
48
|
-
self.monitoring_timeout = 0.5 # [s]
|
|
49
|
-
self.commanding_address = None
|
|
50
|
-
self.is_socket_connected = False
|
|
51
|
-
|
|
52
|
-
self.connect_socket(settings)
|
|
53
|
-
|
|
54
|
-
def connect_socket(self, settings):
|
|
55
|
-
""" Create a socket and connect to the monitoring port.
|
|
56
|
-
|
|
57
|
-
Args:
|
|
58
|
-
- settings: Settings with the connection information (which was loaded from the settings file).
|
|
59
|
-
"""
|
|
60
|
-
|
|
61
|
-
try:
|
|
62
|
-
|
|
63
|
-
# Ctrl settings:
|
|
64
|
-
# - transport protocol
|
|
65
|
-
# - hostname
|
|
66
|
-
# - commanding port (to check whether the CS is active)
|
|
67
|
-
# - monitoring port (to ask for process information)
|
|
68
|
-
|
|
69
|
-
transport = settings.PROTOCOL
|
|
70
|
-
hostname = settings.HOSTNAME
|
|
71
|
-
commanding_port = settings.COMMANDING_PORT
|
|
72
|
-
monitoring_port = settings.MONITORING_PORT
|
|
73
|
-
|
|
74
|
-
# Create a socket and connect to the monitoring port
|
|
75
|
-
|
|
76
|
-
monitoring_address = connect_address(transport, hostname, monitoring_port)
|
|
77
|
-
self.monitoring_socket = zmq.Context().socket(zmq.SUB)
|
|
78
|
-
self.monitoring_socket.connect(monitoring_address)
|
|
79
|
-
self.monitoring_socket.setsockopt_string(zmq.SUBSCRIBE, "")
|
|
80
|
-
|
|
81
|
-
# Address of the commanding port
|
|
82
|
-
# This is needed when checking whether or not the CS is active
|
|
83
|
-
|
|
84
|
-
self.commanding_address = connect_address(transport, hostname, commanding_port)
|
|
85
|
-
|
|
86
|
-
self.is_socket_connected = True
|
|
87
|
-
|
|
88
|
-
except AttributeError:
|
|
89
|
-
|
|
90
|
-
self.is_socket_connected = False
|
|
91
|
-
|
|
92
|
-
def stop(self):
|
|
93
|
-
""" Stop the monitoring worker.
|
|
94
|
-
|
|
95
|
-
The monitoring socket is disconnected from the monitoring port and is then closed immediately.
|
|
96
|
-
"""
|
|
97
|
-
|
|
98
|
-
self.is_socket_connected = False
|
|
99
|
-
self.monitoring_socket.close()
|
|
100
|
-
|
|
101
|
-
# self.monitoring_socket.disconnect(self.monitoring_address)
|
|
102
|
-
# self.monitoring_socket.close(linger=0)
|
|
103
|
-
|
|
104
|
-
def start_process(self):
|
|
105
|
-
""" Start listening on the monitoring port.
|
|
106
|
-
|
|
107
|
-
If the Control Server is not active when the thread starts listening on the monitoring port, a signal is emitted
|
|
108
|
-
to notify the GUI.
|
|
109
|
-
"""
|
|
110
|
-
|
|
111
|
-
self.run()
|
|
112
|
-
|
|
113
|
-
# @pyqtSlot()
|
|
114
|
-
def run(self):
|
|
115
|
-
|
|
116
|
-
raise NotImplementedError
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
class StagesMonitoringWorker(MonitoringWorker):
|
|
120
|
-
""" Worker for monitoring the position of the stages."""
|
|
121
|
-
|
|
122
|
-
# The worker will send a signal with three floats and one dictionaries:
|
|
123
|
-
# The floats will be:
|
|
124
|
-
# - Commanded position of the big rotation stage [degrees]
|
|
125
|
-
# - Commanded position of the small rotation stage [degrees]
|
|
126
|
-
# - Commanded position of the translation stage [mm]
|
|
127
|
-
# The dictionary will have the following entries:
|
|
128
|
-
# - "angles": Tuple with the field angles (theta, phi) [degrees]
|
|
129
|
-
# - "pixels": Tuple with the CCD coordinates (row, column) [pixels] and the CCD code
|
|
130
|
-
# - "mm": Tuple with the focal-plane coordinates (x, y) [pixels]
|
|
131
|
-
|
|
132
|
-
stages_position_signal = pyqtSignal(float, float, float, dict)
|
|
133
|
-
|
|
134
|
-
def __init__(self):
|
|
135
|
-
""" Initialisation of a monitoring worker for the stages.
|
|
136
|
-
|
|
137
|
-
This monitoring worker will listen on the monitoring port of the Huber Control Server.
|
|
138
|
-
"""
|
|
139
|
-
|
|
140
|
-
super(StagesMonitoringWorker, self).__init__(STAGES_SETTINGS)
|
|
141
|
-
|
|
142
|
-
# When new monitoring information comes in, these variables will contain the previous values for the position
|
|
143
|
-
# of the stages (as currently displayed in the GUI). Once we have checked whether changes have occurred since
|
|
144
|
-
# the last time monitoring information was received, these values will be overwritten by the new ones.
|
|
145
|
-
|
|
146
|
-
self.position_big_rotation_stage = None
|
|
147
|
-
self.position_small_rotation_stage = None
|
|
148
|
-
self.position_translation_stage = None
|
|
149
|
-
|
|
150
|
-
# Information from the setup
|
|
151
|
-
|
|
152
|
-
setup = load_setup()
|
|
153
|
-
|
|
154
|
-
self.focal_length = setup.camera.fov.focal_length_mm
|
|
155
|
-
self.offset_alpha = setup.gse.stages.calibration.offset_alpha
|
|
156
|
-
self.offset_phi = setup.gse.stages.calibration.offset_phi
|
|
157
|
-
self.offset_delta_x = setup.gse.stages.calibration.offset_delta_x
|
|
158
|
-
self.alpha_correction_coefficients = setup.gse.stages.calibration.alpha_correction_coefficients
|
|
159
|
-
self.phi_correction_coefficients = setup.gse.stages.calibration.phi_correction_coefficients
|
|
160
|
-
|
|
161
|
-
self.distortion_coefficients = setup.camera.fov.distortion_coefficients
|
|
162
|
-
self.height_collimated_beam = setup.gse.stages.calibration.height_collimated_beam
|
|
163
|
-
|
|
164
|
-
@pyqtSlot()
|
|
165
|
-
def run(self):
|
|
166
|
-
""" Keep on listening on the monitoring port of the stages.
|
|
167
|
-
|
|
168
|
-
If monitoring information is received before the timeout, a signal with the monitoring information is emitted.
|
|
169
|
-
Otherwise, it is checked whether or not the Control Server is active. If not, a signal is emitted with the
|
|
170
|
-
process name. Otherwise, the timeout for monitoring was too strict (and it will therefore be increased by
|
|
171
|
-
0.5s).
|
|
172
|
-
"""
|
|
173
|
-
|
|
174
|
-
self.active = True
|
|
175
|
-
|
|
176
|
-
while self.is_socket_connected and self.active:
|
|
177
|
-
|
|
178
|
-
try:
|
|
179
|
-
|
|
180
|
-
socket_list, _, _ = zmq.select([self.monitoring_socket], [], [], timeout=self.monitoring_timeout)
|
|
181
|
-
|
|
182
|
-
# Monitoring information was received (before timeout)
|
|
183
|
-
|
|
184
|
-
if self.monitoring_socket in socket_list:
|
|
185
|
-
|
|
186
|
-
pickle_string = self.monitoring_socket.recv()
|
|
187
|
-
monitoring_info = pickle.loads(pickle_string)
|
|
188
|
-
|
|
189
|
-
# Update the timeout, to be more in line with the monitoring frequency of the CS (i.e. the delay).
|
|
190
|
-
# Take 0.5s extra to be on the safe side.
|
|
191
|
-
|
|
192
|
-
self.monitoring_timeout = monitoring_info["delay"] / 1000.0 + 0.5 # [s]
|
|
193
|
-
|
|
194
|
-
if self.position_has_changed(monitoring_info):
|
|
195
|
-
|
|
196
|
-
self.stages_position_signal.emit(self.position_big_rotation_stage,
|
|
197
|
-
self.position_small_rotation_stage,
|
|
198
|
-
self.position_translation_stage,
|
|
199
|
-
self.get_position())
|
|
200
|
-
|
|
201
|
-
except zmq.ZMQError:
|
|
202
|
-
|
|
203
|
-
pass
|
|
204
|
-
|
|
205
|
-
# Timeout occurred
|
|
206
|
-
|
|
207
|
-
else:
|
|
208
|
-
|
|
209
|
-
# The CS is not active
|
|
210
|
-
|
|
211
|
-
if not is_control_server_active(self.commanding_address):
|
|
212
|
-
|
|
213
|
-
# TODO
|
|
214
|
-
pass
|
|
215
|
-
|
|
216
|
-
# The CS is active, but the timeout was too strict
|
|
217
|
-
|
|
218
|
-
else:
|
|
219
|
-
|
|
220
|
-
self.monitoring_timeout += 0.5
|
|
221
|
-
|
|
222
|
-
def position_has_changed(self, monitoring_info: dict):
|
|
223
|
-
""" Check whether the position of at least one of the stages has changed.
|
|
224
|
-
|
|
225
|
-
Check whether the position of at least one of the changes has changed since the previous time monitoring
|
|
226
|
-
information was received.
|
|
227
|
-
|
|
228
|
-
If the position of the stages has changed, the previous values are updated.
|
|
229
|
-
|
|
230
|
-
Args:
|
|
231
|
-
- monitoring_info: Monitoring information for the stages.
|
|
232
|
-
|
|
233
|
-
Returns: True if the position of at least one of the stages has changed; False otherwise.
|
|
234
|
-
"""
|
|
235
|
-
|
|
236
|
-
position_has_changed = False
|
|
237
|
-
|
|
238
|
-
# Big rotation stage
|
|
239
|
-
|
|
240
|
-
position_big_rotation_stage = monitoring_info["big_rotation_stage_position"]
|
|
241
|
-
|
|
242
|
-
if position_big_rotation_stage != self.position_big_rotation_stage:
|
|
243
|
-
|
|
244
|
-
self.position_big_rotation_stage = position_big_rotation_stage
|
|
245
|
-
position_has_changed = True
|
|
246
|
-
|
|
247
|
-
# Small rotation stage
|
|
248
|
-
|
|
249
|
-
position_small_rotation_stage = monitoring_info["small_rotation_stage_position"]
|
|
250
|
-
|
|
251
|
-
if position_small_rotation_stage != self.position_small_rotation_stage:
|
|
252
|
-
|
|
253
|
-
self.position_small_rotation_stage = position_small_rotation_stage
|
|
254
|
-
position_has_changed = True
|
|
255
|
-
|
|
256
|
-
# Translation stage
|
|
257
|
-
|
|
258
|
-
position_translation_stage = monitoring_info["translation_stage_position"]
|
|
259
|
-
|
|
260
|
-
if position_translation_stage != self.position_translation_stage:
|
|
261
|
-
|
|
262
|
-
self.position_translation_stage = position_translation_stage
|
|
263
|
-
position_has_changed = True
|
|
264
|
-
|
|
265
|
-
return position_has_changed
|
|
266
|
-
|
|
267
|
-
def get_position(self):
|
|
268
|
-
""" Calculates the coordinate of the source.
|
|
269
|
-
|
|
270
|
-
Calculates the coordinate of the source, given the position of the associated hexapod and stages, and taking
|
|
271
|
-
the field distortion into account.
|
|
272
|
-
|
|
273
|
-
:return: Dictionary with the following entries:
|
|
274
|
-
- "angles": gnomonic distance from the optical axis and in-field angle [degrees]
|
|
275
|
-
- "pixels": CCD coordinates (row, column) [pixels] and the corresponding CCD code
|
|
276
|
-
- "mm": focal-plane coordinates (x, y) [mm]
|
|
277
|
-
"""
|
|
278
|
-
|
|
279
|
-
# TODO Check whether the light beam passes through the entrance pupil
|
|
280
|
-
|
|
281
|
-
# Gnomonic distance to optical axis and in-field angle [degrees]
|
|
282
|
-
|
|
283
|
-
theta = (self.position_small_rotation_stage + self.offset_alpha - self.alpha_correction_coefficients[0]) \
|
|
284
|
-
/ self.alpha_correction_coefficients[1]
|
|
285
|
-
|
|
286
|
-
phi_correction = self.phi_correction_coefficients[1] * theta + self.phi_correction_coefficients[0]
|
|
287
|
-
phi = -self.position_big_rotation_stage - self.offset_phi - phi_correction
|
|
288
|
-
|
|
289
|
-
# Focal-plane coordinates [mm]
|
|
290
|
-
|
|
291
|
-
x, y = coordinates.angles_to_focal_plane_coordinates(theta, phi)
|
|
292
|
-
|
|
293
|
-
# CCD coordinates [pixels]
|
|
294
|
-
|
|
295
|
-
(row, column, ccd_code) = focal_plane_to_ccd_coordinates(x, y, setup)
|
|
296
|
-
|
|
297
|
-
position = {
|
|
298
|
-
"angles": (theta, phi),
|
|
299
|
-
"pixels": (row, column, ccd_code),
|
|
300
|
-
"mm": (x, y)
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return position
|
|
304
|
-
|
|
305
|
-
def light_beam_through_entrance_pupil(self):
|
|
306
|
-
""" Check whether the light beam goes through the entrance pupil.
|
|
307
|
-
|
|
308
|
-
Returns: True of the light beam passes through the entrance pupil; False otherwise.
|
|
309
|
-
"""
|
|
310
|
-
|
|
311
|
-
distance_sma = -self.position_translation_stage + self.offset_delta_x
|
|
312
|
-
|
|
313
|
-
return distance_sma / self.height_collimated_beam == \
|
|
314
|
-
tan(radians(self.position_small_rotation_stage + self.offset_alpha + 45))
|
|
315
|
-
|
|
316
|
-
# def get_focal_plane_position(self):
|
|
317
|
-
#
|
|
318
|
-
# """
|
|
319
|
-
# Calculates and returns the focal-plane coordinates (x, y) [mm] of the source, given the
|
|
320
|
-
# position of the associated hexapod and stages, and taking the field distortion into account.
|
|
321
|
-
#
|
|
322
|
-
# :return: Focal-plane coordinates (x, y) [mm] of the source, given the position of the
|
|
323
|
-
# associated hexapod and stages, and taking the field distortion into account.
|
|
324
|
-
# """
|
|
325
|
-
#
|
|
326
|
-
# angle_big_rotation_stage = self.position_big_rotation_stage
|
|
327
|
-
|
|
328
|
-
# # Rotation angle of the big rotation stage [degrees]
|
|
329
|
-
# # - counterclockwise rotation
|
|
330
|
-
# # - 0° -> axis of the focal plane aligned with GL_FIX
|
|
331
|
-
#
|
|
332
|
-
# angle_big_rotation_stage = self.position_big_rotation_stage
|
|
333
|
-
#
|
|
334
|
-
# # Rotation angle of the small rotation stage [degrees]
|
|
335
|
-
# # - clockwise rotation
|
|
336
|
-
# # - 0° -> ?
|
|
337
|
-
#
|
|
338
|
-
# angle_small_rotation_stage = self.position_small_rotation_stage
|
|
339
|
-
#
|
|
340
|
-
# # Radial distance without field distortion [mm] and corresponding focal-plane coordinates [mm]
|
|
341
|
-
# # Note that the height of the lower triangle is very close to the focal length
|
|
342
|
-
#
|
|
343
|
-
# theta = 2 * angle_small_rotation_stage # [degrees]
|
|
344
|
-
#
|
|
345
|
-
# radial_distance_undistorted = self.focal_length * tan(radians(theta))
|
|
346
|
-
#
|
|
347
|
-
# x_undistorted = -radial_distance_undistorted * cos(-radians(angle_big_rotation_stage))
|
|
348
|
-
# y_undistorted = -radial_distance_undistorted * sin(-radians(angle_big_rotation_stage))
|
|
349
|
-
#
|
|
350
|
-
# x_distorted, y_distorted = \
|
|
351
|
-
# undistorted_to_distorted_focal_plane_coordinates(x_undistorted, y_undistorted,
|
|
352
|
-
# self.distortion_coefficients, self.focal_length)
|
|
353
|
-
#
|
|
354
|
-
# return x_distorted, y_distorted
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
class HexapodMonitoringWorker(MonitoringWorker):
|
|
358
|
-
""" Worker for monitoring the position of the hexapod."""
|
|
359
|
-
|
|
360
|
-
# The worker will send a signal with the following information:
|
|
361
|
-
# - focus positions [mm]
|
|
362
|
-
|
|
363
|
-
hexapod_position_signal = pyqtSignal(float)
|
|
364
|
-
|
|
365
|
-
def __init__(self):
|
|
366
|
-
""" Initialisation of a monitoring worker for the hexapod.
|
|
367
|
-
|
|
368
|
-
This monitoring worker will listen on the monitoring port of the Hexapod PUNA Control Server.
|
|
369
|
-
"""
|
|
370
|
-
|
|
371
|
-
super(HexapodMonitoringWorker, self).__init__(HEXAPOD_SETTINGS)
|
|
372
|
-
|
|
373
|
-
self.focus_position = None
|
|
374
|
-
|
|
375
|
-
@pyqtSlot()
|
|
376
|
-
def run(self):
|
|
377
|
-
""" Keep on listening on the monitoring port of the hexapod.
|
|
378
|
-
|
|
379
|
-
If monitoring information is received before the timeout, a signal with the monitoring information is emitted.
|
|
380
|
-
Otherwise, it is checked whether or not the Control Server is active. If not, a signal is emitted with the
|
|
381
|
-
process name. Otherwise, the timeout for monitoring was too strict (and it will therefore be increased by
|
|
382
|
-
0.5s).
|
|
383
|
-
"""
|
|
384
|
-
self.active = True
|
|
385
|
-
|
|
386
|
-
while self.is_socket_connected and self.active:
|
|
387
|
-
|
|
388
|
-
try:
|
|
389
|
-
|
|
390
|
-
socket_list, _, _ = zmq.select([self.monitoring_socket], [], [], timeout=self.monitoring_timeout)
|
|
391
|
-
|
|
392
|
-
# Monitoring information was received (before timeout)
|
|
393
|
-
|
|
394
|
-
if self.monitoring_socket in socket_list:
|
|
395
|
-
|
|
396
|
-
pickle_string = self.monitoring_socket.recv()
|
|
397
|
-
monitoring_info = pickle.loads(pickle_string)
|
|
398
|
-
|
|
399
|
-
# Update the timeout, to be more in line with the monitoring frequency of the CS (i.e. the delay).
|
|
400
|
-
# Take 0.5s extra to be on the safe side.
|
|
401
|
-
|
|
402
|
-
self.monitoring_timeout = monitoring_info["delay"] / 1000.0 + 0.5 # [s]
|
|
403
|
-
|
|
404
|
-
if self.position_has_changed(monitoring_info):
|
|
405
|
-
self.hexapod_position_signal.emit(self.focus_position)
|
|
406
|
-
|
|
407
|
-
except zmq.ZMQError:
|
|
408
|
-
|
|
409
|
-
pass
|
|
410
|
-
|
|
411
|
-
# Timeout occurred
|
|
412
|
-
|
|
413
|
-
else:
|
|
414
|
-
|
|
415
|
-
# The CS is not active
|
|
416
|
-
|
|
417
|
-
if not is_control_server_active(self.commanding_address):
|
|
418
|
-
|
|
419
|
-
pass
|
|
420
|
-
|
|
421
|
-
# The CS is active, but the timeout was too strict
|
|
422
|
-
|
|
423
|
-
else:
|
|
424
|
-
|
|
425
|
-
self.monitoring_timeout += 0.5
|
|
426
|
-
|
|
427
|
-
@staticmethod
|
|
428
|
-
def get_focus_position(monitoring_info: dict):
|
|
429
|
-
|
|
430
|
-
return -monitoring_info["user"][2]
|
|
431
|
-
|
|
432
|
-
def position_has_changed(self, monitoring_info: dict):
|
|
433
|
-
""" Check whether the focus position has changed.
|
|
434
|
-
|
|
435
|
-
Check whether the focus position has changed since the previous time monitoring information was received.
|
|
436
|
-
|
|
437
|
-
If the focus position has changed, the previous value is updated.
|
|
438
|
-
|
|
439
|
-
Args:
|
|
440
|
-
- monitoring_info: Monitoring information for the hexapod.
|
|
441
|
-
|
|
442
|
-
Returns: True if the focus position has changed; False otherwise.
|
|
443
|
-
"""
|
|
444
|
-
|
|
445
|
-
focus_position = self.get_focus_position(monitoring_info)
|
|
446
|
-
|
|
447
|
-
if focus_position != self.focus_position:
|
|
448
|
-
|
|
449
|
-
self.focus_position = focus_position
|
|
450
|
-
return True
|
|
451
|
-
|
|
452
|
-
return False
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
class FOVUIView(QMainWindow, Observable):
|
|
456
|
-
|
|
457
|
-
def __init__(self):
|
|
458
|
-
|
|
459
|
-
"""
|
|
460
|
-
Open a window and initialiase the GUI. The GUI is divided into two parts. On the
|
|
461
|
-
left there are three widgets, showing the current setting of the stages and the focus
|
|
462
|
-
position. On the right the focal plane is shown, together with a blue circle indicating
|
|
463
|
-
the size of the field-of-view, and a red dot indicating the current position of the source.
|
|
464
|
-
"""
|
|
465
|
-
|
|
466
|
-
super().__init__()
|
|
467
|
-
|
|
468
|
-
self.setGeometry(300, 300, 1500, 1000)
|
|
469
|
-
self.setWindowTitle("FOV Position GUI")
|
|
470
|
-
|
|
471
|
-
setup = load_setup()
|
|
472
|
-
self.fov_radius_mm = setup.camera.fov.radius_mm
|
|
473
|
-
|
|
474
|
-
# Monitoring the stages
|
|
475
|
-
|
|
476
|
-
self.stages_monitoring_thread = QThread(self)
|
|
477
|
-
self.stages_monitoring_worker = StagesMonitoringWorker()
|
|
478
|
-
self.stages_monitoring_worker.moveToThread(self.stages_monitoring_thread)
|
|
479
|
-
|
|
480
|
-
self.stages_monitoring_worker.stages_position_signal.connect(self.on_stages_position_change_signal)
|
|
481
|
-
self.stages_monitoring_thread.started.connect(self.stages_monitoring_worker.start_process)
|
|
482
|
-
self.stages_monitoring_thread.start()
|
|
483
|
-
|
|
484
|
-
# Monitoring the hexapod
|
|
485
|
-
|
|
486
|
-
self.hexapod_monitoring_thread = QThread(self)
|
|
487
|
-
self.hexapod_monitoring_worker = HexapodMonitoringWorker()
|
|
488
|
-
self.hexapod_monitoring_worker.moveToThread(self.hexapod_monitoring_thread)
|
|
489
|
-
|
|
490
|
-
self.hexapod_monitoring_worker.hexapod_position_signal.connect(self.on_hexapod_position_change_signal)
|
|
491
|
-
self.hexapod_monitoring_thread.started.connect(self.hexapod_monitoring_worker.start_process)
|
|
492
|
-
self.hexapod_monitoring_thread.start()
|
|
493
|
-
|
|
494
|
-
# Build up the GUI
|
|
495
|
-
|
|
496
|
-
self.source_position_text = QLabel() # "Current source position"
|
|
497
|
-
self.source_position_angles_text = QLabel() # (theta, phi)
|
|
498
|
-
self.source_position_pixels_text = QLabel() # (row, column)
|
|
499
|
-
self.source_position_mm_text = QLabel() # (xFP, yFP)
|
|
500
|
-
|
|
501
|
-
self.sma = ScanMirrorAssemblyWidget()
|
|
502
|
-
self.big_rotation_stage = BigRotationStageWidget()
|
|
503
|
-
self.focus_position = FocusPositionWidget()
|
|
504
|
-
self.focal_plane = FocalPlaneWidgetWithSourcePosition()
|
|
505
|
-
|
|
506
|
-
self.init_ui()
|
|
507
|
-
|
|
508
|
-
def init_ui(self):
|
|
509
|
-
""" Initialisation of the GUI.
|
|
510
|
-
|
|
511
|
-
The GUI is divided into two parts. On the left there are three widgets, showing the current setting of the
|
|
512
|
-
stages and the focus position. On the right the focal plane is shown, together with a blue circle indicating the
|
|
513
|
-
size of the field-of-view, and a red dot indicating the current position of the source.
|
|
514
|
-
"""
|
|
515
|
-
|
|
516
|
-
app_frame = QFrame()
|
|
517
|
-
app_frame.setObjectName("AppFrame")
|
|
518
|
-
|
|
519
|
-
hbox = QHBoxLayout()
|
|
520
|
-
|
|
521
|
-
self.create_toolbar()
|
|
522
|
-
self.create_statusbar()
|
|
523
|
-
|
|
524
|
-
# Mechanisms
|
|
525
|
-
|
|
526
|
-
mechanisms_frame = QFrame()
|
|
527
|
-
mechanisms_frame.setObjectName("Mechanisms")
|
|
528
|
-
|
|
529
|
-
vbox_left = QGridLayout()
|
|
530
|
-
vbox_left.addWidget(self.sma)
|
|
531
|
-
vbox_left.addWidget(self.big_rotation_stage)
|
|
532
|
-
vbox_left.addWidget(self.focus_position)
|
|
533
|
-
|
|
534
|
-
mechanisms_frame.setLayout(vbox_left)
|
|
535
|
-
|
|
536
|
-
# FOV
|
|
537
|
-
|
|
538
|
-
fpa_frame = QFrame()
|
|
539
|
-
fpa_frame.setObjectName("FOV")
|
|
540
|
-
|
|
541
|
-
vbox_right = QVBoxLayout()
|
|
542
|
-
vbox_right.addWidget(self.focal_plane)
|
|
543
|
-
|
|
544
|
-
# Current source position
|
|
545
|
-
|
|
546
|
-
self.source_position_text.setFont(FONT)
|
|
547
|
-
vbox_right.addWidget(self.source_position_text)
|
|
548
|
-
|
|
549
|
-
self.source_position_angles_text.setIndent(50)
|
|
550
|
-
self.source_position_angles_text.setFont(FONT)
|
|
551
|
-
self.source_position_angles_text.setStatusTip(
|
|
552
|
-
"Gnomonic distance to the optical axis " + u"\u03B8 and in-field angle " + u"\u03C6")
|
|
553
|
-
vbox_right.addWidget(self.source_position_angles_text)
|
|
554
|
-
|
|
555
|
-
self.source_position_pixels_text.setIndent(50)
|
|
556
|
-
self.source_position_pixels_text.setFont(FONT)
|
|
557
|
-
self.source_position_pixels_text.setStatusTip("Pixel coordinates on specified CCD")
|
|
558
|
-
vbox_right.addWidget(self.source_position_pixels_text)
|
|
559
|
-
|
|
560
|
-
self.source_position_mm_text.setIndent(50)
|
|
561
|
-
self.source_position_mm_text.setFont(FONT)
|
|
562
|
-
self.source_position_mm_text.setStatusTip("Focal-plane coordinates")
|
|
563
|
-
vbox_right.addWidget(self.source_position_mm_text)
|
|
564
|
-
|
|
565
|
-
fpa_frame.setLayout(vbox_right)
|
|
566
|
-
|
|
567
|
-
# Putting everything in place
|
|
568
|
-
|
|
569
|
-
hbox.addWidget(mechanisms_frame)
|
|
570
|
-
hbox.addWidget(fpa_frame)
|
|
571
|
-
|
|
572
|
-
app_frame.setLayout(hbox)
|
|
573
|
-
|
|
574
|
-
self.setCentralWidget(app_frame)
|
|
575
|
-
|
|
576
|
-
def create_toolbar(self):
|
|
577
|
-
|
|
578
|
-
# # The Home action is used to command the Homing to the Hexapod.
|
|
579
|
-
#
|
|
580
|
-
# self.homing = TouchButton(
|
|
581
|
-
# name="HOMING",
|
|
582
|
-
# status_tip="perform a homing operation (ON ALL THE STAGES)",
|
|
583
|
-
# selected=get_resource(":/icons/home.svg"),
|
|
584
|
-
# disabled=get_resource(":/icons/home-disabled.svg"),
|
|
585
|
-
# )
|
|
586
|
-
# self.homing.clicked.connect(self.onClick)
|
|
587
|
-
#
|
|
588
|
-
# # The Clear action is used to command the ClearErrors to the Hexapod.
|
|
589
|
-
#
|
|
590
|
-
# self.clear_errors = TouchButton(
|
|
591
|
-
# name="CLEAR-ERRORS",
|
|
592
|
-
# status_tip="clear the error list on the controller (FOR ALL STAGES)",
|
|
593
|
-
# selected=get_resource(":/icons/erase.svg"),
|
|
594
|
-
# disabled=get_resource(":/icons/erase-disabled.svg"),
|
|
595
|
-
# )
|
|
596
|
-
# self.clear_errors.clicked.connect(self.onClick)
|
|
597
|
-
#
|
|
598
|
-
# # The Reconnect action is used to reconnect to the control server
|
|
599
|
-
#
|
|
600
|
-
# self.cs_connection = ToggleButton(
|
|
601
|
-
# name="CS-CONNECT",
|
|
602
|
-
# status_tip="connect-disconnect huber stages control server.",
|
|
603
|
-
# selected=get_resource(":/icons/cs-connected.svg"),
|
|
604
|
-
# not_selected=get_resource(":/icons/cs-not-connected.svg"),
|
|
605
|
-
# disabled=get_resource(":/icons/cs-connected-disabled.svg")
|
|
606
|
-
# )
|
|
607
|
-
# self.cs_connection.clicked.connect(self.onClick)
|
|
608
|
-
#
|
|
609
|
-
# # The Reconnect action is used to reconnect the device
|
|
610
|
-
#
|
|
611
|
-
# self.device_connection = ToggleButton(
|
|
612
|
-
# name="DEVICE-CONNECT",
|
|
613
|
-
# status_tip="connect-disconnect the huber stages controller",
|
|
614
|
-
# selected=get_resource(":/icons/plugged.svg"),
|
|
615
|
-
# not_selected=get_resource(":/icons/unplugged.svg"),
|
|
616
|
-
# disabled=get_resource(":/icons/plugged-disabled.svg")
|
|
617
|
-
# )
|
|
618
|
-
# self.device_connection.clicked.connect(self.onClick)
|
|
619
|
-
#
|
|
620
|
-
# # The STOP button is used to immediately stop the current motion
|
|
621
|
-
#
|
|
622
|
-
# stop_button = QIcon(str(get_resource(":/icons/stop.svg")))
|
|
623
|
-
#
|
|
624
|
-
# self.stop_action = QAction(stop_button, "STOP", self)
|
|
625
|
-
# self.stop_action.setToolTip("STOP Movement")
|
|
626
|
-
# self.stop_action.triggered.connect(self.onClick)
|
|
627
|
-
|
|
628
|
-
# The HELP button is used to show the on-line help in a browser window
|
|
629
|
-
|
|
630
|
-
help_button = QIcon(str(get_resource(":/icons/info.svg")))
|
|
631
|
-
|
|
632
|
-
self.help_action = QAction(help_button, "INFO", self)
|
|
633
|
-
self.help_action.setToolTip("Browse the on-line documentation")
|
|
634
|
-
self.help_action.triggered.connect(self.on_click)
|
|
635
|
-
|
|
636
|
-
# spacer widget to help with aligning STOP button to the right
|
|
637
|
-
|
|
638
|
-
spacer = QWidget()
|
|
639
|
-
spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
|
640
|
-
|
|
641
|
-
self.toolbar = self.addToolBar("MainToolbar")
|
|
642
|
-
# self.toolbar.addWidget(self.homing)
|
|
643
|
-
# self.toolbar.addWidget(self.clear_errors)
|
|
644
|
-
# self.toolbar.addWidget(self.device_connection)
|
|
645
|
-
# self.toolbar.addWidget(self.cs_connection)
|
|
646
|
-
self.toolbar.addWidget(spacer)
|
|
647
|
-
# self.toolbar.addAction(self.stop_action)
|
|
648
|
-
self.toolbar.addAction(self.help_action)
|
|
649
|
-
|
|
650
|
-
return self.toolbar
|
|
651
|
-
|
|
652
|
-
def create_statusbar(self):
|
|
653
|
-
""" Create a status bar.
|
|
654
|
-
|
|
655
|
-
Returns: Status bar.
|
|
656
|
-
"""
|
|
657
|
-
|
|
658
|
-
self.statusBar().setStyleSheet("border: 0; background-color: #FFF8DC;")
|
|
659
|
-
self.statusBar().setStyleSheet("QStatusBar::item {border: none;}")
|
|
660
|
-
self.statusBar().addPermanentWidget(VLine())
|
|
661
|
-
# self.statusBar().addPermanentWidget(self.mode_label)
|
|
662
|
-
|
|
663
|
-
def on_click(self):
|
|
664
|
-
|
|
665
|
-
sender = self.sender()
|
|
666
|
-
self.notifyObservers(sender)
|
|
667
|
-
|
|
668
|
-
def on_stages_position_change_signal(self, position_big_rotation_stage: float, position_small_rotation_stage: float,
|
|
669
|
-
position_translation_stage: float, source_position: dict):
|
|
670
|
-
""" Update the GUI for changes in the position of the stages.
|
|
671
|
-
|
|
672
|
-
Args:
|
|
673
|
-
- position_big_rotation_stage: Rotation angle for the new configuration of the big rotation stage [degrees].
|
|
674
|
-
This does not include the offset!
|
|
675
|
-
- position_small_rotation_stage: Orientation angle of the scan mirror [degrees]. This does not include the
|
|
676
|
-
offset!
|
|
677
|
-
- position_translation_stage: Distance between the scan mirror and the optical axis (along the translation
|
|
678
|
-
stage) for the new configuration of the scan mirror assembly [mm]. This does
|
|
679
|
-
not include the offset!
|
|
680
|
-
- source_position: Dictionary with the following entries:
|
|
681
|
-
- "angles": tuple with the field angles (theta, phi) [degrees];
|
|
682
|
-
- "pixels": tuple with the pixel coordinates (row, column) [pixels] and CCD code;
|
|
683
|
-
- "mm": tuple with the focal-plane coordinates (x, y) [mm].
|
|
684
|
-
"""
|
|
685
|
-
|
|
686
|
-
# Mechanisms
|
|
687
|
-
|
|
688
|
-
self.update_sma(position_translation_stage, position_small_rotation_stage)
|
|
689
|
-
self.update_big_rotation_stage(position_big_rotation_stage)
|
|
690
|
-
|
|
691
|
-
# Source position
|
|
692
|
-
|
|
693
|
-
self.update_source_position(source_position)
|
|
694
|
-
|
|
695
|
-
def on_hexapod_position_change_signal(self, focus_position: float):
|
|
696
|
-
""" Update the GUI for changes in the position of the hexapod."""
|
|
697
|
-
|
|
698
|
-
self.update_focus_position(focus_position)
|
|
699
|
-
|
|
700
|
-
def update_sma(self, distance, angle):
|
|
701
|
-
""" Update the shown configuration of the scan mirror assembly.
|
|
702
|
-
|
|
703
|
-
The orientation of the scan mirror must be changed, and the labels showing the distance from the scan
|
|
704
|
-
mirror to the optical axis (along the translation stage) and the orientation angle of the scan mirror must be
|
|
705
|
-
updated.
|
|
706
|
-
|
|
707
|
-
Args
|
|
708
|
-
- distance: Distance between the scan mirror and the optical axis (along the translation stage) for the new
|
|
709
|
-
configuration of the scan mirror assembly [mm]. This does not include the offset!
|
|
710
|
-
- angle: Orientation angle of the scan mirror [degrees]. This does not include the offset!
|
|
711
|
-
"""
|
|
712
|
-
|
|
713
|
-
self.sma.update_plot(distance, angle)
|
|
714
|
-
|
|
715
|
-
def update_big_rotation_stage(self, angle):
|
|
716
|
-
""" Update the shown configuration of the big rotation stage.
|
|
717
|
-
|
|
718
|
-
The orientation of GL_ROT w.r.t. GL_FIX must be set to the given angle.
|
|
719
|
-
|
|
720
|
-
Args:
|
|
721
|
-
- angle: Rotation angle for the new configuration of the big rotation stage [degrees]. This does not
|
|
722
|
-
include the offset!
|
|
723
|
-
"""
|
|
724
|
-
|
|
725
|
-
self.big_rotation_stage.update(angle)
|
|
726
|
-
|
|
727
|
-
def update_focus_position(self, focus_position):
|
|
728
|
-
""" Update the shown focus position.
|
|
729
|
-
|
|
730
|
-
Args:
|
|
731
|
-
- focus_position: New focus position [mm].
|
|
732
|
-
"""
|
|
733
|
-
|
|
734
|
-
self.focus_position.update_plot(focus_position)
|
|
735
|
-
|
|
736
|
-
def update_source_position(self, position: dict):
|
|
737
|
-
""" Update the position of the source in the focal plane to the given position.
|
|
738
|
-
|
|
739
|
-
The red dot must move on the focal plane (movement may not be visible) and the text label with the focal-plane
|
|
740
|
-
coordinates must be updated.
|
|
741
|
-
|
|
742
|
-
Args:
|
|
743
|
-
- position: Dictionary with the following entries:
|
|
744
|
-
|
|
745
|
-
- "angles": tuple with the field angles (theta, phi) [degrees];
|
|
746
|
-
- "pixels": tuple with the pixel coordinates (row, column) [pixels] and CCD code;
|
|
747
|
-
- "mm": tuple with the focal-plane coordinates (x, y) [mm].
|
|
748
|
-
"""
|
|
749
|
-
|
|
750
|
-
(theta, phi) = position["angles"]
|
|
751
|
-
(row, column, ccd_code) = position["pixels"]
|
|
752
|
-
(x_fp, y_fp) = position["mm"]
|
|
753
|
-
|
|
754
|
-
# Update the red dot in the plot
|
|
755
|
-
|
|
756
|
-
self.focal_plane.update_source_position(x_fp, y_fp)
|
|
757
|
-
|
|
758
|
-
# Update the text label
|
|
759
|
-
|
|
760
|
-
if abs(x_fp) > self.fov_radius_mm or abs(y_fp) > self.fov_radius_mm:
|
|
761
|
-
|
|
762
|
-
# MODULE_LOGGER.debug("Current source position: outside FOV")
|
|
763
|
-
|
|
764
|
-
self.source_position_text.setText("Current source position: outside FOV")
|
|
765
|
-
self.source_position_angles_text.setText("")
|
|
766
|
-
self.source_position_pixels_text.setText("")
|
|
767
|
-
self.source_position_mm_text.setText("")
|
|
768
|
-
|
|
769
|
-
else:
|
|
770
|
-
|
|
771
|
-
self.source_position_text.setText("Current source position:")
|
|
772
|
-
self.source_position_angles_text.setText(
|
|
773
|
-
u"\u2022" + "(" + u"\u03B8" + ", " + u"\u03C6" + ") [" + u"\u00B0" + "] = ({:.2f}, {:.2f})"
|
|
774
|
-
.format(theta, phi))
|
|
775
|
-
|
|
776
|
-
if ccd_code is None:
|
|
777
|
-
|
|
778
|
-
self.source_position_pixels_text.setText(u"\u2022" + " source doesn't fall on any CCD")
|
|
779
|
-
|
|
780
|
-
else:
|
|
781
|
-
|
|
782
|
-
self.source_position_pixels_text.setText(
|
|
783
|
-
u"\u2022" + "(x<sub>CCD</sub>, y<sub>CCD</sub>) [pixels] = ({:.2f}, {:.2f}) on CCD "
|
|
784
|
-
.format(column, row) + str(ccd_code))
|
|
785
|
-
|
|
786
|
-
self.source_position_mm_text.setText(
|
|
787
|
-
u"\u2022" + "(x<sub>FP</sub>, y<sub>FP</sub>) [mm] = ({:.2f}, {:.2f})".format(x_fp, y_fp))
|
|
788
|
-
|
|
789
|
-
def closeEvent(self, close_event: QCloseEvent) -> None:
|
|
790
|
-
""" Make sure that all threads are stopped when the GUI is closed.
|
|
791
|
-
|
|
792
|
-
Args:
|
|
793
|
-
- close_event: Close event received when the GUI is closed.
|
|
794
|
-
"""
|
|
795
|
-
|
|
796
|
-
# Stages
|
|
797
|
-
|
|
798
|
-
self.stages_monitoring_worker.active = False
|
|
799
|
-
self.stages_monitoring_thread.quit()
|
|
800
|
-
self.stages_monitoring_thread.wait()
|
|
801
|
-
|
|
802
|
-
# Hexapod
|
|
803
|
-
|
|
804
|
-
self.hexapod_monitoring_worker.active = False
|
|
805
|
-
self.hexapod_monitoring_thread.quit()
|
|
806
|
-
self.hexapod_monitoring_thread.wait()
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
class FOVUIController(Observer):
|
|
810
|
-
|
|
811
|
-
def __init__(self, view):
|
|
812
|
-
|
|
813
|
-
self.view = view
|
|
814
|
-
self.view.addObserver(self)
|
|
815
|
-
|
|
816
|
-
self.help_window = HelpWindow(topic_url=HELP_TOPICS["smc9300_ui"])
|
|
817
|
-
|
|
818
|
-
def update(self, changed_object):
|
|
819
|
-
|
|
820
|
-
text = changed_object.text()
|
|
821
|
-
|
|
822
|
-
if text == "INFO":
|
|
823
|
-
|
|
824
|
-
self.help_window.show()
|
|
825
|
-
|
|
826
|
-
def do(self, actions):
|
|
827
|
-
|
|
828
|
-
pass
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
def main():
|
|
832
|
-
lock_file = QLockFile(str(Path("~/fov_ui.app.lock").expanduser()))
|
|
833
|
-
|
|
834
|
-
styles_location = find_file("styles.qss", in_dir="egse/gui")
|
|
835
|
-
|
|
836
|
-
args = list(sys.argv)
|
|
837
|
-
args[1:1] = ['-stylesheet', str(styles_location)]
|
|
838
|
-
|
|
839
|
-
app = QApplication(args)
|
|
840
|
-
app.setWindowIcon(QIcon(str(get_resource(":/icons/location-marker.svg"))))
|
|
841
|
-
|
|
842
|
-
if lock_file.tryLock(100):
|
|
843
|
-
view = FOVUIView()
|
|
844
|
-
FOVUIController(view)
|
|
845
|
-
view.show()
|
|
846
|
-
|
|
847
|
-
return app.exec_()
|
|
848
|
-
else:
|
|
849
|
-
error_message = QMessageBox()
|
|
850
|
-
error_message.setIcon(QMessageBox.Warning)
|
|
851
|
-
error_message.setWindowTitle("Error")
|
|
852
|
-
error_message.setText("The FOV GUI application is already running!")
|
|
853
|
-
error_message.setStandardButtons(QMessageBox.Ok)
|
|
854
|
-
|
|
855
|
-
return error_message.exec()
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
if __name__ == "__main__":
|
|
859
|
-
sys.exit(main())
|