cgse 2023.38.0__py3-none-any.whl → 2024.1.4__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-2024.1.4.dist-info/METADATA +38 -0
- cgse-2024.1.4.dist-info/RECORD +5 -0
- {cgse-2023.38.0.dist-info → cgse-2024.1.4.dist-info}/WHEEL +1 -2
- cgse-2023.38.0.dist-info/COPYING +0 -674
- cgse-2023.38.0.dist-info/COPYING.LESSER +0 -165
- cgse-2023.38.0.dist-info/METADATA +0 -144
- cgse-2023.38.0.dist-info/RECORD +0 -649
- cgse-2023.38.0.dist-info/entry_points.txt +0 -75
- cgse-2023.38.0.dist-info/top_level.txt +0 -2
- egse/__init__.py +0 -12
- egse/__main__.py +0 -32
- egse/aeu/aeu.py +0 -5235
- egse/aeu/aeu_awg.yaml +0 -265
- egse/aeu/aeu_crio.yaml +0 -273
- egse/aeu/aeu_cs.py +0 -626
- egse/aeu/aeu_devif.py +0 -321
- egse/aeu/aeu_main_ui.py +0 -912
- 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 -234
- egse/alert/alertman_ui.py +0 -603
- 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 -130
- egse/alert/gsm/beaglebone_protocol.py +0 -48
- 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 -129
- 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 -1015
- egse/confman/confman.yaml +0 -67
- egse/confman/confman_cs.py +0 -239
- egse/confman/confman_ui.py +0 -381
- egse/confman/setup_ui.py +0 -565
- egse/control.py +0 -442
- egse/coordinates/__init__.py +0 -531
- egse/coordinates/avoidance.py +0 -103
- egse/coordinates/cslmodel.py +0 -127
- egse/coordinates/laser_tracker_to_dict.py +0 -120
- egse/coordinates/point.py +0 -707
- egse/coordinates/pyplot.py +0 -195
- 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 -1247
- 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 -415
- egse/device.py +0 -269
- egse/dpu/__init__.py +0 -2681
- egse/dpu/ccd_ui.py +0 -508
- egse/dpu/dpu.py +0 -786
- egse/dpu/dpu.yaml +0 -153
- egse/dpu/dpu_cs.py +0 -272
- egse/dpu/dpu_ui.py +0 -668
- egse/dpu/fitsgen.py +0 -2077
- egse/dpu/fitsgen_test.py +0 -752
- 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/constants.py +0 -220
- egse/dsi/esl.py +0 -870
- egse/dsi/rmap.py +0 -1042
- egse/dsi/rmapci.py +0 -37
- egse/dsi/spw.py +0 -154
- egse/dsi/spw_state.py +0 -29
- egse/dummy.py +0 -258
- egse/dyndummy.py +0 -179
- egse/env.py +0 -278
- egse/exceptions.py +0 -88
- egse/fdir/__init__.py +0 -28
- egse/fdir/fdir_manager.py +0 -85
- egse/fdir/fdir_manager.yaml +0 -51
- egse/fdir/fdir_manager_controller.py +0 -228
- egse/fdir/fdir_manager_cs.py +0 -164
- egse/fdir/fdir_manager_interface.py +0 -25
- egse/fdir/fdir_remote.py +0 -73
- egse/fdir/fdir_remote.yaml +0 -37
- egse/fdir/fdir_remote_controller.py +0 -50
- egse/fdir/fdir_remote_cs.py +0 -97
- egse/fdir/fdir_remote_interface.py +0 -14
- egse/fdir/fdir_remote_popup.py +0 -31
- egse/fee/__init__.py +0 -114
- egse/fee/f_fee_register.yaml +0 -43
- egse/fee/fee.py +0 -631
- egse/fee/feesim.py +0 -750
- egse/fee/n_fee_hk.py +0 -761
- egse/fee/nfee.py +0 -187
- egse/filterwheel/__init__.py +0 -4
- egse/filterwheel/eksma/__init__.py +0 -24
- egse/filterwheel/eksma/fw8smc4.py +0 -661
- 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 -81
- egse/filterwheel/eksma/fw8smc4_ui.py +0 -940
- egse/filterwheel/eksma/fw8smc5.py +0 -111
- 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 -1068
- egse/filterwheel/eksma/testpythonfw.py +0 -215
- egse/fov/__init__.py +0 -65
- egse/fov/fov_hk.py +0 -712
- egse/fov/fov_ui.py +0 -861
- 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 -135
- 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 -1281
- egse/gui/formatter.py +0 -10
- egse/gui/led.py +0 -162
- egse/gui/limitswitch.py +0 -143
- egse/gui/mechanisms.py +0 -588
- egse/gui/states.py +0 -148
- egse/gui/stripchart.py +0 -729
- 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 -138
- 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 -196
- egse/hexapod/symetrie/puna_protocol.py +0 -131
- egse/hexapod/symetrie/puna_ui.py +0 -434
- 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 -415
- egse/hexapod/symetrie/zonda_protocol.py +0 -119
- egse/hexapod/symetrie/zonda_ui.py +0 -449
- egse/hk.py +0 -765
- 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 -69
- 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/macOS/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/macOS/EtherSpaceLink_v34_86.dylib +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 -73
- egse/logger/__init__.py +0 -243
- egse/logger/log_cs.py +0 -321
- egse/metrics.py +0 -98
- 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 -163
- 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 -811
- 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 -603
- egse/proxy.py +0 -522
- egse/randomwalk.py +0 -140
- egse/reg.py +0 -585
- egse/reload.py +0 -122
- egse/reprocess.py +0 -675
- egse/resource.py +0 -333
- egse/rst.py +0 -135
- egse/search.py +0 -182
- egse/serialdevice.py +0 -190
- egse/services.py +0 -212
- egse/services.yaml +0 -51
- egse/settings.py +0 -379
- egse/settings.yaml +0 -980
- egse/setup.py +0 -1180
- 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 -69
- 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 -1479
- egse/stages/__init__.py +0 -12
- egse/stages/aerotech/ensemble.py +0 -247
- 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 -193
- egse/stages/arun/smd3.py +0 -111
- egse/stages/arun/smd3.yaml +0 -68
- egse/stages/arun/smd3_controller.py +0 -472
- 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 -904
- 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 -111
- 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 -1004
- egse/storage/persistence.py +0 -2295
- egse/storage/storage.yaml +0 -72
- egse/storage/storage_cs.py +0 -214
- egse/styles/dark.qss +0 -343
- egse/styles/default.qss +0 -48
- egse/synoptics/__init__.py +0 -412
- egse/synoptics/syn.yaml +0 -9
- egse/synoptics/syn_cs.py +0 -195
- egse/system.py +0 -1408
- egse/tcs/__init__.py +0 -14
- egse/tcs/tcs.py +0 -874
- 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 -177
- 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 -116
- egse/tempcontrol/agilent/agilent34970_devif.py +0 -182
- egse/tempcontrol/agilent/agilent34970_protocol.py +0 -99
- egse/tempcontrol/agilent/agilent34972.py +0 -111
- egse/tempcontrol/agilent/agilent34972.yaml +0 -44
- egse/tempcontrol/agilent/agilent34972_cs.py +0 -117
- egse/tempcontrol/agilent/agilent34972_devif.py +0 -189
- egse/tempcontrol/agilent/agilent34972_protocol.py +0 -101
- egse/tempcontrol/beaglebone/beaglebone.py +0 -342
- egse/tempcontrol/beaglebone/beaglebone.yaml +0 -110
- egse/tempcontrol/beaglebone/beaglebone_cs.py +0 -117
- egse/tempcontrol/beaglebone/beaglebone_protocol.py +0 -135
- egse/tempcontrol/beaglebone/beaglebone_ui.py +0 -681
- egse/tempcontrol/digalox/digalox.py +0 -107
- egse/tempcontrol/digalox/digalox.yaml +0 -36
- egse/tempcontrol/digalox/digalox_cs.py +0 -112
- egse/tempcontrol/digalox/digalox_protocol.py +0 -55
- 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 -78
- 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 -73
- egse/tempcontrol/lakeshore/lsci_ui.py +0 -389
- 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 -727
- egse/tempcontrol/srs/__init__.py +0 -22
- egse/tempcontrol/srs/ptc10.py +0 -875
- egse/tempcontrol/srs/ptc10.yaml +0 -227
- egse/tempcontrol/srs/ptc10_cs.py +0 -128
- egse/tempcontrol/srs/ptc10_devif.py +0 -118
- egse/tempcontrol/srs/ptc10_protocol.py +0 -42
- 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 -164
- egse/vacuum/beaglebone/beaglebone_protocol.py +0 -193
- egse/vacuum/beaglebone/beaglebone_ui.py +0 -638
- egse/vacuum/instrutech/igm402.py +0 -92
- egse/vacuum/instrutech/igm402.yaml +0 -90
- egse/vacuum/instrutech/igm402_controller.py +0 -128
- 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 -102
- egse/vacuum/keller/leo3.yaml +0 -38
- egse/vacuum/keller/leo3_controller.py +0 -83
- 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 -316
- egse/vacuum/mks/evision_interface.py +0 -60
- egse/vacuum/mks/evision_simulator.py +0 -24
- egse/vacuum/mks/evision_ui.py +0 -704
- 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 -39
- egse/vacuum/pfeiffer/tc400.py +0 -113
- egse/vacuum/pfeiffer/tc400.yaml +0 -83
- egse/vacuum/pfeiffer/tc400_controller.py +0 -140
- egse/vacuum/pfeiffer/tc400_cs.py +0 -109
- egse/vacuum/pfeiffer/tc400_interface.py +0 -70
- egse/vacuum/pfeiffer/tc400_simulator.py +0 -24
- egse/vacuum/pfeiffer/tpg261.py +0 -81
- 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 -60
- egse/vacuum/pfeiffer/tpg261_simulator.py +0 -24
- 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 -44
- scripts/check_hdf5_files.py +0 -192
- scripts/check_register_sync.py +0 -47
- scripts/create_hdf5_report.py +0 -295
- scripts/csl_model.py +0 -436
- scripts/csl_restore_setup.py +0 -230
- scripts/export-grafana-dashboards.py +0 -50
- scripts/fdir/cs_recovery/fdir_cs_recovery.py +0 -59
- scripts/fdir/fdir_table.yaml +0 -70
- scripts/fdir/fdir_test_recovery.py +0 -11
- scripts/fdir/hw_recovery/fdir_agilent_hw_recovery.py +0 -73
- scripts/fdir/limit_recovery/fdir_agilent_limit.py +0 -64
- scripts/fdir/limit_recovery/fdir_bb_heater_limit.py +0 -61
- 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/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/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/tm_gen/tm_gen_agilent.py +0 -38
- 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/fee/fee.py
DELETED
|
@@ -1,631 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This module contains functions and classes that are typically used by the FEE.
|
|
3
|
-
"""
|
|
4
|
-
import ctypes
|
|
5
|
-
import logging
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
|
|
8
|
-
import numpy as np
|
|
9
|
-
|
|
10
|
-
from egse import h5
|
|
11
|
-
from egse.bits import beautify_binary
|
|
12
|
-
from egse.decorators import static_vars
|
|
13
|
-
from egse.dsi import constants
|
|
14
|
-
from egse.dsi.esl import ESL
|
|
15
|
-
from egse.dsi.esl import ESLError
|
|
16
|
-
from egse.dsi.esl import esl_flush
|
|
17
|
-
from egse.dsi.esl import esl_get_esl_error
|
|
18
|
-
from egse.dsi.esl import esl_read_packet
|
|
19
|
-
from egse.dsi.esl import esl_write_packet
|
|
20
|
-
from egse.dsi.esl import get_extension_name
|
|
21
|
-
from egse.dsi.esl import get_terminator_name
|
|
22
|
-
from egse.dsi.esl import is_extension_code
|
|
23
|
-
from egse.dsi.esl import is_terminator_code
|
|
24
|
-
from egse.dsi.esl import pretty_print_packet
|
|
25
|
-
from egse.dsi.rmap import CheckError
|
|
26
|
-
from egse.dsi.rmap import ESL_RMAP
|
|
27
|
-
from egse.dsi.rmap import check_data_crc
|
|
28
|
-
from egse.dsi.rmap import check_header_crc
|
|
29
|
-
from egse.dsi.rmap import check_initiator_logical_address
|
|
30
|
-
from egse.dsi.rmap import check_instruction
|
|
31
|
-
from egse.dsi.rmap import check_key
|
|
32
|
-
from egse.dsi.rmap import check_protocol_id
|
|
33
|
-
from egse.dsi.rmap import check_target_logical_address
|
|
34
|
-
from egse.dsi.rmap import create_rmap_read_reply_packet
|
|
35
|
-
from egse.dsi.rmap import get_address
|
|
36
|
-
from egse.dsi.rmap import get_data_length
|
|
37
|
-
from egse.dsi.rmap import get_instruction_field
|
|
38
|
-
from egse.dsi.rmap import get_transaction_identifier
|
|
39
|
-
from egse.dsi.rmap import is_command
|
|
40
|
-
from egse.dsi.rmap import is_increment
|
|
41
|
-
from egse.dsi.rmap import is_write
|
|
42
|
-
from egse.dsi.rmap import rmap_crc_check
|
|
43
|
-
from egse.dsi.spw import handle_extension_packet
|
|
44
|
-
from egse.dsi.spw import handle_special_packet
|
|
45
|
-
from egse.settings import Settings
|
|
46
|
-
from egse.spw import DataPacketHeader
|
|
47
|
-
from egse.spw import PacketType
|
|
48
|
-
from egse.spw import SpaceWirePacket
|
|
49
|
-
from egse.state import GlobalState
|
|
50
|
-
from egse.system import Timer
|
|
51
|
-
|
|
52
|
-
fee_settings = Settings.load("FEE")
|
|
53
|
-
dsi_settings = Settings.load("DSI")
|
|
54
|
-
site_settings = Settings.load("SITE")
|
|
55
|
-
|
|
56
|
-
LOGGER = logging.getLogger(__name__)
|
|
57
|
-
|
|
58
|
-
DATA_DIR = (Path(__file__).parent / "../../data").resolve()
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def create_pattern_data(timecode: int, ccd_id: int, ccd_side: int) -> np.ndarray:
|
|
62
|
-
"""
|
|
63
|
-
Create pattern data as a two-dimensional ND array. The pattern data is generated as described
|
|
64
|
-
in PLATO-LESIA-PL-TN-023 - SimuCam pattern requirement.
|
|
65
|
-
|
|
66
|
-
The pattern is build up like this: each pixel is a 16-bit number with the following structure:
|
|
67
|
-
|
|
68
|
-
* Bits [15:13] = time-code % 8
|
|
69
|
-
* Bits [12:11] = CCD number [1, 2, 3, 4] should be [0-3]!
|
|
70
|
-
* Bit [10] = CCD side: 0 = left side, 1 = right side
|
|
71
|
-
* Bits [9:5] = Y-coordinate % 32
|
|
72
|
-
* Bits [4:0] = X-coordinate % 32
|
|
73
|
-
|
|
74
|
-
The total image data size of a full frame CCD is:
|
|
75
|
-
|
|
76
|
-
x = 4590 = 2 x (25 [serial prescan] + 2255 + 15 [serial overscan])
|
|
77
|
-
y = 4540 = 4510 + 30 [parallel overscan]
|
|
78
|
-
|
|
79
|
-
This function creates each side of the CCD separately, so each half can be treated individually
|
|
80
|
-
as is done in the N-FEE. The two sides can easily be concatenated to form the full image:
|
|
81
|
-
|
|
82
|
-
data = np.concatenate((data_left, data_right), axis=1)
|
|
83
|
-
|
|
84
|
-
Args:
|
|
85
|
-
timecode (int): the timecode for this readout
|
|
86
|
-
ccd_id (int): the CCD number [0-3]
|
|
87
|
-
ccd_side (int): the CCD side, 0 = left = E-side, 1 = right = F-side
|
|
88
|
-
Returns:
|
|
89
|
-
A two-dimensional ND array representing half of a CCD.
|
|
90
|
-
"""
|
|
91
|
-
|
|
92
|
-
ccd_number = ccd_id # save for later use
|
|
93
|
-
|
|
94
|
-
timecode = (timecode % 8) << 13 # timecode is 3 bits at [15:13]
|
|
95
|
-
ccd_id = (ccd_id & 0b0011) << 11 # ccd_id is 2 bits at [12:11]
|
|
96
|
-
ccd_side = (ccd_side & 0b0001) << 10 # ccd_side is 1 bit at [10]
|
|
97
|
-
|
|
98
|
-
x_size = 25 + 2255 + 15
|
|
99
|
-
y_size = 4510 + 30
|
|
100
|
-
|
|
101
|
-
rows, cols = np.indices((y_size, x_size), dtype=np.uint16)
|
|
102
|
-
cols %= 32
|
|
103
|
-
rows %= 32
|
|
104
|
-
|
|
105
|
-
data = rows * 16 + cols + timecode + ccd_side + ccd_id
|
|
106
|
-
|
|
107
|
-
# We leave set the msb because of the bit flipt for N-FEE EM
|
|
108
|
-
|
|
109
|
-
data[50:300, 100:105] = ccd_number | 0b10000000_00000000
|
|
110
|
-
data[100:105, 50:500] = ccd_number | 0b10000000_00000000
|
|
111
|
-
data[300:305, 50:150] = ccd_number | 0b10000000_00000000
|
|
112
|
-
data[50:150, 500:505] = ccd_number | 0b10000000_00000000
|
|
113
|
-
|
|
114
|
-
# We unset the msb because of the bit flip for N-FEE EM
|
|
115
|
-
|
|
116
|
-
data[110, 110] = 0x7FFF
|
|
117
|
-
|
|
118
|
-
return data
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def generate_data_packets(data: np.ndarray, header: DataPacketHeader,
|
|
122
|
-
v_start: int, v_end: int):
|
|
123
|
-
"""
|
|
124
|
-
This generator function creates and returns the SpaceWire packets to send to the DPU Processor.
|
|
125
|
-
|
|
126
|
-
Args:
|
|
127
|
-
data (ndarray): the full frame image data
|
|
128
|
-
header (DataPacketHeader): the data packet header
|
|
129
|
-
v_start (int): the first row to be transmitted
|
|
130
|
-
v_end (int): the last row to be transmitted
|
|
131
|
-
|
|
132
|
-
Returns:
|
|
133
|
-
|
|
134
|
-
"""
|
|
135
|
-
# steps:
|
|
136
|
-
# * reshape data to 1D array
|
|
137
|
-
# * update header with length, last_packet
|
|
138
|
-
# * increment sequence number?
|
|
139
|
-
# * convert data part into bytes object
|
|
140
|
-
# * concatenate header and data -> bytes
|
|
141
|
-
# * yield the packet
|
|
142
|
-
|
|
143
|
-
N_FEE_SIDE = GlobalState.setup.camera.fee.ccd_sides.enum
|
|
144
|
-
|
|
145
|
-
MAX_PACKET_SIZE = 32140 # this is a register value reg_4_config
|
|
146
|
-
HEADER_LENGTH = 10
|
|
147
|
-
H_END = 2294
|
|
148
|
-
MAX_CCD_LINE = 4509
|
|
149
|
-
MAX_OVERSCAN_LINE = MAX_CCD_LINE + 30
|
|
150
|
-
|
|
151
|
-
nr_rows_in_packet = row_offset = (MAX_PACKET_SIZE - HEADER_LENGTH) // (H_END + 1) // 2
|
|
152
|
-
|
|
153
|
-
y_size, x_size = data.shape
|
|
154
|
-
h_end = x_size - 1
|
|
155
|
-
v_end_ccd = min(MAX_CCD_LINE, v_end)
|
|
156
|
-
|
|
157
|
-
ccd_side = header.type_as_object.ccd_side
|
|
158
|
-
|
|
159
|
-
# F-side is read out starting from the right, so we flip the data left to right
|
|
160
|
-
# before sending, which simulates the reverse readout.
|
|
161
|
-
|
|
162
|
-
data = np.fliplr(data) if ccd_side == N_FEE_SIDE.RIGHT_SIDE else data
|
|
163
|
-
|
|
164
|
-
header.length = nr_rows_in_packet * ((h_end + 1) * 2)
|
|
165
|
-
LOGGER.debug(f"{header.length = }, {nr_rows_in_packet = }, {h_end = }")
|
|
166
|
-
|
|
167
|
-
for idx in range(v_start, v_end_ccd + 1, nr_rows_in_packet):
|
|
168
|
-
if idx + nr_rows_in_packet > v_end_ccd:
|
|
169
|
-
row_offset = v_end_ccd - idx + 1
|
|
170
|
-
header.length = row_offset * ((h_end + 1) * 2)
|
|
171
|
-
header.last_packet = True
|
|
172
|
-
# LOGGER.debug(f"{idx=}, {row_offset=}")
|
|
173
|
-
chunk = bytearray(data[idx:idx+row_offset, :])
|
|
174
|
-
chunk[0::2], chunk[1::2] = chunk[1::2], chunk[0::2]
|
|
175
|
-
packet_data = header.data_as_bytes() + chunk
|
|
176
|
-
# LOGGER.debug(f"{len(packet_data)=}, {len(chunk)=}")
|
|
177
|
-
yield SpaceWirePacket.create_packet(packet_data)
|
|
178
|
-
|
|
179
|
-
# reset the header for the overscan lines
|
|
180
|
-
|
|
181
|
-
header.packet_type = PacketType.OVERSCAN_DATA
|
|
182
|
-
header.last_packet = False
|
|
183
|
-
header.length = nr_rows_in_packet * ((h_end + 1) * 2)
|
|
184
|
-
|
|
185
|
-
v_end_overscan = min(MAX_OVERSCAN_LINE, v_end)
|
|
186
|
-
|
|
187
|
-
# reset the row_offset
|
|
188
|
-
|
|
189
|
-
row_offset = nr_rows_in_packet
|
|
190
|
-
|
|
191
|
-
for idx in range(MAX_CCD_LINE+1, v_end_overscan + 1, nr_rows_in_packet):
|
|
192
|
-
if idx + nr_rows_in_packet > v_end_overscan:
|
|
193
|
-
row_offset = v_end_overscan - idx + 1
|
|
194
|
-
header.length = row_offset * ((h_end + 1) * 2)
|
|
195
|
-
header.last_packet = True
|
|
196
|
-
LOGGER.debug(f"{idx=}, {row_offset=}")
|
|
197
|
-
chunk = bytearray(data[idx:idx+row_offset, :])
|
|
198
|
-
chunk[0::2], chunk[1::2] = chunk[1::2], chunk[0::2]
|
|
199
|
-
packet_data = header.data_as_bytes() + chunk
|
|
200
|
-
LOGGER.debug(f"{len(packet_data)=}, {len(chunk)=}")
|
|
201
|
-
yield SpaceWirePacket.create_packet(packet_data)
|
|
202
|
-
|
|
203
|
-
def read_exposure(image_count):
|
|
204
|
-
"""
|
|
205
|
-
Private method to extract an exposure from the PlatoSim HDF5 file.
|
|
206
|
-
|
|
207
|
-
This method uses an internal counter to read the next exposure from the
|
|
208
|
-
HDF5 file. When no exposures are available, an empty numpy array is returned.
|
|
209
|
-
"""
|
|
210
|
-
|
|
211
|
-
platosim_filename = DATA_DIR / fee_settings.PLATOSIM_FILENAME
|
|
212
|
-
platosim_hdf5file = h5.get_file(platosim_filename, "r")
|
|
213
|
-
|
|
214
|
-
# Construct the image name that was used to store the image
|
|
215
|
-
image_name = "image{0:06d}".format(image_count)
|
|
216
|
-
|
|
217
|
-
# Copy the contents of the Image into a numpy array
|
|
218
|
-
try:
|
|
219
|
-
dataset = platosim_hdf5file["Images"][image_name]
|
|
220
|
-
image = np.zeros(dataset.shape, dataset.dtype)
|
|
221
|
-
LOGGER.info("image shape {} and type {}".format(dataset.shape, dataset.dtype))
|
|
222
|
-
dataset.read_direct(image)
|
|
223
|
-
return image
|
|
224
|
-
except KeyError as msg:
|
|
225
|
-
LOGGER.error("KeyError: {}".format(msg))
|
|
226
|
-
LOGGER.error("Cannot read exposure {} from the HDF5 file".format(image_name))
|
|
227
|
-
return np.array([])
|
|
228
|
-
except TypeError as msg:
|
|
229
|
-
LOGGER.error("TypeError: {}".format(msg))
|
|
230
|
-
LOGGER.error(
|
|
231
|
-
"Somehow the shape and/or the data type of the image are wrong in the HDF5 file."
|
|
232
|
-
)
|
|
233
|
-
return np.array([])
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def is_data_packet(packet):
|
|
237
|
-
return packet[0] == 0x50 and packet[1] == 0xF0
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
def is_hk_data_packet(packet):
|
|
241
|
-
packet_type = int.from_bytes(packet[4:6], "big")
|
|
242
|
-
|
|
243
|
-
return (packet_type & 0b0011) == 2
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
def is_data_data_packet(packet):
|
|
247
|
-
packet_type = int.from_bytes(packet[4:6], "big")
|
|
248
|
-
|
|
249
|
-
return (packet_type & 0b0011) == 0
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
def is_overscan_data_packet(packet):
|
|
253
|
-
packet_type = int.from_bytes(packet[4:6], "big")
|
|
254
|
-
|
|
255
|
-
return (packet_type & 0b0011) == 1
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
def is_last_packet(packet):
|
|
259
|
-
|
|
260
|
-
# Note that this bit is only set when in readout mode and when data is sent.
|
|
261
|
-
# It's currently not clear if the HK data packet will then also have the bit set (as there is
|
|
262
|
-
# only one HK packet) or if it is only the last data packet.
|
|
263
|
-
|
|
264
|
-
# bit 7 of the Data Packet Field: Type
|
|
265
|
-
packet_type = int.from_bytes(packet[4:6], "big")
|
|
266
|
-
|
|
267
|
-
LOGGER.log(5, f"Packet Type Field: 0b{beautify_binary(packet_type, size=16)}")
|
|
268
|
-
|
|
269
|
-
return packet_type & 0b10000000
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
def get_mode(packet):
|
|
273
|
-
# bit [8:12] of the Data Packet Field: Type
|
|
274
|
-
packet_type = int.from_bytes(packet[4:6], "big")
|
|
275
|
-
|
|
276
|
-
mode = (packet_type & 0b111100000000) >> 8
|
|
277
|
-
return mode
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
def get_data(packet) -> bytes:
|
|
281
|
-
"""Return the data from the HK or Data packet.
|
|
282
|
-
|
|
283
|
-
Raises:
|
|
284
|
-
ValueError: if there is no data section in the packet (TODO: not yet implemented)
|
|
285
|
-
"""
|
|
286
|
-
if not is_data_packet(packet):
|
|
287
|
-
LOGGER.debug(f"0x{packet.hex()}")
|
|
288
|
-
raise ValueError("Trying to read data from a packet that is not a data packet.")
|
|
289
|
-
|
|
290
|
-
length = int.from_bytes(packet[2:4], "big")
|
|
291
|
-
data = packet[10:]
|
|
292
|
-
|
|
293
|
-
LOGGER.debug(f"length field={length}, packet length={len(packet)}, data length={len(data)}")
|
|
294
|
-
|
|
295
|
-
return data
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
@static_vars(timecode=0)
|
|
299
|
-
def increment_timecode() -> int:
|
|
300
|
-
if increment_timecode.timecode == 0x3F:
|
|
301
|
-
increment_timecode.timecode = 0
|
|
302
|
-
else:
|
|
303
|
-
increment_timecode.timecode += 1
|
|
304
|
-
|
|
305
|
-
return increment_timecode.timecode
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
def process_rmap_commands(esl_link: ESL, rmap_link: ESL_RMAP):
|
|
309
|
-
total_received = 0
|
|
310
|
-
packet = bytes()
|
|
311
|
-
|
|
312
|
-
terminator, rx_buffer = esl_read_packet(esl_link)
|
|
313
|
-
bytes_received = len(rx_buffer)
|
|
314
|
-
|
|
315
|
-
if is_terminator_code(terminator):
|
|
316
|
-
LOGGER.debug(
|
|
317
|
-
f"bytes received={bytes_received}, terminator={terminator} "
|
|
318
|
-
f"[{get_terminator_name(terminator)}]"
|
|
319
|
-
)
|
|
320
|
-
elif is_extension_code(terminator):
|
|
321
|
-
LOGGER.debug(
|
|
322
|
-
f"bytes received={bytes_received}, terminator={terminator} "
|
|
323
|
-
f"[{get_extension_name(terminator)}]"
|
|
324
|
-
)
|
|
325
|
-
else:
|
|
326
|
-
LOGGER.debug(f"bytes received={bytes_received}, terminator={terminator}")
|
|
327
|
-
|
|
328
|
-
# TODO:
|
|
329
|
-
# When the link is closed from the other end (dpusim) just one byte (b'\x08') is received.
|
|
330
|
-
# So, we should try to restart the link...
|
|
331
|
-
|
|
332
|
-
if bytes_received == 1:
|
|
333
|
-
LOGGER.warning("Link was closed from the initiator side, terminating.")
|
|
334
|
-
return
|
|
335
|
-
|
|
336
|
-
# First check if we encountered any errors or shutdown,
|
|
337
|
-
# if True then break the main while loop and end the connection
|
|
338
|
-
#
|
|
339
|
-
# FIXME:
|
|
340
|
-
# We need better handling of exceptional conditions here since the FEE Simulator can never
|
|
341
|
-
# die.
|
|
342
|
-
# - what shall we do when a shutdown is received?
|
|
343
|
-
# - what shall we do when a timeout has occured?
|
|
344
|
-
# - what shall we do with a buffer overflow? When can this happen?
|
|
345
|
-
# - some errors are related to the virtual DSI, how do we solve those?
|
|
346
|
-
|
|
347
|
-
if bytes_received < 0:
|
|
348
|
-
error = esl_get_esl_error(esl_link)
|
|
349
|
-
if error == constants.ESL_ERROR_TIMEOUT:
|
|
350
|
-
LOGGER.debug("Received a timeout, continuing...")
|
|
351
|
-
return
|
|
352
|
-
# FIXME: We should handle all these cases in a simpler way
|
|
353
|
-
if error == constants.ESL_ERROR_RECEIVER_SHUTDOWN:
|
|
354
|
-
LOGGER.info("Shutdown detected.")
|
|
355
|
-
return
|
|
356
|
-
if error == constants.ESL_ERROR_BUFFER_OVERFLOW:
|
|
357
|
-
# FIXME: Can we recover from this situation?
|
|
358
|
-
LOGGER.error("Insufficient buffer to read full packet, bailing out.")
|
|
359
|
-
return
|
|
360
|
-
if error == constants.ESL_ERROR_RECFILE_WRITE:
|
|
361
|
-
LOGGER.error("Write error on record file, bailing out.")
|
|
362
|
-
return
|
|
363
|
-
|
|
364
|
-
LOGGER.error(
|
|
365
|
-
f"read_packet: returned error, "
|
|
366
|
-
f"ESL error = {constants.esl_error_codes[error]} [{error}]"
|
|
367
|
-
)
|
|
368
|
-
return
|
|
369
|
-
|
|
370
|
-
# When we receive an unknown terminator we just ignore, log the error and continue...
|
|
371
|
-
|
|
372
|
-
if terminator not in (
|
|
373
|
-
constants.ESL_EXTN,
|
|
374
|
-
constants.ESL_SPECIAL,
|
|
375
|
-
constants.ESL_PART_EOP_EEP,
|
|
376
|
-
constants.ESL_PART_EXTN,
|
|
377
|
-
constants.ESL_PART_SPECIAL,
|
|
378
|
-
constants.ESL_EEP,
|
|
379
|
-
constants.ESL_EOP,
|
|
380
|
-
):
|
|
381
|
-
LOGGER.error(f"Unknown terminator [{terminator}] received.")
|
|
382
|
-
return
|
|
383
|
-
|
|
384
|
-
if terminator == constants.ESL_EXTN:
|
|
385
|
-
handle_extension_packet(rx_buffer, bytes_received)
|
|
386
|
-
|
|
387
|
-
if terminator == constants.ESL_SPECIAL:
|
|
388
|
-
handle_special_packet(rx_buffer, bytes_received)
|
|
389
|
-
|
|
390
|
-
if terminator in (
|
|
391
|
-
constants.ESL_PART_EOP_EEP,
|
|
392
|
-
constants.ESL_PART_EXTN,
|
|
393
|
-
constants.ESL_PART_SPECIAL,
|
|
394
|
-
):
|
|
395
|
-
LOGGER.debug("Partial Data Packet received.")
|
|
396
|
-
|
|
397
|
-
total_received += bytes_received
|
|
398
|
-
packet += rx_buffer[:bytes_received]
|
|
399
|
-
|
|
400
|
-
# FIXME:
|
|
401
|
-
# at this point we need to go for the next part of the packet
|
|
402
|
-
# continue was used in the while loop before splitting off this code. We now do a
|
|
403
|
-
# return, but we loose information on the total packet size etc.
|
|
404
|
-
return
|
|
405
|
-
|
|
406
|
-
if terminator == constants.ESL_EEP:
|
|
407
|
-
LOGGER.debug("Error End of Packet returned by DSI")
|
|
408
|
-
|
|
409
|
-
if terminator == constants.ESL_EOP:
|
|
410
|
-
LOGGER.debug("Normal End of Packet returned by DSI")
|
|
411
|
-
|
|
412
|
-
total_received += bytes_received
|
|
413
|
-
packet += rx_buffer[:bytes_received]
|
|
414
|
-
|
|
415
|
-
LOGGER.debug(f"total_received={total_received}")
|
|
416
|
-
LOGGER.debug("Pretty Print Received Packet:\n" + pretty_print_packet(packet))
|
|
417
|
-
|
|
418
|
-
# Deal with RMAP request packet
|
|
419
|
-
# FIXME: shouldn't this all be checked on packet instead of rx_buffer?
|
|
420
|
-
|
|
421
|
-
try:
|
|
422
|
-
# Run a number of checks on the received packet
|
|
423
|
-
|
|
424
|
-
check_target_logical_address(rmap_link, rx_buffer, dsi_settings.TARGET_LOGICAL_ADDRESS)
|
|
425
|
-
check_protocol_id(rx_buffer)
|
|
426
|
-
check_instruction(rx_buffer)
|
|
427
|
-
check_key(rmap_link, rx_buffer)
|
|
428
|
-
check_initiator_logical_address(rx_buffer, dsi_settings.INITIATOR_LOGICAL_ADDRESS)
|
|
429
|
-
check_header_crc(rx_buffer)
|
|
430
|
-
|
|
431
|
-
# Extract information from the packet that we need further on
|
|
432
|
-
|
|
433
|
-
tid = get_transaction_identifier(rx_buffer)
|
|
434
|
-
address = get_address(rx_buffer)
|
|
435
|
-
data_length = get_data_length(rx_buffer)
|
|
436
|
-
except CheckError as ce:
|
|
437
|
-
LOGGER.error(f"{ce.message}, status = {ce.status}")
|
|
438
|
-
status = ce.status
|
|
439
|
-
# FIXME:
|
|
440
|
-
# Something is wrong with the packet here, do proper exception handling.
|
|
441
|
-
# We are not anymore in the while loop after we have split off this code,
|
|
442
|
-
# so continue doesn't work anymore...
|
|
443
|
-
# continue
|
|
444
|
-
raise ce
|
|
445
|
-
|
|
446
|
-
# Do something with the packet received
|
|
447
|
-
|
|
448
|
-
instruction_field = get_instruction_field(packet)
|
|
449
|
-
|
|
450
|
-
if is_command(instruction_field):
|
|
451
|
-
|
|
452
|
-
status = constants.RMAP_SUCCESS
|
|
453
|
-
|
|
454
|
-
if (
|
|
455
|
-
not dsi_settings.RMAP_BASE_ADDRESS
|
|
456
|
-
<= address
|
|
457
|
-
< (dsi_settings.RMAP_BASE_ADDRESS + dsi_settings.RMAP_MEMORY_SIZE)
|
|
458
|
-
):
|
|
459
|
-
LOGGER.error(f"ERROR: Access outside of RMAP memory area, address=0x{address:010X}")
|
|
460
|
-
status = constants.RMAP_GENERAL_ERROR
|
|
461
|
-
|
|
462
|
-
# Handling an RMAP Write Command
|
|
463
|
-
#
|
|
464
|
-
# - Send a reply
|
|
465
|
-
# - Check Data CRC before writing
|
|
466
|
-
# - Write the data into memory
|
|
467
|
-
|
|
468
|
-
if is_write(instruction_field):
|
|
469
|
-
|
|
470
|
-
LOGGER.debug("RMAP write command received, sending reply packet...")
|
|
471
|
-
|
|
472
|
-
# FIXME: need some work here!!!!
|
|
473
|
-
|
|
474
|
-
# Create the target memory map and fill it with a pattern.
|
|
475
|
-
# This is just to simplify checking the correct write command.
|
|
476
|
-
# TODO: this should be replaced with the RegistryMap
|
|
477
|
-
|
|
478
|
-
rmap_target_memory = ctypes.create_string_buffer(
|
|
479
|
-
bytes([x & 0xFF for x in range(dsi_settings.RMAP_MEMORY_SIZE)])
|
|
480
|
-
)
|
|
481
|
-
|
|
482
|
-
tx_buffer = ctypes.create_string_buffer(dsi_settings.TX_BUFFER_LENGTH)
|
|
483
|
-
|
|
484
|
-
tx_buffer[7] = rmap_crc_check(tx_buffer, 0, 7)
|
|
485
|
-
|
|
486
|
-
result = esl_write_packet(esl_link, tx_buffer, 8, constants.ESL_EOP)
|
|
487
|
-
|
|
488
|
-
esl_flush(esl_link)
|
|
489
|
-
|
|
490
|
-
# When no errors, then write the data into memory at the given position
|
|
491
|
-
|
|
492
|
-
if status == constants.RMAP_SUCCESS:
|
|
493
|
-
|
|
494
|
-
# Check the Data CRC
|
|
495
|
-
|
|
496
|
-
try:
|
|
497
|
-
check_data_crc(rx_buffer)
|
|
498
|
-
except CheckError as ce:
|
|
499
|
-
LOGGER.error(f"{ce}, status = {ce.status}")
|
|
500
|
-
raise ce
|
|
501
|
-
|
|
502
|
-
# Write the data into the target memory map
|
|
503
|
-
|
|
504
|
-
# FIXME: I do not understand why this is !!!!
|
|
505
|
-
|
|
506
|
-
if is_increment(instruction_field):
|
|
507
|
-
# change this code to work with RegisterMap
|
|
508
|
-
# rmap_target_memory[address:address + data_length] = get_data(rx_buffer)
|
|
509
|
-
pass
|
|
510
|
-
else:
|
|
511
|
-
# change this code to work with RegisterMap
|
|
512
|
-
# Overwrite all the data into the same memory address, why?
|
|
513
|
-
# for b in get_data(rx_buffer):
|
|
514
|
-
# rmap_target_memory[address] = b
|
|
515
|
-
pass
|
|
516
|
-
|
|
517
|
-
# Handling an RMAP Read Command
|
|
518
|
-
|
|
519
|
-
else:
|
|
520
|
-
if status:
|
|
521
|
-
data_length = 0
|
|
522
|
-
|
|
523
|
-
LOGGER.warning(
|
|
524
|
-
"Commented out this code, work needs to be done on RMAP read command"
|
|
525
|
-
)
|
|
526
|
-
# data = self.register_map.get_data(address, data_length)
|
|
527
|
-
data = b"\x00\x01\x02\x03"
|
|
528
|
-
|
|
529
|
-
tx_buffer = create_rmap_read_reply_packet(
|
|
530
|
-
rmap_link, instruction_field, tid, status, data, data_length
|
|
531
|
-
)
|
|
532
|
-
|
|
533
|
-
result = esl_write_packet(esl_link, tx_buffer, len(tx_buffer), constants.ESL_EOP)
|
|
534
|
-
|
|
535
|
-
result = esl_flush(
|
|
536
|
-
esl_link
|
|
537
|
-
) # FIXME: This will mask previous ESL_error if there was one
|
|
538
|
-
|
|
539
|
-
if result:
|
|
540
|
-
raise ESLError(
|
|
541
|
-
f"Could not write the packet, "
|
|
542
|
-
f"ESL error code = {constants.esl_error_codes[esl_link.contents.ESL_error]} "
|
|
543
|
-
f"[{esl_link.contents.ESL_error}]"
|
|
544
|
-
)
|
|
545
|
-
|
|
546
|
-
else:
|
|
547
|
-
LOGGER.warning("The packet is not an RMAP read/write command.")
|
|
548
|
-
|
|
549
|
-
total_received = 0
|
|
550
|
-
packet = bytes()
|
|
551
|
-
|
|
552
|
-
LOGGER.debug("Going for the next SpaceWire packet...")
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
if __name__ == "__main__":
|
|
556
|
-
|
|
557
|
-
import numpy as np
|
|
558
|
-
import matplotlib.pyplot as plt
|
|
559
|
-
from egse.fee import n_fee_mode
|
|
560
|
-
|
|
561
|
-
fig, (ax1, ax2, ax3) = plt.subplots(3)
|
|
562
|
-
|
|
563
|
-
header = DataPacketHeader()
|
|
564
|
-
|
|
565
|
-
timecode = 0
|
|
566
|
-
ccd_side = 0
|
|
567
|
-
ccd_id = 2
|
|
568
|
-
|
|
569
|
-
data_left = create_pattern_data(timecode, ccd_id, ccd_side)
|
|
570
|
-
|
|
571
|
-
print(f"{data_left[0, 0]=:016b}, {data_left[0, 1]=:016b}, {data_left[0, 2278]=:016b}, {data_left[0, 2279]=:016b}")
|
|
572
|
-
print(f"{data_left[1, 0]=:016b}, {data_left[1, 1]=:016b}, {data_left[1, 2278]=:016b}, {data_left[1, 2279]=:016b}")
|
|
573
|
-
print(f"{data_left[4538, 0]=:016b}, {data_left[4538, 1]=:016b}, {data_left[4538, 2278]=:016b}, {data_left[4538, 2279]=:016b}")
|
|
574
|
-
print(f"{data_left[4539, 0]=:016b}, {data_left[4539, 1]=:016b}, {data_left[4539, 2278]=:016b}, {data_left[4539, 2279]=:016b}")
|
|
575
|
-
|
|
576
|
-
v_start = 0
|
|
577
|
-
v_end = 4509 # remember that v_end is inclusive
|
|
578
|
-
|
|
579
|
-
data_left = create_pattern_data(62, 0, 0)
|
|
580
|
-
data_right = create_pattern_data(62, 0, 1)
|
|
581
|
-
|
|
582
|
-
data = np.concatenate((data_left, data_right), axis=1)
|
|
583
|
-
data = data[v_start:v_end+1, :]
|
|
584
|
-
|
|
585
|
-
LOGGER.info(f"{data.shape=}")
|
|
586
|
-
|
|
587
|
-
ax1.imshow(data, origin='lower')
|
|
588
|
-
|
|
589
|
-
# now generate the packet for the first 10 lines and glue the data together again to
|
|
590
|
-
# be displayed
|
|
591
|
-
|
|
592
|
-
packet_type = header.type_as_object
|
|
593
|
-
packet_type.ccd_side = ccd_side
|
|
594
|
-
packet_type.ccd_number = ccd_id
|
|
595
|
-
packet_type.last_packet = False
|
|
596
|
-
packet_type.frame_number = 2
|
|
597
|
-
packet_type.mode = n_fee_mode.FULL_IMAGE_PATTERN_MODE
|
|
598
|
-
header.type = packet_type
|
|
599
|
-
|
|
600
|
-
nr_lines = 0
|
|
601
|
-
image_left = np.empty((0,), dtype=np.uint16)
|
|
602
|
-
|
|
603
|
-
with Timer("Generate left side data packets") as timer:
|
|
604
|
-
for packet in generate_data_packets(data_left, header, v_start, v_end):
|
|
605
|
-
image_left = np.concatenate((image_left, packet.data_as_ndarray))
|
|
606
|
-
nr_lines += len(packet.data_as_ndarray) // 2295
|
|
607
|
-
|
|
608
|
-
image_left = image_left.reshape(nr_lines, 2295)
|
|
609
|
-
LOGGER.info(f"{image_left.shape = }")
|
|
610
|
-
|
|
611
|
-
nr_lines = 0
|
|
612
|
-
image_right = np.empty((0,), dtype=np.uint16)
|
|
613
|
-
|
|
614
|
-
with Timer("Generate right side datapackets"):
|
|
615
|
-
for packet in generate_data_packets(data_right, header, v_start, v_end):
|
|
616
|
-
image_right = np.concatenate((image_right, packet.data_as_ndarray))
|
|
617
|
-
nr_lines += len(packet.data_as_ndarray) // 2295
|
|
618
|
-
|
|
619
|
-
image_right = image_right.reshape(nr_lines, 2295)
|
|
620
|
-
LOGGER.info(f"{image_right.shape = }")
|
|
621
|
-
|
|
622
|
-
image = np.concatenate((image_left, image_right), axis=1)
|
|
623
|
-
|
|
624
|
-
ax2.imshow(image, origin='lower')
|
|
625
|
-
|
|
626
|
-
x = data - image
|
|
627
|
-
|
|
628
|
-
print(f"{np.count_nonzero(x)=}")
|
|
629
|
-
|
|
630
|
-
ax3.imshow(x, origin='lower')
|
|
631
|
-
plt.show()
|