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
|
@@ -1,1279 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
The referenceFrames module provides the class :code:`ReferenceFrames` which defines the affine transformation
|
|
3
|
-
for bringing one reference frame to another.
|
|
4
|
-
|
|
5
|
-
.. todo:: The tests in methods like getPassiveTransformationTo using '==' should be looked at again and maybe
|
|
6
|
-
changed into using the 'is' operator. This because we now have __eq__ implemented.
|
|
7
|
-
|
|
8
|
-
@author: Pierre Royer
|
|
9
|
-
"""
|
|
10
|
-
import logging
|
|
11
|
-
import random
|
|
12
|
-
import string
|
|
13
|
-
import textwrap
|
|
14
|
-
|
|
15
|
-
import numpy as np
|
|
16
|
-
import transforms3d as t3
|
|
17
|
-
|
|
18
|
-
import egse.coordinates.transform3d_addon as t3add
|
|
19
|
-
from egse.coordinates.point import Point
|
|
20
|
-
from egse.coordinates.rotationMatrix import RotationMatrix
|
|
21
|
-
from egse.decorators import deprecate
|
|
22
|
-
from egse.exceptions import InvalidOperationError
|
|
23
|
-
|
|
24
|
-
LOGGER = logging.getLogger(__name__)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def transformationToString(transformation):
|
|
28
|
-
"""Helper function: prints out a transformation (numpy ndarray) in a condensed form on one line."""
|
|
29
|
-
|
|
30
|
-
if isinstance(transformation, np.ndarray):
|
|
31
|
-
if np.allclose(transformation, ReferenceFrame._I):
|
|
32
|
-
return "Identity"
|
|
33
|
-
msg = np.array2string(
|
|
34
|
-
transformation,
|
|
35
|
-
separator=",",
|
|
36
|
-
suppress_small=True,
|
|
37
|
-
formatter={"float_kind": lambda x: "%.2f" % x},
|
|
38
|
-
).replace("\n", "")
|
|
39
|
-
return msg
|
|
40
|
-
|
|
41
|
-
# We do not want to raise an Exception here since this is mainly used in logging messages
|
|
42
|
-
# and doesn't really harm the execution of the program.
|
|
43
|
-
return f"ERROR: expected transformation to be an ndarray, type={type(transformation)}"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
class ReferenceFrame(object):
|
|
47
|
-
"""
|
|
48
|
-
A Reference Frame defined in reference frame "ref", i.e.
|
|
49
|
-
defined by the affine transformation bringing the reference frame "ref" onto "self".
|
|
50
|
-
|
|
51
|
-
By default, "ref" is the master refence frame, defined as the identity matrix.
|
|
52
|
-
|
|
53
|
-
:param transformation: 4x4 affine transformation matrix defining this system in "ref" system
|
|
54
|
-
:type transformation: numpy array
|
|
55
|
-
|
|
56
|
-
:param ref: reference system in which this new reference frame is defined
|
|
57
|
-
:type ref: ReferenceFrame
|
|
58
|
-
|
|
59
|
-
:param name: name the reference frame so it can be referenced, set to 'master' when None
|
|
60
|
-
:type name: str
|
|
61
|
-
|
|
62
|
-
:param rot_config:
|
|
63
|
-
* Is set when using creator ReferenceFrame.fromTranslationRotation()
|
|
64
|
-
* In other cases, is set to a default "szyx"
|
|
65
|
-
(rotations around static axes z, y and x in this order)
|
|
66
|
-
In these other cases, it has no real direct influence,
|
|
67
|
-
except for methods returning the rotation vector (e.g. getRotationVector)
|
|
68
|
-
It is therefore always recommended to pass it to the constructor, even when
|
|
69
|
-
constructing the ReferenceFrame directly from a transformation matrix
|
|
70
|
-
:type rot_config: str
|
|
71
|
-
|
|
72
|
-
Both the ``transformation`` and the ``ref`` parameters are mandatory.
|
|
73
|
-
|
|
74
|
-
If the reference frame is None, the master reference frame is created.
|
|
75
|
-
|
|
76
|
-
The master reference frame:
|
|
77
|
-
|
|
78
|
-
* is defined by the identity transformation matrix
|
|
79
|
-
* has itself as a reference
|
|
80
|
-
|
|
81
|
-
For convenience we provide the following factory methods:
|
|
82
|
-
|
|
83
|
-
createMaster()
|
|
84
|
-
Create a Master Reference Frame
|
|
85
|
-
|
|
86
|
-
createRotation(..)
|
|
87
|
-
Create a new Reference Frame that is rotated with respect to the given reference frame
|
|
88
|
-
|
|
89
|
-
createTranslation(..)
|
|
90
|
-
Create a new Reference Frame that is a translation with respect to the given reference frame
|
|
91
|
-
"""
|
|
92
|
-
|
|
93
|
-
_I = np.identity(4)
|
|
94
|
-
_MASTER = None
|
|
95
|
-
_ROT_CONFIG_DEFAULT = "sxyz"
|
|
96
|
-
_names_used = [None, "Master"]
|
|
97
|
-
_strict_naming = False
|
|
98
|
-
_ACTIVE_DEFAULT = True
|
|
99
|
-
|
|
100
|
-
def __new__(cls, transformation, ref, name=None, rot_config=_ROT_CONFIG_DEFAULT):
|
|
101
|
-
"""Create a new ReferenceFrame class."""
|
|
102
|
-
|
|
103
|
-
LOGGER.debug(
|
|
104
|
-
f"transformation={transformationToString(transformation)}, ref={ref!r}, name={name}, rot_config={rot_config}"
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
if ref is None:
|
|
108
|
-
msg = (
|
|
109
|
-
"No reference frame was given, if you planned to create a Master Reference Frame, "
|
|
110
|
-
"use ReferenceFrame.createMaster(). "
|
|
111
|
-
)
|
|
112
|
-
LOGGER.error(msg)
|
|
113
|
-
raise ValueError(msg, "REF_IS_NONE")
|
|
114
|
-
|
|
115
|
-
if not isinstance(ref, cls):
|
|
116
|
-
msg = f"The 'ref' keyword argument is not a ReferenceFrame object, but {type(ref)}"
|
|
117
|
-
LOGGER.error(msg)
|
|
118
|
-
raise ValueError(msg, "REF_IS_NOT_CLS")
|
|
119
|
-
|
|
120
|
-
if name == "Master":
|
|
121
|
-
msg = (
|
|
122
|
-
"The 'name' argument cannot be 'Master' unless a Master instance should be created, "
|
|
123
|
-
"in that case, use ReferenceFrame.createMaster()"
|
|
124
|
-
)
|
|
125
|
-
LOGGER.error(msg)
|
|
126
|
-
raise ValueError(msg, "MASTER_NAME_USED")
|
|
127
|
-
|
|
128
|
-
if transformation is None:
|
|
129
|
-
msg = "The 'transformation' argument can not be None, please provide a proper transformation for this reference frame."
|
|
130
|
-
LOGGER.error(msg)
|
|
131
|
-
raise ValueError(msg, "TRANSFORMATION_IS_NONE")
|
|
132
|
-
|
|
133
|
-
if not isinstance(transformation, np.ndarray):
|
|
134
|
-
msg = f"The 'transformation' argument shall be a Numpy ndarray [not a {type(transformation)}], please provide a proper transformation for this reference frame."
|
|
135
|
-
LOGGER.error(msg)
|
|
136
|
-
raise ValueError(msg, "TRANSFORMATION_IS_NOT_NDARRAY")
|
|
137
|
-
|
|
138
|
-
if rot_config is None:
|
|
139
|
-
msg = "The 'rot_config' keyword argument can not be None, do not specify it when you want to use the default value."
|
|
140
|
-
LOGGER.error(msg)
|
|
141
|
-
raise ValueError(msg)
|
|
142
|
-
|
|
143
|
-
_instance = super(ReferenceFrame, cls).__new__(cls)
|
|
144
|
-
|
|
145
|
-
return _instance
|
|
146
|
-
|
|
147
|
-
def __init__(self, transformation, ref, name=None, rot_config=_ROT_CONFIG_DEFAULT):
|
|
148
|
-
"""Initialize the ReferenceFrame object """
|
|
149
|
-
|
|
150
|
-
self.debug = False
|
|
151
|
-
|
|
152
|
-
LOGGER.debug(
|
|
153
|
-
f"transformation={transformationToString(transformation)}, ref={ref!r}, name={name}, rot_config={rot_config}"
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
# All argument testing is done in the __new__() method and we should be save here.
|
|
157
|
-
|
|
158
|
-
self.ref = ref
|
|
159
|
-
self.name = self.__createName(name)
|
|
160
|
-
self.transformation = transformation
|
|
161
|
-
self.rot_config = rot_config
|
|
162
|
-
|
|
163
|
-
self.definition = [self.transformation, self.ref, self.name]
|
|
164
|
-
|
|
165
|
-
self.x = self.getAxis("x")
|
|
166
|
-
self.y = self.getAxis("y")
|
|
167
|
-
self.z = self.getAxis("z")
|
|
168
|
-
|
|
169
|
-
self.linkedTo = {}
|
|
170
|
-
self.referenceFor = []
|
|
171
|
-
|
|
172
|
-
ref.referenceFor.append(self)
|
|
173
|
-
|
|
174
|
-
return
|
|
175
|
-
|
|
176
|
-
def find_master(self):
|
|
177
|
-
return self.findMaster()
|
|
178
|
-
|
|
179
|
-
def findMaster(self):
|
|
180
|
-
"""
|
|
181
|
-
Returns the Master frame for this reference frame. The Master frame is always at the end
|
|
182
|
-
of the path following the references.
|
|
183
|
-
|
|
184
|
-
Returns:
|
|
185
|
-
The master frame.
|
|
186
|
-
"""
|
|
187
|
-
|
|
188
|
-
frame = self
|
|
189
|
-
while not frame.isMaster():
|
|
190
|
-
frame = frame.ref
|
|
191
|
-
return frame
|
|
192
|
-
|
|
193
|
-
@classmethod
|
|
194
|
-
def createMaster(cls):
|
|
195
|
-
"""
|
|
196
|
-
Create a master reference frame.
|
|
197
|
-
|
|
198
|
-
A master reference frame is defined with respect to itself and is initialised with the
|
|
199
|
-
identity matrix.
|
|
200
|
-
|
|
201
|
-
The master frame is automatically given the name "Master".
|
|
202
|
-
"""
|
|
203
|
-
ref_master = super(ReferenceFrame, cls).__new__(cls)
|
|
204
|
-
ref_master.name = "Master"
|
|
205
|
-
ref_master.ref = ref_master
|
|
206
|
-
ref_master.transformation = cls._I
|
|
207
|
-
ref_master.rot_config = cls._ROT_CONFIG_DEFAULT
|
|
208
|
-
ref_master.initialized = True
|
|
209
|
-
ref_master.debug = False
|
|
210
|
-
ref_master.linkedTo = {}
|
|
211
|
-
ref_master.referenceFor = []
|
|
212
|
-
|
|
213
|
-
LOGGER.debug(
|
|
214
|
-
f"NEW MASTER CREATED: {id(ref_master)}, ref = {id(ref_master.ref)}, "
|
|
215
|
-
f"name = {ref_master.name}"
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
return ref_master
|
|
219
|
-
|
|
220
|
-
@classmethod
|
|
221
|
-
def __createName(cls, name: str = None):
|
|
222
|
-
|
|
223
|
-
if name is None:
|
|
224
|
-
while name in cls._names_used:
|
|
225
|
-
name = "F" + "".join(random.choices(string.ascii_uppercase, k=3))
|
|
226
|
-
return name
|
|
227
|
-
|
|
228
|
-
if cls._strict_naming:
|
|
229
|
-
|
|
230
|
-
# generate a unique name
|
|
231
|
-
|
|
232
|
-
old_name = name
|
|
233
|
-
|
|
234
|
-
while name in cls._names_used:
|
|
235
|
-
name = "F" + "".join(random.choices(string.ascii_uppercase, k=3))
|
|
236
|
-
|
|
237
|
-
LOGGER.warning(
|
|
238
|
-
f"name ('{old_name}') is already defined, since strict naming is applied, "
|
|
239
|
-
f"a new unique name was created: {name}"
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
else:
|
|
243
|
-
|
|
244
|
-
if name in cls._names_used:
|
|
245
|
-
LOGGER.log(
|
|
246
|
-
0,
|
|
247
|
-
f"name ('{name}') is already defined, now you have more than one "
|
|
248
|
-
f"ReferenceFrame with the same name.",
|
|
249
|
-
)
|
|
250
|
-
|
|
251
|
-
cls._names_used.append(name)
|
|
252
|
-
return name
|
|
253
|
-
|
|
254
|
-
@classmethod
|
|
255
|
-
def fromTranslation(cls, transx, transy, transz, ref, name=None):
|
|
256
|
-
"""
|
|
257
|
-
Create a ReferenceFrame from a translation with respect to the given reference frame.
|
|
258
|
-
|
|
259
|
-
:param transx: translation along the x-axis
|
|
260
|
-
:type transx: float
|
|
261
|
-
|
|
262
|
-
:param transy: translation along the y-axis
|
|
263
|
-
:type transy: float
|
|
264
|
-
|
|
265
|
-
:param transz: translation along the z-axis
|
|
266
|
-
:type transz: float
|
|
267
|
-
|
|
268
|
-
:param ref: reference frame with respect to which the translation is performed. If no ref is given
|
|
269
|
-
the rotation is with respect to the master reference frame
|
|
270
|
-
:type ref: ReferenceFrame
|
|
271
|
-
|
|
272
|
-
:param name: a simple convenient name to identify the reference frame. If no name is provided
|
|
273
|
-
a random name of four characters starting with 'F' will be generated.
|
|
274
|
-
:type name: str
|
|
275
|
-
|
|
276
|
-
:return: a reference frame
|
|
277
|
-
"""
|
|
278
|
-
adef = np.identity(4)
|
|
279
|
-
adef[:3, 3] = [transx, transy, transz]
|
|
280
|
-
|
|
281
|
-
if ref is None:
|
|
282
|
-
raise ValueError(
|
|
283
|
-
"The ref argument can not be None, provide a master or another reference frame."
|
|
284
|
-
)
|
|
285
|
-
|
|
286
|
-
return cls(transformation=adef, ref=ref, name=name)
|
|
287
|
-
|
|
288
|
-
@classmethod
|
|
289
|
-
def fromRotation(
|
|
290
|
-
cls,
|
|
291
|
-
rotx,
|
|
292
|
-
roty,
|
|
293
|
-
rotz,
|
|
294
|
-
ref,
|
|
295
|
-
name=None,
|
|
296
|
-
rot_config=_ROT_CONFIG_DEFAULT,
|
|
297
|
-
active=_ACTIVE_DEFAULT,
|
|
298
|
-
degrees=True,
|
|
299
|
-
):
|
|
300
|
-
"""
|
|
301
|
-
Create a ReferenceFrame from a rotation with respect to the given reference frame.
|
|
302
|
-
|
|
303
|
-
:param rotx: rotation around the x-axis
|
|
304
|
-
:type rotx: float
|
|
305
|
-
|
|
306
|
-
:param roty: rotation around the y-axis
|
|
307
|
-
:type roty: float
|
|
308
|
-
|
|
309
|
-
:param rotz: rotation around the z-axis
|
|
310
|
-
:type rotz: float
|
|
311
|
-
|
|
312
|
-
:param ref: reference frame with respect to which the rotation is performed. If no ref is given
|
|
313
|
-
the rotation is with respect to the master reference frame
|
|
314
|
-
:type ref: ReferenceFrame
|
|
315
|
-
|
|
316
|
-
:param name: a simple convenient name to identify the reference frame. If no name is provided
|
|
317
|
-
a random name of four characters starting with 'F' will be generated.
|
|
318
|
-
:type name: str
|
|
319
|
-
|
|
320
|
-
:return: a reference frame
|
|
321
|
-
"""
|
|
322
|
-
# Convention (rotating axes, in order xyz)
|
|
323
|
-
|
|
324
|
-
# rot_config = cls._ROT_CONFIG_DEFAULT
|
|
325
|
-
|
|
326
|
-
# Rotation amplitude
|
|
327
|
-
|
|
328
|
-
# Rotation
|
|
329
|
-
if degrees:
|
|
330
|
-
rotx = np.deg2rad(rotx)
|
|
331
|
-
roty = np.deg2rad(roty)
|
|
332
|
-
rotz = np.deg2rad(rotz)
|
|
333
|
-
|
|
334
|
-
rotation = RotationMatrix(rotx, roty, rotz, rot_config, active=active)
|
|
335
|
-
|
|
336
|
-
# Defaults for zoom & shear
|
|
337
|
-
|
|
338
|
-
zdef = np.array([1, 1, 1])
|
|
339
|
-
sdef = np.array([0, 0, 0])
|
|
340
|
-
|
|
341
|
-
translation = [0, 0, 0]
|
|
342
|
-
|
|
343
|
-
TT = t3.affines.compose(T=translation, R=rotation.R, Z=zdef, S=sdef)
|
|
344
|
-
|
|
345
|
-
if ref is None:
|
|
346
|
-
raise ValueError(
|
|
347
|
-
"The ref argument can not be None, provide a master or another reference frame."
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
return cls(transformation=TT, ref=ref, name=name, rot_config=rot_config)
|
|
351
|
-
|
|
352
|
-
@staticmethod
|
|
353
|
-
def fromPoints(points, plane="xy", name=None, usesvd=True, verbose=True):
|
|
354
|
-
"""
|
|
355
|
-
fromPoints(points, plane="xy", name=None, usesvd=True,verbose=True)
|
|
356
|
-
|
|
357
|
-
Finds the best fitting "plane" plane to all points in "points" and builds a ReferenceFrame
|
|
358
|
-
considering the fitted plane as the 'xy' plane of the new system
|
|
359
|
-
|
|
360
|
-
fitPlane must be in ['xy','yz','zx']
|
|
361
|
-
"""
|
|
362
|
-
return points.bestFittingPlane(fitPlane=plane, usesvd=usesvd, verbose=verbose)
|
|
363
|
-
|
|
364
|
-
@classmethod
|
|
365
|
-
def fromTranslationRotation(
|
|
366
|
-
cls,
|
|
367
|
-
translation,
|
|
368
|
-
rotation,
|
|
369
|
-
ref,
|
|
370
|
-
name=None,
|
|
371
|
-
rot_config=_ROT_CONFIG_DEFAULT,
|
|
372
|
-
active=_ACTIVE_DEFAULT,
|
|
373
|
-
degrees=True,
|
|
374
|
-
):
|
|
375
|
-
"""fromTranslationRotation(cls,translation,rotation, ref=None,name=None, rot_config=_ROT_CONFIG_DEFAULT,active=_ACTIVE_DEFAULT, degrees=True)
|
|
376
|
-
|
|
377
|
-
Construct a ReferenceFrame from a translation and a rotation (vectors!)
|
|
378
|
-
|
|
379
|
-
translation : translation vector : 3 x 1 = tx, ty, tz
|
|
380
|
-
rotation : rotation vector : 3 x 1 = rx, ry, rz
|
|
381
|
-
|
|
382
|
-
rot_config : convention for the rotation, see rotationMatrix.__doc__
|
|
383
|
-
|
|
384
|
-
degrees : if True, input values are assumed in degrees, otherwise radians
|
|
385
|
-
"""
|
|
386
|
-
# Translation
|
|
387
|
-
translation = np.array(translation)
|
|
388
|
-
# Zoom - unit
|
|
389
|
-
zdef = np.array([1, 1, 1])
|
|
390
|
-
# Shear
|
|
391
|
-
sdef = np.array([0, 0, 0])
|
|
392
|
-
# Rotation
|
|
393
|
-
if degrees:
|
|
394
|
-
rotation = np.array([np.deg2rad(item) for item in rotation])
|
|
395
|
-
rotx, roty, rotz = rotation
|
|
396
|
-
#
|
|
397
|
-
rmat = RotationMatrix(rotx, roty, rotz, rot_config=rot_config, active=active)
|
|
398
|
-
#
|
|
399
|
-
# transformation = t3.affines.compose(translation,rmat.R,Z=zdef,S=sdef)
|
|
400
|
-
|
|
401
|
-
if ref is None:
|
|
402
|
-
raise ValueError(
|
|
403
|
-
"The ref argument can not be None, provide a master or another reference frame."
|
|
404
|
-
)
|
|
405
|
-
|
|
406
|
-
return cls(
|
|
407
|
-
transformation=t3.affines.compose(translation, rmat.R, Z=zdef, S=sdef),
|
|
408
|
-
ref=ref,
|
|
409
|
-
name=name,
|
|
410
|
-
rot_config=rot_config,
|
|
411
|
-
)
|
|
412
|
-
|
|
413
|
-
def getTranslationVector(self):
|
|
414
|
-
"""
|
|
415
|
-
getTranslationVector()
|
|
416
|
-
|
|
417
|
-
Returns the translation defining this reference frame (from self.ref to self)
|
|
418
|
-
"""
|
|
419
|
-
return self.transformation[:3, 3]
|
|
420
|
-
|
|
421
|
-
def getRotationVector(self, degrees=True, active=_ACTIVE_DEFAULT):
|
|
422
|
-
"""
|
|
423
|
-
getRotationVector()
|
|
424
|
-
|
|
425
|
-
Returns the rotation (vector) defining this reference frame (from self.ref to self)
|
|
426
|
-
degrees : if true, rotation angles are expressed in degrees
|
|
427
|
-
"""
|
|
428
|
-
rotation = t3.euler.mat2euler(self.transformation, axes=self.rot_config)
|
|
429
|
-
if degrees:
|
|
430
|
-
rotation = np.array([np.rad2deg(item) for item in rotation])
|
|
431
|
-
return rotation
|
|
432
|
-
|
|
433
|
-
def getTranslationRotationVectors(self, degrees=True, active=_ACTIVE_DEFAULT):
|
|
434
|
-
"""getTranslationRotationVectors()
|
|
435
|
-
Returns the translation and rotation (vectors) defining this reference frame (from self.ref to self)
|
|
436
|
-
degrees : if true, rotation angles are expressed in degrees
|
|
437
|
-
"""
|
|
438
|
-
translation = self.getTranslationVector()
|
|
439
|
-
rotation = self.getRotationVector(degrees=degrees, active=active)
|
|
440
|
-
return translation, rotation
|
|
441
|
-
|
|
442
|
-
def getRotationMatrix(self):
|
|
443
|
-
"""
|
|
444
|
-
getRotationMatrix()
|
|
445
|
-
|
|
446
|
-
Returns the rotation (matrix) defining this reference frame (from self.ref to self)
|
|
447
|
-
"""
|
|
448
|
-
result = self.transformation.copy()
|
|
449
|
-
result[:3, 3] = [0.0, 0.0, 0.0]
|
|
450
|
-
return result
|
|
451
|
-
|
|
452
|
-
def __repr__(self):
|
|
453
|
-
return f"ReferenceFrame(transformation={transformationToString(self.transformation)}, ref={self.ref.name}, name={self.name}, rot_config={self.rot_config})"
|
|
454
|
-
|
|
455
|
-
def __str__(self):
|
|
456
|
-
msg = textwrap.dedent(
|
|
457
|
-
f"""\
|
|
458
|
-
ReferenceFrame
|
|
459
|
-
name : {self.name}
|
|
460
|
-
reference : {self.ref.name}
|
|
461
|
-
rot_config : {self.rot_config}
|
|
462
|
-
links : {[key.name for key in self.linkedTo.keys()]}
|
|
463
|
-
transformation:
|
|
464
|
-
[{np.round(self.transformation[0], 3)}
|
|
465
|
-
{np.round(self.transformation[1], 3)}
|
|
466
|
-
{np.round(self.transformation[2], 3)}
|
|
467
|
-
{np.round(self.transformation[3], 3)}]
|
|
468
|
-
translation : {np.round(self.getTranslationVector(),3)}
|
|
469
|
-
rotation : {np.round(self.getRotationVector(),3)}"""
|
|
470
|
-
)
|
|
471
|
-
return msg
|
|
472
|
-
|
|
473
|
-
@deprecate(
|
|
474
|
-
reason=(
|
|
475
|
-
"I do not see the added value of changing the name and "
|
|
476
|
-
"the current method has the side effect to change the name "
|
|
477
|
-
"to a random string when the name argument is already used."
|
|
478
|
-
),
|
|
479
|
-
alternative="the constructor argument to set the name already of the object.",
|
|
480
|
-
)
|
|
481
|
-
def setName(self, name=None):
|
|
482
|
-
"""
|
|
483
|
-
Set or change the name of a reference frame.
|
|
484
|
-
|
|
485
|
-
..note: this method is deprecated
|
|
486
|
-
|
|
487
|
-
:param str name: the new name for the reference frame, if None, a random name will be generated.
|
|
488
|
-
|
|
489
|
-
:raises InvalidOperationError: when you try to change the name of the Master reference frame
|
|
490
|
-
"""
|
|
491
|
-
if self.isMaster():
|
|
492
|
-
raise InvalidOperationError(
|
|
493
|
-
"You try to change the name of the Master reference frame, which is not allowed."
|
|
494
|
-
)
|
|
495
|
-
self.name = self.__createName(name)
|
|
496
|
-
|
|
497
|
-
def addLink(self, ref, transformation=None, _stop=False):
|
|
498
|
-
"""
|
|
499
|
-
adds a link between self and ref in self.linkedTo and ref.linkedTo
|
|
500
|
-
"""
|
|
501
|
-
|
|
502
|
-
# DONE: set the inverse transformation in the ref to this
|
|
503
|
-
# ref.linkedTo[self] = t3add.affine_inverse(transformation)
|
|
504
|
-
# TODO:
|
|
505
|
-
# remove the _stop keyword
|
|
506
|
-
|
|
507
|
-
# TODO: deprecate transformation as an input variable
|
|
508
|
-
# linkedTo can become a list of reference frames, with no transformation
|
|
509
|
-
# associated to the link. The tfo associated to a link is already
|
|
510
|
-
# checked in real time whenever the link is addressed
|
|
511
|
-
if transformation is None:
|
|
512
|
-
transformation = self.getActiveTransformationTo(ref)
|
|
513
|
-
else:
|
|
514
|
-
LOGGER.info("Deprecation warning: transformation will be automatically set to "
|
|
515
|
-
"the current relation between {self.name} and {ref.name}")
|
|
516
|
-
LOGGER.flash_flood("Requested:")
|
|
517
|
-
LOGGER.flash_flood(np.round(transformation, decimals=3))
|
|
518
|
-
LOGGER.flash_flood("Auto (enforced):")
|
|
519
|
-
|
|
520
|
-
transformation = self.getActiveTransformationTo(ref)
|
|
521
|
-
|
|
522
|
-
LOGGER.flash_flood(np.round(transformation, decimals=3))
|
|
523
|
-
|
|
524
|
-
self.linkedTo[ref] = transformation
|
|
525
|
-
|
|
526
|
-
# TODO simplify this when transformation is deprecated
|
|
527
|
-
# it becomes ref.linkedTo[self] = ref.getActiveTransformationTo(self)
|
|
528
|
-
ref.linkedTo[self] = t3add.affine_inverse(transformation)
|
|
529
|
-
|
|
530
|
-
def removeLink(self, ref):
|
|
531
|
-
"""
|
|
532
|
-
Remove the link between self and ref, both ways.
|
|
533
|
-
"""
|
|
534
|
-
|
|
535
|
-
# First remove the entry in ref to this
|
|
536
|
-
|
|
537
|
-
if self in ref.linkedTo:
|
|
538
|
-
del ref.linkedTo[self]
|
|
539
|
-
|
|
540
|
-
# Then remove the entry in this to ref
|
|
541
|
-
|
|
542
|
-
if ref in self.linkedTo:
|
|
543
|
-
del self.linkedTo[ref]
|
|
544
|
-
|
|
545
|
-
def getPassiveTransformationTo(self, targetFrame):
|
|
546
|
-
"""
|
|
547
|
-
getPassiveTransformationTo(self,targetFrame)
|
|
548
|
-
== getPointTransformationTo(self,targetFrame)
|
|
549
|
-
|
|
550
|
-
returns the transformation to apply to a Point (defined in self) to express it in targetFrame
|
|
551
|
-
|
|
552
|
-
Passive transformation : the point is static, we change the reference frame around it
|
|
553
|
-
"""
|
|
554
|
-
LOGGER.flash_flood("PASSIVE TO self {self.name} target {targetFrame.name}")
|
|
555
|
-
if targetFrame is self:
|
|
556
|
-
"""
|
|
557
|
-
Nothing to do here, we already have the right coordinates
|
|
558
|
-
"""
|
|
559
|
-
LOGGER.flash_flood("case 1")
|
|
560
|
-
result = np.identity(4)
|
|
561
|
-
|
|
562
|
-
elif targetFrame.ref is self:
|
|
563
|
-
"""
|
|
564
|
-
The target frame is defined in self => the requested transformation is the targetFrame definition
|
|
565
|
-
"""
|
|
566
|
-
LOGGER.flash_flood("=== 2 start ===")
|
|
567
|
-
result = t3add.affine_inverse(targetFrame.transformation)
|
|
568
|
-
LOGGER.flash_flood("=== 2 end ===")
|
|
569
|
-
elif targetFrame.ref is self.ref:
|
|
570
|
-
"""
|
|
571
|
-
targetFrame and self are defined wrt the same reference frame
|
|
572
|
-
We want
|
|
573
|
-
self --> targetFrame
|
|
574
|
-
We know
|
|
575
|
-
targetFrame.ref --> targetFrame (= targetFrame.transformation)
|
|
576
|
-
self.ref --> self (= self.transformation)
|
|
577
|
-
That is
|
|
578
|
-
self --> self.ref is targetFrame.ref --> targetFrame
|
|
579
|
-
inverse(definition) targetFrame definition
|
|
580
|
-
|
|
581
|
-
"""
|
|
582
|
-
LOGGER.flash_flood("=== 3 start ===")
|
|
583
|
-
LOGGER.flash_flood(" ref \n{0}".format(self.ref))
|
|
584
|
-
LOGGER.flash_flood("===")
|
|
585
|
-
LOGGER.flash_flood("self \n{0}".format(self))
|
|
586
|
-
LOGGER.flash_flood("===")
|
|
587
|
-
LOGGER.flash_flood("targetFrame \n{0}".format(targetFrame))
|
|
588
|
-
LOGGER.flash_flood("===")
|
|
589
|
-
|
|
590
|
-
selfToRef = self.transformation
|
|
591
|
-
LOGGER.flash_flood("selfToRef \n{0}".format(selfToRef))
|
|
592
|
-
|
|
593
|
-
# refToRef = I
|
|
594
|
-
|
|
595
|
-
refToTarget = t3add.affine_inverse(targetFrame.transformation)
|
|
596
|
-
LOGGER.flash_flood("refToTarget \n{0}".format(refToTarget))
|
|
597
|
-
|
|
598
|
-
result = np.dot(refToTarget, selfToRef)
|
|
599
|
-
LOGGER.flash_flood("result \n{0}".format(result))
|
|
600
|
-
LOGGER.flash_flood("=== 3 end ===")
|
|
601
|
-
else:
|
|
602
|
-
"""
|
|
603
|
-
We are after the transformation from
|
|
604
|
-
self --> targetFrame
|
|
605
|
-
==
|
|
606
|
-
self --> self.ref --> targetFrame.ref --> targetFrame
|
|
607
|
-
|
|
608
|
-
We know
|
|
609
|
-
targetFrame.ref --> targetFrame (targetFrame.transformation)
|
|
610
|
-
self.ref --> self (self.transformation)
|
|
611
|
-
but
|
|
612
|
-
targetFrame.ref != self.ref
|
|
613
|
-
so we need
|
|
614
|
-
self.ref --> targetFrame.ref
|
|
615
|
-
then we can compose
|
|
616
|
-
self --> self.ref --> targetFrame.ref --> targetFrame
|
|
617
|
-
|
|
618
|
-
Note: the transformation self.ref --> targetFrame.ref is acquired recursively
|
|
619
|
-
This relies on the underlying assumption that there exists
|
|
620
|
-
one unique reference frame that source and self can be linked to
|
|
621
|
-
(without constraints on the number of links necessary), i.e.
|
|
622
|
-
that, from a frame to its reference or the opposite, there exists
|
|
623
|
-
a path between self and targetFrame. That is equivalent to
|
|
624
|
-
the assumption that the entire set of reference frames is connex,
|
|
625
|
-
i.e. defined upon a unique master reference frame.
|
|
626
|
-
"""
|
|
627
|
-
LOGGER.flash_flood("=== 4 start ===")
|
|
628
|
-
selfToRef = self.transformation
|
|
629
|
-
selfRefToTargetRef = self.ref.getPassiveTransformationTo(targetFrame.ref)
|
|
630
|
-
refToTarget = t3add.affine_inverse(targetFrame.transformation)
|
|
631
|
-
result = np.dot(refToTarget, np.dot(selfRefToTargetRef, selfToRef))
|
|
632
|
-
LOGGER.flash_flood("=== 4 end ===")
|
|
633
|
-
|
|
634
|
-
return result
|
|
635
|
-
|
|
636
|
-
def getPassiveTranslationRotationVectorsTo(
|
|
637
|
-
self, targetFrame, degrees=True
|
|
638
|
-
): # , active=_ACTIVE_DEFAULT):
|
|
639
|
-
"""
|
|
640
|
-
getPassiveTranslationRotationVectorsTo(self,ref,degrees=True)
|
|
641
|
-
|
|
642
|
-
extracts rotation vector from the result of getPassiveTransformationTo(target)
|
|
643
|
-
"""
|
|
644
|
-
transformation = self.getPassiveTransformationTo(targetFrame)
|
|
645
|
-
rotation = t3.euler.mat2euler(transformation, axes=self.rot_config)
|
|
646
|
-
if degrees:
|
|
647
|
-
rotation = np.array([np.rad2deg(item) for item in rotation])
|
|
648
|
-
translation = transformation[:3, 3]
|
|
649
|
-
return translation, rotation
|
|
650
|
-
|
|
651
|
-
def getPassiveTranslationVectorTo(self, targetFrame, degrees=True):
|
|
652
|
-
"""
|
|
653
|
-
getPassiveTranslationRotationVectorsTo(self,ref,degrees=True)
|
|
654
|
-
|
|
655
|
-
extracts translation vector from the result of getPassiveTransformationTo(target)
|
|
656
|
-
"""
|
|
657
|
-
return self.getPassiveTranslationRotationVectorsTo(targetFrame, degrees=degrees)[0]
|
|
658
|
-
|
|
659
|
-
def getPassiveRotationVectorTo(self, targetFrame, degrees=True):
|
|
660
|
-
"""
|
|
661
|
-
getPassiveTranslationRotationVectorsTo(self,targetFrame,degrees=True)
|
|
662
|
-
|
|
663
|
-
extracts rotation vector from the result of getPassiveTransformationTo(targetFrame)
|
|
664
|
-
"""
|
|
665
|
-
return self.getPassiveTranslationRotationVectorsTo(targetFrame, degrees=degrees)[1]
|
|
666
|
-
|
|
667
|
-
def getPassiveTransformationFrom(self, source):
|
|
668
|
-
"""
|
|
669
|
-
getPassiveTransformationFrom(self,source)
|
|
670
|
-
== getPointTransformationTo(self,source)
|
|
671
|
-
|
|
672
|
-
INPUT
|
|
673
|
-
source : is a ReferenceFrame object
|
|
674
|
-
|
|
675
|
-
OUTPUT
|
|
676
|
-
returns the transformation matrix that, applied to a point defined
|
|
677
|
-
in source returns its coordinates in self
|
|
678
|
-
"""
|
|
679
|
-
LOGGER.flash_flood("PASSIVE FROM self {self.name} source {source.name}")
|
|
680
|
-
return source.getPassiveTransformationTo(self)
|
|
681
|
-
|
|
682
|
-
def getPassiveTranslationRotationVectorsFrom(
|
|
683
|
-
self, source, degrees=True
|
|
684
|
-
): # , active=_ACTIVE_DEFAULT):
|
|
685
|
-
"""
|
|
686
|
-
getPassiveTranslationRotationVectorsFrom(self,source, degrees=True)
|
|
687
|
-
|
|
688
|
-
extracts rotation vector from the result of getPassiveTransformationTo(target)
|
|
689
|
-
"""
|
|
690
|
-
transformation = self.getPassiveTransformationFrom(source)
|
|
691
|
-
rotation = t3.euler.mat2euler(transformation, axes=self.rot_config)
|
|
692
|
-
if degrees:
|
|
693
|
-
rotation = np.array([np.rad2deg(item) for item in rotation])
|
|
694
|
-
translation = transformation[:3, 3]
|
|
695
|
-
return translation, rotation
|
|
696
|
-
|
|
697
|
-
def getPassiveTranslationVectorFrom(self, source, degrees=True):
|
|
698
|
-
"""
|
|
699
|
-
getPassiveTranslationVectorFrom(self,source, degrees=True)
|
|
700
|
-
|
|
701
|
-
extracts translation vector from the result of getPassiveTransformationFrom(source)
|
|
702
|
-
"""
|
|
703
|
-
return self.getPassiveTranslationRotationVectorsFrom(source, degrees=degrees)[0]
|
|
704
|
-
|
|
705
|
-
def getPassiveRotationVectorFrom(self, source, degrees=True):
|
|
706
|
-
"""
|
|
707
|
-
getPassiveTranslationRotationVectorsFrom(self,source,degrees=True)
|
|
708
|
-
|
|
709
|
-
extracts rotation vector from the result of getPassiveTransformationFrom(source)
|
|
710
|
-
"""
|
|
711
|
-
return self.getPassiveTranslationRotationVectorsFrom(source, degrees=degrees)[1]
|
|
712
|
-
|
|
713
|
-
def getActiveTransformationTo(self, target):
|
|
714
|
-
"""
|
|
715
|
-
Return the transformation matrix from this reference frame (``self``) to
|
|
716
|
-
the target reference frame.
|
|
717
|
-
|
|
718
|
-
Applying this transformation to the ``self`` ReferenceFrame would render it
|
|
719
|
-
identical to target.
|
|
720
|
-
|
|
721
|
-
Applying this transformation to a point defined in ``self`` would move it to
|
|
722
|
-
the same coordinates in target.
|
|
723
|
-
|
|
724
|
-
:param target: is a ReferenceFrame object
|
|
725
|
-
|
|
726
|
-
:return: the transformation matrix that defines the reference frame ``target``
|
|
727
|
-
in ``self``, the current reference frame. The transformation from self
|
|
728
|
-
to target
|
|
729
|
-
|
|
730
|
-
"""
|
|
731
|
-
LOGGER.flash_flood("ACTIVE TO self {self.name} target {target.name}")
|
|
732
|
-
return target.getPassiveTransformationTo(self)
|
|
733
|
-
|
|
734
|
-
def getActiveTranslationRotationVectorsTo(
|
|
735
|
-
self, targetFrame, degrees=True
|
|
736
|
-
): # ,active=_ACTIVE_DEFAULT):
|
|
737
|
-
"""
|
|
738
|
-
getActiveTranslationRotationVectorsTo(self,ref,degrees=True)
|
|
739
|
-
|
|
740
|
-
extracts rotation vector from the result of getActiveTransformationTo(target)
|
|
741
|
-
"""
|
|
742
|
-
transformation = self.getActiveTransformationTo(targetFrame)
|
|
743
|
-
rotation = t3.euler.mat2euler(transformation, axes=self.rot_config)
|
|
744
|
-
if degrees:
|
|
745
|
-
rotation = np.array([np.rad2deg(item) for item in rotation])
|
|
746
|
-
translation = transformation[:3, 3]
|
|
747
|
-
return translation, rotation
|
|
748
|
-
|
|
749
|
-
def getActiveTranslationVectorTo(self, targetFrame, degrees=True):
|
|
750
|
-
"""
|
|
751
|
-
getActiveTranslationRotationVectorsTo(self,ref,degrees=True)
|
|
752
|
-
|
|
753
|
-
extracts translation vector from the result of getActiveTransformationTo(target)
|
|
754
|
-
"""
|
|
755
|
-
return self.getActiveTranslationRotationVectorsTo(targetFrame, degrees=degrees)[0]
|
|
756
|
-
|
|
757
|
-
def getActiveRotationVectorTo(self, targetFrame, degrees=True):
|
|
758
|
-
"""
|
|
759
|
-
getActiveTranslationRotationVectorsTo(self,targetFrame,degrees=True)
|
|
760
|
-
|
|
761
|
-
extracts rotation vector from the result of getActiveTransformationTo(targetFrame)
|
|
762
|
-
"""
|
|
763
|
-
return self.getActiveTranslationRotationVectorsTo(targetFrame, degrees=degrees)[1]
|
|
764
|
-
|
|
765
|
-
def getActiveTransformationFrom(self, source):
|
|
766
|
-
"""
|
|
767
|
-
Applying this transformation to the ``source`` ReferenceFrame
|
|
768
|
-
would render it identical to self.
|
|
769
|
-
|
|
770
|
-
Applying this transformation to a point defined in source
|
|
771
|
-
would move it to the same coordinates in self.
|
|
772
|
-
|
|
773
|
-
:param source: is a ReferenceFrame object
|
|
774
|
-
|
|
775
|
-
:return: the transformation matrix that defines this reference frame in ``source``,
|
|
776
|
-
i.e. the transformation from ``source`` to ``self``
|
|
777
|
-
|
|
778
|
-
"""
|
|
779
|
-
LOGGER.flash_flood("ACTIVE FROM self {self.name} source {source.name}")
|
|
780
|
-
return self.getPassiveTransformationTo(source)
|
|
781
|
-
|
|
782
|
-
def getActiveTranslationRotationVectorsFrom(
|
|
783
|
-
self, source, degrees=True
|
|
784
|
-
): # ,active=_ACTIVE_DEFAULT):
|
|
785
|
-
"""
|
|
786
|
-
getActiveTranslationRotationVectorsFrom(self,source, degrees=True)
|
|
787
|
-
|
|
788
|
-
extracts rotation vector from the result of getActiveTransformationTo(target)
|
|
789
|
-
"""
|
|
790
|
-
transformation = self.getActiveTransformationFrom(source)
|
|
791
|
-
rotation = t3.euler.mat2euler(transformation, axes=self.rot_config)
|
|
792
|
-
if degrees:
|
|
793
|
-
rotation = np.array([np.rad2deg(item) for item in rotation])
|
|
794
|
-
translation = transformation[:3, 3]
|
|
795
|
-
return translation, rotation
|
|
796
|
-
|
|
797
|
-
def getActiveTranslationVectorFrom(self, source, degrees=True):
|
|
798
|
-
"""
|
|
799
|
-
getActiveTranslationVectorFrom(self,source, degrees=True)
|
|
800
|
-
|
|
801
|
-
extracts translation vector from the result of getActiveTransformationFrom(source)
|
|
802
|
-
"""
|
|
803
|
-
return self.getActiveTranslationRotationVectorsFrom(source, degrees=degrees)[0]
|
|
804
|
-
|
|
805
|
-
def getActiveRotationVectorFrom(self, source, degrees=True):
|
|
806
|
-
"""
|
|
807
|
-
getActiveTranslationRotationVectorsFrom(self,source,degrees=True)
|
|
808
|
-
|
|
809
|
-
extracts rotation vector from the result of getActiveTransformationFrom(source)
|
|
810
|
-
"""
|
|
811
|
-
return self.getActiveTranslationRotationVectorsFrom(source, degrees=degrees)[1]
|
|
812
|
-
|
|
813
|
-
def _findEnds(self, frame, visited=[], ends=[], verbose=True, level=1):
|
|
814
|
-
"""
|
|
815
|
-
PURPOSE
|
|
816
|
-
Identify the 'linked_frames':
|
|
817
|
-
frames that are linked, either directly or indirectly (via mult. links) to "frame"
|
|
818
|
-
--> returned as visited
|
|
819
|
-
Identify subset of 'linked_frames of which the reference does not belong to linked_frames
|
|
820
|
-
--> returned as 'finalEnds'
|
|
821
|
-
"""
|
|
822
|
-
LOGGER.flash_flood(
|
|
823
|
-
f"{level:-2d}{2*level*' '} Current: {frame.name} -- ends: {[f.name for f in ends]} -- visited {[f.name for f in visited]}"
|
|
824
|
-
)
|
|
825
|
-
# if verbose: print (f"{level:-2d}{2*level*' '} Current: {frame.name} -- ends: {[f.name for f in ends]} -- visited {[f.name for f in visited]}")
|
|
826
|
-
|
|
827
|
-
# Establish the set of 'linked_frames' (variable 'visited')
|
|
828
|
-
# The recursive process below keeps unwanted (non-endFrames), namely the
|
|
829
|
-
# frames that are not directly, but well indirectly linked to their reference
|
|
830
|
-
# This case is solved further down
|
|
831
|
-
if frame not in visited:
|
|
832
|
-
visited.append(frame)
|
|
833
|
-
if verbose and level:
|
|
834
|
-
level += 1
|
|
835
|
-
if frame.ref not in frame.linkedTo:
|
|
836
|
-
ends.append(frame)
|
|
837
|
-
LOGGER.flash_flood(f"{(10+2*level)*' '}{frame.name}: new end")
|
|
838
|
-
# if verbose: LOGGER.info(f"{(10+2*level)*' '}{frame.name}: new end")
|
|
839
|
-
for linkedFrame in frame.linkedTo:
|
|
840
|
-
ends, visited = self._findEnds(
|
|
841
|
-
linkedFrame, visited=visited, ends=ends, verbose=verbose, level=level
|
|
842
|
-
)
|
|
843
|
-
|
|
844
|
-
# If frame.ref was linked to frame via an indirect route, reject it
|
|
845
|
-
finalEnds = []
|
|
846
|
-
for aframe in ends:
|
|
847
|
-
if aframe.ref not in ends:
|
|
848
|
-
finalEnds.append(aframe)
|
|
849
|
-
return finalEnds, visited
|
|
850
|
-
|
|
851
|
-
def setTransformation(
|
|
852
|
-
self, transformation, updated=None, preserveLinks=True, _relative=False, verbose=True
|
|
853
|
-
):
|
|
854
|
-
"""
|
|
855
|
-
setTransformation(self,transformation, updated=None, preserveLinks=True,_relative=False, verbose=True)
|
|
856
|
-
|
|
857
|
-
Alter the definition of this coordinate system
|
|
858
|
-
|
|
859
|
-
If other systems are linked to this one, their definition must be updated accordingly
|
|
860
|
-
The link set between two ref. Frames A & B is the active transformation matrix from A to B
|
|
861
|
-
A.addLink(B, matrix)
|
|
862
|
-
A.getActiveTransformationTo(B) --> matrix
|
|
863
|
-
|
|
864
|
-
The way to update the definition of the present system, and of those linked to it
|
|
865
|
-
depends on the structure of those links.
|
|
866
|
-
|
|
867
|
-
We define
|
|
868
|
-
- the target frame as the one we want to move / redefine
|
|
869
|
-
- 'linkedFrames' as those directly, or indirectly (i.e. via multiple links)
|
|
870
|
-
linked to the target frame
|
|
871
|
-
- endFrames as the subset of linkedFrames which are not linked to their reference (directly or indirectly)
|
|
872
|
-
- sideFrames as the set of frames whose reference is a linkedFrame, but not themselves belonging to the linkedFrames
|
|
873
|
-
|
|
874
|
-
We can demonstrate that updating the endFrames (Block A below) is sufficient to represent
|
|
875
|
-
the movement of the target frame and all frames directly or indirectly linked to it.
|
|
876
|
-
|
|
877
|
-
This may nevertheless have perverse effects for sideFrames. Indeed,
|
|
878
|
-
their reference will (directly or implicitely) be redefined, but they shouldn't:
|
|
879
|
-
they are not linked to their reference --> their location in space (e.g. wrt the master frame)
|
|
880
|
-
should not be affected by the movement of the target frame. This is the aim of block B.
|
|
881
|
-
|
|
882
|
-
For a completely robust solution, 2 steps must be taken
|
|
883
|
-
BLOCK A. apply the rigt transformation to all "endFrames"
|
|
884
|
-
BLOCK B. Check for frames
|
|
885
|
-
using any of the "visited" frames as a reference
|
|
886
|
-
not linked to its reference
|
|
887
|
-
Correct its so that it doesn't move (it shouldn't be affected by the requested movement)
|
|
888
|
-
This demands a "referenceFor" array property
|
|
889
|
-
|
|
890
|
-
"""
|
|
891
|
-
# Ruthless, enforced redefinition of one system. Know what you do, or stay away.
|
|
892
|
-
# Semi-unpredictible side effets if the impacted frame has links!
|
|
893
|
-
if preserveLinks == False:
|
|
894
|
-
self.transformation = transformation
|
|
895
|
-
return
|
|
896
|
-
|
|
897
|
-
if updated is None:
|
|
898
|
-
updated = []
|
|
899
|
-
|
|
900
|
-
# visitedFrames = all frames which can be reached from self via invariant links
|
|
901
|
-
# endFrames = subset of visitedFrames that are at the end of a chain, and must be updated
|
|
902
|
-
# in order to properly represent the requested movement
|
|
903
|
-
endFrames, visitedFrames = self._findEnds(frame=self, visited=[], ends=[], verbose=verbose)
|
|
904
|
-
if verbose:
|
|
905
|
-
LOGGER.info(
|
|
906
|
-
f"Visited sub-system {[f.name for f in visitedFrames]}"
|
|
907
|
-
)
|
|
908
|
-
LOGGER.info(f"End-frames (movement necessary) {[f.name for f in endFrames]}")
|
|
909
|
-
|
|
910
|
-
# All updates are done by relative movements
|
|
911
|
-
# so we must first compute the relative movement corresponding to the requested absolute movement
|
|
912
|
-
if _relative == False:
|
|
913
|
-
## virtual = what self should become after the (absolute) movement
|
|
914
|
-
## it allows to compute the relative transformation to be applied and work in relative further down
|
|
915
|
-
virtual = ReferenceFrame(
|
|
916
|
-
transformation, ref=self.ref, name="virtual", rot_config=self.rot_config
|
|
917
|
-
)
|
|
918
|
-
request = self.getActiveTransformationTo(virtual)
|
|
919
|
-
del virtual
|
|
920
|
-
else:
|
|
921
|
-
# If this method is called by applyTransformation,
|
|
922
|
-
# we are facing a request for a relative movement
|
|
923
|
-
# In that case the input is directly what we want
|
|
924
|
-
request = transformation
|
|
925
|
-
|
|
926
|
-
# BLOCK B. Check for frames that were impacted but shouldn't have been and correct them
|
|
927
|
-
# B1. List of frames demanding a correction
|
|
928
|
-
# 'impacted' are frames having their reference inside the rigid structure moving, but not linked to it
|
|
929
|
-
# If nothing is done, the movement will implicitely displace them, which is not intended
|
|
930
|
-
|
|
931
|
-
### Impacted shall not contain frames that are linked to self (== to any frame in visitedFrames) via any route...
|
|
932
|
-
### We check if the impacted frames are in visitedFrames:
|
|
933
|
-
### it is enough to know it's connected to the entire 'solid body' in which self belongs
|
|
934
|
-
impacted = []
|
|
935
|
-
for frame in visitedFrames:
|
|
936
|
-
for child in frame.referenceFor:
|
|
937
|
-
# Version 1 : too simple (restores too many frames)
|
|
938
|
-
#if child not in frame.linkedTo:
|
|
939
|
-
|
|
940
|
-
# Version 2 : overkill
|
|
941
|
-
#child_ends, child_visited = child._findEnds(frame=child,visited=[],ends=[],verbose=verbose)
|
|
942
|
-
#if frame not in child_visited:
|
|
943
|
-
|
|
944
|
-
# Version 3 : just check if the child belongs to the rigid structure...
|
|
945
|
-
if child not in visitedFrames:
|
|
946
|
-
impacted.append(child)
|
|
947
|
-
|
|
948
|
-
LOGGER.debug(f"Impacted (not moving, defined in moving) {[f.name for f in impacted]}")
|
|
949
|
-
|
|
950
|
-
# B2. save the location of all impacted frames
|
|
951
|
-
# tempReference has the only purpose of avoiding that every frame must know the master
|
|
952
|
-
# It could be any frame without links and defined wrt the master, but the master isn't known here...
|
|
953
|
-
# TODO : confirm that the master isn't known (e.g. via cls._MASTER)
|
|
954
|
-
tempMaster = self.findMaster()
|
|
955
|
-
toRestore = {}
|
|
956
|
-
for frame in impacted:
|
|
957
|
-
toRestore[frame] = ReferenceFrame(
|
|
958
|
-
frame.getActiveTransformationFrom(tempMaster),
|
|
959
|
-
ref=tempMaster,
|
|
960
|
-
name=frame.name + "toRestore",
|
|
961
|
-
rot_config=frame.rot_config,
|
|
962
|
-
)
|
|
963
|
-
|
|
964
|
-
# BLOCK A. apply the rigt transformation to all "endFrames"
|
|
965
|
-
"""
|
|
966
|
-
### Ensure that "Untouched" remains unaffected regardless of the update order of the endFrames
|
|
967
|
-
selfUntouched = ReferenceFrame(
|
|
968
|
-
transformation = self.getActiveTransformationFrom(tempMaster),
|
|
969
|
-
ref=tempMaster,
|
|
970
|
-
name=self.name + "_fixed",
|
|
971
|
-
rot_config=self.rot_config,
|
|
972
|
-
)
|
|
973
|
-
"""
|
|
974
|
-
|
|
975
|
-
selfUntouched = ReferenceFrame(
|
|
976
|
-
transformation=self.transformation,
|
|
977
|
-
ref=self.ref,
|
|
978
|
-
name=self.name + "_fixed",
|
|
979
|
-
rot_config=self.rot_config,
|
|
980
|
-
)
|
|
981
|
-
|
|
982
|
-
for bottom in endFrames:
|
|
983
|
-
|
|
984
|
-
up = bottom.getActiveTransformationTo(selfUntouched)
|
|
985
|
-
down = selfUntouched.getActiveTransformationTo(bottom)
|
|
986
|
-
|
|
987
|
-
relativeTransformation = up @ request @ down
|
|
988
|
-
|
|
989
|
-
LOGGER.flash_flood(
|
|
990
|
-
f"\nAdjusting {bottom.name} to {self.name}\nUpdated {[i.name for i in updated]}"
|
|
991
|
-
)
|
|
992
|
-
LOGGER.flash_flood(f"\ninput transformation \n{np.round(transformation,3)}")
|
|
993
|
-
LOGGER.flash_flood(
|
|
994
|
-
f"\nup \n{np.round(up,3)}\ntransformation\n{np.round(request,3)}\ndown\n{np.round(down,3)}"
|
|
995
|
-
)
|
|
996
|
-
LOGGER.flash_flood(f"\nrelativeTransformation \n{np.round(relativeTransformation,3)}")
|
|
997
|
-
|
|
998
|
-
bottom.transformation = bottom.transformation @ relativeTransformation
|
|
999
|
-
|
|
1000
|
-
updated.append(bottom)
|
|
1001
|
-
|
|
1002
|
-
for frame in visitedFrames:
|
|
1003
|
-
if frame not in updated:
|
|
1004
|
-
updated.append(frame)
|
|
1005
|
-
|
|
1006
|
-
# Block B
|
|
1007
|
-
# B3. Correction
|
|
1008
|
-
# we must set preserveLinks to False to prevent cascading impact from this update
|
|
1009
|
-
# if X1 is impacted with
|
|
1010
|
-
# X1.ref = E1 X1 --> X2 (simple link) E2.ref = X2
|
|
1011
|
-
# where X1 and X2 are "external frames" and E1 and E2 are "endFrames" that will hence move
|
|
1012
|
-
# X1 was impacted by the move of E1, but X2 wasn't
|
|
1013
|
-
# ==> wrt master, neither X1 nor X2 should have moved, but X1 did (via its ref)
|
|
1014
|
-
# and hence its link with X2 is now corrupt
|
|
1015
|
-
# We need to move X1 back to its original location wrt master
|
|
1016
|
-
# if we preserved the links while doing that,
|
|
1017
|
-
# we will move X2, which shouldn't move
|
|
1018
|
-
# (it didn't have to, it didn't and the goal is to restore the validity of the links)
|
|
1019
|
-
#
|
|
1020
|
-
# Direct restoration or the impacted frames at their original location
|
|
1021
|
-
|
|
1022
|
-
for frame in toRestore:
|
|
1023
|
-
frame.transformation = frame.ref.getActiveTransformationTo(toRestore[frame])
|
|
1024
|
-
|
|
1025
|
-
del toRestore
|
|
1026
|
-
|
|
1027
|
-
return
|
|
1028
|
-
|
|
1029
|
-
def setTranslationRotation(
|
|
1030
|
-
self,
|
|
1031
|
-
translation,
|
|
1032
|
-
rotation,
|
|
1033
|
-
rot_config=_ROT_CONFIG_DEFAULT,
|
|
1034
|
-
active=_ACTIVE_DEFAULT,
|
|
1035
|
-
degrees=True,
|
|
1036
|
-
preserveLinks=True,
|
|
1037
|
-
):
|
|
1038
|
-
"""
|
|
1039
|
-
setTranslationRotation(self,translation,rotation,rot_config=_ROT_CONFIG_DEFAULT, active=_ACTIVE_DEFAULT, degrees=True, preserveLinks=True)
|
|
1040
|
-
|
|
1041
|
-
Same as setTransformation, but input = translation and rotation vectors rather than affine transformation matrix
|
|
1042
|
-
"""
|
|
1043
|
-
# Translation
|
|
1044
|
-
translation = np.array(translation)
|
|
1045
|
-
# Zoom - unit
|
|
1046
|
-
zdef = np.array([1, 1, 1])
|
|
1047
|
-
# Shear
|
|
1048
|
-
sdef = np.array([0, 0, 0])
|
|
1049
|
-
# Rotation
|
|
1050
|
-
if degrees:
|
|
1051
|
-
rotation = np.array([np.deg2rad(item) for item in rotation])
|
|
1052
|
-
|
|
1053
|
-
rotx, roty, rotz = rotation
|
|
1054
|
-
|
|
1055
|
-
rmat = RotationMatrix(rotx, roty, rotz, rot_config=rot_config, active=active)
|
|
1056
|
-
|
|
1057
|
-
LOGGER.flash_flood(t3.affines.compose(translation, rmat.R, Z=zdef, S=sdef))
|
|
1058
|
-
|
|
1059
|
-
transformation = t3.affines.compose(translation, rmat.R, Z=zdef, S=sdef)
|
|
1060
|
-
|
|
1061
|
-
self.setTransformation(transformation, preserveLinks=preserveLinks, _relative=False)
|
|
1062
|
-
return
|
|
1063
|
-
|
|
1064
|
-
def applyTransformation(self, transformation, updated=None, preserveLinks=True):
|
|
1065
|
-
"""
|
|
1066
|
-
applyTransformation(self,transformation)
|
|
1067
|
-
|
|
1068
|
-
Applies the transformation to the current reference frame's definition
|
|
1069
|
-
|
|
1070
|
-
self.transformation := transformation @ self.transformation
|
|
1071
|
-
"""
|
|
1072
|
-
if updated is None:
|
|
1073
|
-
updated = []
|
|
1074
|
-
|
|
1075
|
-
self.setTransformation(
|
|
1076
|
-
transformation=transformation,
|
|
1077
|
-
updated=updated,
|
|
1078
|
-
preserveLinks=preserveLinks,
|
|
1079
|
-
_relative=True,
|
|
1080
|
-
)
|
|
1081
|
-
|
|
1082
|
-
def applyTranslationRotation(
|
|
1083
|
-
self,
|
|
1084
|
-
translation,
|
|
1085
|
-
rotation,
|
|
1086
|
-
rot_config=None,
|
|
1087
|
-
active=_ACTIVE_DEFAULT,
|
|
1088
|
-
degrees=True,
|
|
1089
|
-
preserveLinks=True,
|
|
1090
|
-
):
|
|
1091
|
-
"""
|
|
1092
|
-
applyTranslationRotation(self,translation,rotation,rot_config=None,active=_ACTIVE_DEFAULT,degrees=True, preserveLinks=True)
|
|
1093
|
-
|
|
1094
|
-
Builds transformation from input translation and rotation, then applies this transformation
|
|
1095
|
-
"""
|
|
1096
|
-
if rot_config is None:
|
|
1097
|
-
rot_config = self.rot_config
|
|
1098
|
-
|
|
1099
|
-
# Translation
|
|
1100
|
-
translation = np.array(translation)
|
|
1101
|
-
# Zoom - unit
|
|
1102
|
-
zdef = np.array([1, 1, 1])
|
|
1103
|
-
# Shear
|
|
1104
|
-
sdef = np.array([0, 0, 0])
|
|
1105
|
-
# Rotation
|
|
1106
|
-
if degrees:
|
|
1107
|
-
rotation = np.array([np.deg2rad(item) for item in rotation])
|
|
1108
|
-
rotx, roty, rotz = rotation
|
|
1109
|
-
#
|
|
1110
|
-
rmat = RotationMatrix(rotx, roty, rotz, rot_config=rot_config, active=active)
|
|
1111
|
-
#
|
|
1112
|
-
transformation = t3.affines.compose(translation, rmat.R, Z=zdef, S=sdef)
|
|
1113
|
-
#
|
|
1114
|
-
self.applyTransformation(transformation, preserveLinks=preserveLinks)
|
|
1115
|
-
return
|
|
1116
|
-
|
|
1117
|
-
def getAxis(self, axis, name=None):
|
|
1118
|
-
"""
|
|
1119
|
-
INPUT
|
|
1120
|
-
axis : in ['x','y','z']
|
|
1121
|
-
|
|
1122
|
-
OUTPUT
|
|
1123
|
-
Returns an object of class Point, corresponding to the vector defining
|
|
1124
|
-
the axis of choice in self.
|
|
1125
|
-
The output can be used with the Point methods to express that axis in any reference frame
|
|
1126
|
-
"""
|
|
1127
|
-
haxis = {}
|
|
1128
|
-
haxis["x"] = [1, 0, 0]
|
|
1129
|
-
haxis["y"] = [0, 1, 0]
|
|
1130
|
-
haxis["z"] = [0, 0, 1]
|
|
1131
|
-
if name is None:
|
|
1132
|
-
name = self.name + axis
|
|
1133
|
-
return Point(haxis[axis], ref=self, name=name)
|
|
1134
|
-
|
|
1135
|
-
def getNormal(self, name=None):
|
|
1136
|
-
"""
|
|
1137
|
-
getNormal(self,name=None)
|
|
1138
|
-
|
|
1139
|
-
Returns a unit vector normal to the X-Y plane (= [0,0,1] = getAxis('z'))
|
|
1140
|
-
"""
|
|
1141
|
-
return Point([0, 0, 1], ref=self, name=name)
|
|
1142
|
-
|
|
1143
|
-
def getOrigin(self, name=None):
|
|
1144
|
-
"""
|
|
1145
|
-
OUTPUT
|
|
1146
|
-
Returns an object of class Point, corresponding to the vector defining the origin in 'self', i.e. [0,0,0]
|
|
1147
|
-
The output can be used with the Point methods to express that axis in any reference frame
|
|
1148
|
-
"""
|
|
1149
|
-
return Point([0, 0, 0], ref=self, name=name)
|
|
1150
|
-
|
|
1151
|
-
def is_master(self):
|
|
1152
|
-
return self.isMaster()
|
|
1153
|
-
|
|
1154
|
-
def isMaster(self):
|
|
1155
|
-
"""
|
|
1156
|
-
A Master reference frame is a reference frame that refers to itself, and the
|
|
1157
|
-
transformation is the Identity matrix.
|
|
1158
|
-
"""
|
|
1159
|
-
tr = self.transformation
|
|
1160
|
-
|
|
1161
|
-
if (
|
|
1162
|
-
(self.name == self.ref.name)
|
|
1163
|
-
and (tr.shape[0] == tr.shape[1])
|
|
1164
|
-
and np.allclose(tr, np.eye(tr.shape[0]))
|
|
1165
|
-
):
|
|
1166
|
-
return True
|
|
1167
|
-
return False
|
|
1168
|
-
|
|
1169
|
-
def isSame(self, other):
|
|
1170
|
-
"""
|
|
1171
|
-
Returns True if the two reference frames are the same except for their name.
|
|
1172
|
-
|
|
1173
|
-
Two Reference Frames are considered the same when:
|
|
1174
|
-
|
|
1175
|
-
* their transformation matrices are equal
|
|
1176
|
-
* the reference frame is equal
|
|
1177
|
-
* the rot_config is equal
|
|
1178
|
-
* the name may be different
|
|
1179
|
-
|
|
1180
|
-
.. todo:: This needs further work and testing!
|
|
1181
|
-
"""
|
|
1182
|
-
|
|
1183
|
-
if other is self:
|
|
1184
|
-
LOGGER.debug(
|
|
1185
|
-
"self and other are the same object (beware: this message might occur with recursion from self.ref != self.other)"
|
|
1186
|
-
)
|
|
1187
|
-
return True
|
|
1188
|
-
|
|
1189
|
-
if isinstance(other, ReferenceFrame):
|
|
1190
|
-
LOGGER.flash_flood(f"comparing {self.name} and {other.name}")
|
|
1191
|
-
if not np.array_equal(self.transformation, other.transformation):
|
|
1192
|
-
LOGGER.flash_flood("self.transformation not equals other.transformation")
|
|
1193
|
-
return False
|
|
1194
|
-
if self.rot_config != other.rot_config:
|
|
1195
|
-
LOGGER.flash_flood("self.rot_config not equals other.rot_config")
|
|
1196
|
-
return False
|
|
1197
|
-
# The following tests are here to prevent recursion to go infinite when self and other
|
|
1198
|
-
# point to itself
|
|
1199
|
-
if self.ref is self and other.ref is other:
|
|
1200
|
-
LOGGER.flash_flood("both self.ref and other.ref point to themselves")
|
|
1201
|
-
pass
|
|
1202
|
-
else:
|
|
1203
|
-
LOGGER.flash_flood("one of self.ref or other.ref doesn't points to itself")
|
|
1204
|
-
if self.ref != other.ref:
|
|
1205
|
-
LOGGER.flash_flood("self.ref not equals other.ref")
|
|
1206
|
-
return False
|
|
1207
|
-
if self.name is not other.name:
|
|
1208
|
-
LOGGER.flash_flood(
|
|
1209
|
-
f"When checking two reference frames for equality, only their names differ: '{self.name}' not equals '{other.name}'"
|
|
1210
|
-
)
|
|
1211
|
-
pass
|
|
1212
|
-
return True
|
|
1213
|
-
return NotImplemented
|
|
1214
|
-
|
|
1215
|
-
def __eq__(self, other):
|
|
1216
|
-
"""
|
|
1217
|
-
Overrides the default implementation, which basically checks for id(self) == id(other).
|
|
1218
|
-
|
|
1219
|
-
Two Reference Frames are considered equal when:
|
|
1220
|
-
|
|
1221
|
-
* their transformation matrices are equal
|
|
1222
|
-
* the reference frame is equal
|
|
1223
|
-
* the rot_config is equal
|
|
1224
|
-
* do we want to insist on the name being equal?
|
|
1225
|
-
YES - for strict testing
|
|
1226
|
-
NO - this might need a new method like isSame(self, other) where the criteria are relaxed
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
.. todo:: This needs further work and testing!
|
|
1230
|
-
"""
|
|
1231
|
-
|
|
1232
|
-
if other is self:
|
|
1233
|
-
LOGGER.debug(
|
|
1234
|
-
"self and other are the same object (beware: this message might occur with recursion from self.ref != self.other)"
|
|
1235
|
-
)
|
|
1236
|
-
return True
|
|
1237
|
-
|
|
1238
|
-
if isinstance(other, ReferenceFrame):
|
|
1239
|
-
LOGGER.flash_flood(f"comparing {self.name} and {other.name}")
|
|
1240
|
-
if not np.array_equal(self.transformation, other.transformation):
|
|
1241
|
-
LOGGER.flash_flood("self.transformation not equals other.transformation")
|
|
1242
|
-
return False
|
|
1243
|
-
if self.rot_config != other.rot_config:
|
|
1244
|
-
LOGGER.flash_flood("self.rot_config not equals other.rot_config")
|
|
1245
|
-
return False
|
|
1246
|
-
# The following tests are here to prevent recursion to go infinite when self and other
|
|
1247
|
-
# point to itself
|
|
1248
|
-
if self.ref is self and other.ref is other:
|
|
1249
|
-
LOGGER.flash_flood("both self.ref and other.ref point to themselves")
|
|
1250
|
-
pass
|
|
1251
|
-
else:
|
|
1252
|
-
LOGGER.flash_flood("one of self.ref or other.ref doesn't points to itself")
|
|
1253
|
-
if self.ref != other.ref:
|
|
1254
|
-
LOGGER.flash_flood("self.ref not equals other.ref")
|
|
1255
|
-
return False
|
|
1256
|
-
if self.name is not other.name:
|
|
1257
|
-
LOGGER.flash_flood(
|
|
1258
|
-
f"When checking two reference frames for equality, only their names differ: '{self.name}' not equals '{other.name}'"
|
|
1259
|
-
)
|
|
1260
|
-
return False
|
|
1261
|
-
return True
|
|
1262
|
-
return NotImplemented
|
|
1263
|
-
|
|
1264
|
-
def __hash__(self):
|
|
1265
|
-
"""Overrides the default implementation"""
|
|
1266
|
-
hash_number = (id(self.rot_config) + id(self.ref) + id(self.name)) // 16
|
|
1267
|
-
return hash_number
|
|
1268
|
-
|
|
1269
|
-
def __copy__(self):
|
|
1270
|
-
|
|
1271
|
-
LOGGER.debug(
|
|
1272
|
-
f'Copying {self!r} unless {self.name} is "Master" in which case the Master itself is returned.'
|
|
1273
|
-
)
|
|
1274
|
-
|
|
1275
|
-
if self.isMaster():
|
|
1276
|
-
LOGGER.debug(f"Returning Master itself instead of a copy.")
|
|
1277
|
-
return self
|
|
1278
|
-
|
|
1279
|
-
return ReferenceFrame(self.transformation, self.ref, self.name, self.rot_config)
|