cgse 2024.7.0__py3-none-any.whl → 2025.0.1__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.1.dist-info/METADATA +38 -0
- cgse-2025.0.1.dist-info/RECORD +5 -0
- {cgse-2024.7.0.dist-info → cgse-2025.0.1.dist-info}/WHEEL +1 -2
- cgse-2024.7.0.dist-info/COPYING +0 -674
- cgse-2024.7.0.dist-info/COPYING.LESSER +0 -165
- cgse-2024.7.0.dist-info/METADATA +0 -144
- cgse-2024.7.0.dist-info/RECORD +0 -660
- cgse-2024.7.0.dist-info/entry_points.txt +0 -75
- cgse-2024.7.0.dist-info/top_level.txt +0 -2
- egse/__init__.py +0 -12
- egse/__main__.py +0 -32
- egse/aeu/aeu.py +0 -5238
- egse/aeu/aeu_awg.yaml +0 -265
- egse/aeu/aeu_crio.yaml +0 -273
- egse/aeu/aeu_cs.py +0 -627
- egse/aeu/aeu_devif.py +0 -321
- egse/aeu/aeu_main_ui.py +0 -903
- egse/aeu/aeu_metrics.py +0 -131
- egse/aeu/aeu_protocol.py +0 -463
- egse/aeu/aeu_psu.yaml +0 -204
- egse/aeu/aeu_ui.py +0 -873
- egse/aeu/arbdata/FccdRead.arb +0 -2
- egse/aeu/arbdata/FccdRead_min_points.arb +0 -2
- egse/aeu/arbdata/HeaterSync_FccdRead.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead25.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead31_25.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead37_50.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead43_75.arb +0 -2
- egse/aeu/arbdata/HeaterSync_ccdRead50.arb +0 -2
- egse/aeu/arbdata/Heater_FccdRead_min_points.arb +0 -2
- egse/aeu/arbdata/ccdRead25.arb +0 -2
- egse/aeu/arbdata/ccdRead25_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead31_25.arb +0 -2
- egse/aeu/arbdata/ccdRead31_25_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead37_50.arb +0 -2
- egse/aeu/arbdata/ccdRead37_50_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead43_75.arb +0 -2
- egse/aeu/arbdata/ccdRead43_75_150ms.arb +0 -2
- egse/aeu/arbdata/ccdRead50.arb +0 -2
- egse/aeu/arbdata/ccdRead50_150ms.arb +0 -2
- egse/alert/__init__.py +0 -1049
- egse/alert/alertman.yaml +0 -37
- egse/alert/alertman_cs.py +0 -233
- egse/alert/alertman_ui.py +0 -600
- egse/alert/gsm/beaglebone.py +0 -138
- egse/alert/gsm/beaglebone.yaml +0 -51
- egse/alert/gsm/beaglebone_cs.py +0 -108
- egse/alert/gsm/beaglebone_devif.py +0 -122
- egse/alert/gsm/beaglebone_protocol.py +0 -46
- egse/bits.py +0 -318
- egse/camera.py +0 -44
- egse/collimator/__init__.py +0 -0
- egse/collimator/fcul/__init__.py +0 -0
- egse/collimator/fcul/ogse.py +0 -1077
- egse/collimator/fcul/ogse.yaml +0 -14
- egse/collimator/fcul/ogse_cs.py +0 -154
- egse/collimator/fcul/ogse_devif.py +0 -358
- egse/collimator/fcul/ogse_protocol.py +0 -132
- egse/collimator/fcul/ogse_sim.py +0 -431
- egse/collimator/fcul/ogse_ui.py +0 -1108
- egse/command.py +0 -699
- egse/config.py +0 -410
- egse/confman/__init__.py +0 -1058
- egse/confman/confman.yaml +0 -70
- egse/confman/confman_cs.py +0 -240
- egse/confman/confman_ui.py +0 -381
- egse/confman/setup_ui.py +0 -565
- egse/control.py +0 -632
- egse/coordinates/__init__.py +0 -534
- egse/coordinates/avoidance.py +0 -100
- egse/coordinates/cslmodel.py +0 -127
- egse/coordinates/laser_tracker_to_dict.py +0 -122
- egse/coordinates/point.py +0 -707
- egse/coordinates/pyplot.py +0 -194
- egse/coordinates/referenceFrame.py +0 -1279
- egse/coordinates/refmodel.py +0 -737
- egse/coordinates/rotationMatrix.py +0 -85
- egse/coordinates/transform3d_addon.py +0 -419
- egse/csl/__init__.py +0 -50
- egse/csl/commanding.py +0 -78
- egse/csl/icons/hexapod-connected-selected.svg +0 -30
- egse/csl/icons/hexapod-connected.svg +0 -30
- egse/csl/icons/hexapod-homing-selected.svg +0 -68
- egse/csl/icons/hexapod-homing.svg +0 -68
- egse/csl/icons/hexapod-retract-selected.svg +0 -56
- egse/csl/icons/hexapod-retract.svg +0 -51
- egse/csl/icons/hexapod-zero-selected.svg +0 -56
- egse/csl/icons/hexapod-zero.svg +0 -56
- egse/csl/icons/logo-puna.svg +0 -92
- egse/csl/icons/stop.svg +0 -1
- egse/csl/initialisation.py +0 -102
- egse/csl/mech_pos_settings.yaml +0 -18
- egse/das.py +0 -1240
- egse/das.yaml +0 -7
- egse/data/conf/SETUP_CSL_00000_170620_150000.yaml +0 -5
- egse/data/conf/SETUP_CSL_00001_170620_151010.yaml +0 -69
- egse/data/conf/SETUP_CSL_00002_170620_151020.yaml +0 -69
- egse/data/conf/SETUP_CSL_00003_170620_151030.yaml +0 -69
- egse/data/conf/SETUP_CSL_00004_170620_151040.yaml +0 -69
- egse/data/conf/SETUP_CSL_00005_170620_151050.yaml +0 -69
- egse/data/conf/SETUP_CSL_00006_170620_151060.yaml +0 -69
- egse/data/conf/SETUP_CSL_00007_170620_151070.yaml +0 -69
- egse/data/conf/SETUP_CSL_00008_170620_151080.yaml +0 -75
- egse/data/conf/SETUP_CSL_00010_210308_083016.yaml +0 -138
- egse/data/conf/SETUP_INTA_00000_170620_150000.yaml +0 -4
- egse/data/conf/SETUP_SRON_00000_170620_150000.yaml +0 -4
- egse/decorators.py +0 -514
- egse/device.py +0 -269
- egse/dpu/__init__.py +0 -2698
- egse/dpu/ccd_ui.py +0 -514
- egse/dpu/dpu.py +0 -783
- egse/dpu/dpu.yaml +0 -153
- egse/dpu/dpu_cs.py +0 -272
- egse/dpu/dpu_ui.py +0 -671
- egse/dpu/fitsgen.py +0 -2096
- egse/dpu/fitsgen_ui.py +0 -399
- egse/dpu/hdf5_model.py +0 -332
- egse/dpu/hdf5_ui.py +0 -277
- egse/dpu/hdf5_viewer.py +0 -506
- egse/dpu/hk_ui.py +0 -468
- egse/dpu_commands.py +0 -81
- egse/dsi/__init__.py +0 -33
- egse/dsi/_libesl.py +0 -232
- egse/dsi/constants.py +0 -296
- egse/dsi/esl.py +0 -630
- egse/dsi/rmap.py +0 -444
- egse/dsi/rmapci.py +0 -39
- egse/dsi/spw.py +0 -335
- egse/dsi/spw_state.py +0 -29
- egse/dummy.py +0 -318
- egse/dyndummy.py +0 -179
- egse/env.py +0 -278
- egse/exceptions.py +0 -88
- egse/fdir/__init__.py +0 -26
- egse/fdir/fdir_manager.py +0 -85
- egse/fdir/fdir_manager.yaml +0 -37
- egse/fdir/fdir_manager_controller.py +0 -136
- egse/fdir/fdir_manager_cs.py +0 -164
- egse/fdir/fdir_manager_interface.py +0 -15
- egse/fdir/fdir_remote.py +0 -73
- egse/fdir/fdir_remote.yaml +0 -30
- egse/fdir/fdir_remote_controller.py +0 -30
- egse/fdir/fdir_remote_cs.py +0 -94
- egse/fdir/fdir_remote_interface.py +0 -9
- egse/fdir/fdir_remote_popup.py +0 -26
- egse/fee/__init__.py +0 -106
- egse/fee/f_fee_register.yaml +0 -43
- egse/fee/feesim.py +0 -914
- egse/fee/n_fee_hk.py +0 -768
- egse/fee/nfee.py +0 -188
- egse/filterwheel/__init__.py +0 -4
- egse/filterwheel/eksma/__init__.py +0 -49
- egse/filterwheel/eksma/fw8smc4.py +0 -657
- egse/filterwheel/eksma/fw8smc4.yaml +0 -121
- egse/filterwheel/eksma/fw8smc4_cs.py +0 -144
- egse/filterwheel/eksma/fw8smc4_devif.py +0 -473
- egse/filterwheel/eksma/fw8smc4_protocol.py +0 -82
- egse/filterwheel/eksma/fw8smc4_ui.py +0 -940
- egse/filterwheel/eksma/fw8smc5.py +0 -115
- egse/filterwheel/eksma/fw8smc5.yaml +0 -105
- egse/filterwheel/eksma/fw8smc5_controller.py +0 -307
- egse/filterwheel/eksma/fw8smc5_cs.py +0 -141
- egse/filterwheel/eksma/fw8smc5_interface.py +0 -65
- egse/filterwheel/eksma/fw8smc5_simulator.py +0 -29
- egse/filterwheel/eksma/fw8smc5_ui.py +0 -1065
- egse/filterwheel/eksma/testpythonfw.py +0 -215
- egse/fov/__init__.py +0 -65
- egse/fov/fov_hk.py +0 -710
- egse/fov/fov_ui.py +0 -859
- egse/fov/fov_ui_controller.py +0 -140
- egse/fov/fov_ui_model.py +0 -200
- egse/fov/fov_ui_view.py +0 -345
- egse/gimbal/__init__.py +0 -32
- egse/gimbal/symetrie/__init__.py +0 -26
- egse/gimbal/symetrie/alpha.py +0 -586
- egse/gimbal/symetrie/generic_gimbal_ui.py +0 -1521
- egse/gimbal/symetrie/gimbal.py +0 -877
- egse/gimbal/symetrie/gimbal.yaml +0 -168
- egse/gimbal/symetrie/gimbal_cs.py +0 -183
- egse/gimbal/symetrie/gimbal_protocol.py +0 -138
- egse/gimbal/symetrie/gimbal_ui.py +0 -361
- egse/gimbal/symetrie/pmac.py +0 -1006
- egse/gimbal/symetrie/pmac_regex.py +0 -83
- egse/graph.py +0 -132
- egse/gui/__init__.py +0 -47
- egse/gui/buttons.py +0 -378
- egse/gui/focalplane.py +0 -1285
- egse/gui/formatter.py +0 -10
- egse/gui/led.py +0 -162
- egse/gui/limitswitch.py +0 -143
- egse/gui/mechanisms.py +0 -587
- egse/gui/states.py +0 -148
- egse/gui/stripchart.py +0 -729
- egse/gui/styles.qss +0 -48
- egse/gui/switch.py +0 -112
- egse/h5.py +0 -274
- egse/help/__init__.py +0 -0
- egse/help/help_ui.py +0 -126
- egse/hexapod/__init__.py +0 -32
- egse/hexapod/symetrie/__init__.py +0 -137
- egse/hexapod/symetrie/alpha.py +0 -874
- egse/hexapod/symetrie/dynalpha.py +0 -1387
- egse/hexapod/symetrie/hexapod_ui.py +0 -1516
- egse/hexapod/symetrie/pmac.py +0 -1010
- egse/hexapod/symetrie/pmac_regex.py +0 -83
- egse/hexapod/symetrie/puna.py +0 -1167
- egse/hexapod/symetrie/puna.yaml +0 -193
- egse/hexapod/symetrie/puna_cs.py +0 -195
- egse/hexapod/symetrie/puna_protocol.py +0 -134
- egse/hexapod/symetrie/puna_ui.py +0 -433
- egse/hexapod/symetrie/punaplus.py +0 -107
- egse/hexapod/symetrie/zonda.py +0 -872
- egse/hexapod/symetrie/zonda.yaml +0 -337
- egse/hexapod/symetrie/zonda_cs.py +0 -172
- egse/hexapod/symetrie/zonda_devif.py +0 -414
- egse/hexapod/symetrie/zonda_protocol.py +0 -123
- egse/hexapod/symetrie/zonda_ui.py +0 -449
- egse/hk.py +0 -791
- egse/icons/aeu-cs-start.svg +0 -117
- egse/icons/aeu-cs-stop.svg +0 -118
- egse/icons/aeu-cs.svg +0 -107
- egse/icons/aeu_cs-started.svg +0 -112
- egse/icons/aeu_cs-stopped.svg +0 -112
- egse/icons/aeu_cs.svg +0 -55
- egse/icons/alert.svg +0 -1
- egse/icons/arrow-double-left.png +0 -0
- egse/icons/arrow-double-right.png +0 -0
- egse/icons/arrow-up.svg +0 -11
- egse/icons/backward.svg +0 -1
- egse/icons/busy.svg +0 -1
- egse/icons/cleaning.svg +0 -115
- egse/icons/color-scheme.svg +0 -1
- egse/icons/cs-connected-alert.svg +0 -91
- egse/icons/cs-connected-disabled.svg +0 -43
- egse/icons/cs-connected.svg +0 -89
- egse/icons/cs-not-connected.svg +0 -44
- egse/icons/double-left-arrow.svg +0 -1
- egse/icons/double-right-arrow.svg +0 -1
- egse/icons/erase-disabled.svg +0 -19
- egse/icons/erase.svg +0 -59
- egse/icons/fitsgen-start.svg +0 -47
- egse/icons/fitsgen-stop.svg +0 -48
- egse/icons/fitsgen.svg +0 -1
- egse/icons/forward.svg +0 -1
- egse/icons/fov-hk-start.svg +0 -33
- egse/icons/fov-hk-stop.svg +0 -37
- egse/icons/fov-hk.svg +0 -1
- egse/icons/front-desk.svg +0 -1
- egse/icons/home-actioned.svg +0 -15
- egse/icons/home-disabled.svg +0 -15
- egse/icons/home.svg +0 -13
- egse/icons/info.svg +0 -1
- egse/icons/invalid.png +0 -0
- egse/icons/led-green.svg +0 -20
- egse/icons/led-grey.svg +0 -20
- egse/icons/led-orange.svg +0 -20
- egse/icons/led-red.svg +0 -20
- egse/icons/led-square-green.svg +0 -134
- egse/icons/led-square-grey.svg +0 -134
- egse/icons/led-square-orange.svg +0 -134
- egse/icons/led-square-red.svg +0 -134
- egse/icons/limit-switch-all-green.svg +0 -115
- egse/icons/limit-switch-all-red.svg +0 -117
- egse/icons/limit-switch-el+.svg +0 -116
- egse/icons/limit-switch-el-.svg +0 -117
- egse/icons/location-marker.svg +0 -1
- egse/icons/logo-dpu.svg +0 -48
- egse/icons/logo-gimbal.svg +0 -112
- egse/icons/logo-huber.svg +0 -23
- egse/icons/logo-ogse.svg +0 -31
- egse/icons/logo-puna.svg +0 -92
- egse/icons/logo-tcs.svg +0 -29
- egse/icons/logo-zonda.svg +0 -66
- egse/icons/maximize.svg +0 -1
- egse/icons/meter.svg +0 -1
- egse/icons/more.svg +0 -45
- egse/icons/n-fee-hk-start.svg +0 -24
- egse/icons/n-fee-hk-stop.svg +0 -25
- egse/icons/n-fee-hk.svg +0 -83
- egse/icons/observing-off.svg +0 -46
- egse/icons/observing-on.svg +0 -46
- egse/icons/open-document-hdf5.png +0 -0
- egse/icons/open-document-hdf5.svg +0 -21
- egse/icons/ops-mode.svg +0 -1
- egse/icons/play-green.svg +0 -17
- egse/icons/plugged-disabled.svg +0 -27
- egse/icons/plugged.svg +0 -21
- egse/icons/pm_ui.svg +0 -1
- egse/icons/power-button-green.svg +0 -27
- egse/icons/power-button-red.svg +0 -27
- egse/icons/power-button.svg +0 -27
- egse/icons/radar.svg +0 -1
- egse/icons/radioactive.svg +0 -2
- egse/icons/reload.svg +0 -1
- egse/icons/remote-control-off.svg +0 -28
- egse/icons/remote-control-on.svg +0 -28
- egse/icons/repeat-blue.svg +0 -15
- egse/icons/repeat.svg +0 -1
- egse/icons/settings.svg +0 -1
- egse/icons/shrink.svg +0 -1
- egse/icons/shutter.svg +0 -1
- egse/icons/sign-off.svg +0 -1
- egse/icons/sign-on.svg +0 -1
- egse/icons/sim-mode.svg +0 -1
- egse/icons/small-buttons-go.svg +0 -20
- egse/icons/small-buttons-minus.svg +0 -51
- egse/icons/small-buttons-plus.svg +0 -51
- egse/icons/sponge.svg +0 -220
- egse/icons/start-button-disabled.svg +0 -84
- egse/icons/start-button.svg +0 -50
- egse/icons/stop-button-disabled.svg +0 -84
- egse/icons/stop-button.svg +0 -50
- egse/icons/stop-red.svg +0 -17
- egse/icons/stop.svg +0 -1
- egse/icons/switch-disabled-square.svg +0 -87
- egse/icons/switch-disabled.svg +0 -15
- egse/icons/switch-off-square.svg +0 -87
- egse/icons/switch-off.svg +0 -72
- egse/icons/switch-on-square.svg +0 -87
- egse/icons/switch-on.svg +0 -61
- egse/icons/temperature-control.svg +0 -44
- egse/icons/th_ui_logo.svg +0 -1
- egse/icons/unplugged.svg +0 -23
- egse/icons/unvalid.png +0 -0
- egse/icons/user-interface.svg +0 -1
- egse/icons/vacuum.svg +0 -1
- egse/icons/valid.png +0 -0
- egse/icons/zoom-to-pixel-dark.svg +0 -64
- egse/icons/zoom-to-pixel-white.svg +0 -36
- egse/images/big-rotation-stage.png +0 -0
- egse/images/connected-100.png +0 -0
- egse/images/cross.svg +0 -6
- egse/images/disconnected-100.png +0 -0
- egse/images/gui-icon.png +0 -0
- egse/images/home.svg +0 -6
- egse/images/info-icon.png +0 -0
- egse/images/led-black.svg +0 -89
- egse/images/led-green.svg +0 -85
- egse/images/led-orange.svg +0 -85
- egse/images/led-red.svg +0 -85
- egse/images/load-icon.png +0 -0
- egse/images/load-setup.png +0 -0
- egse/images/load.png +0 -0
- egse/images/pause.png +0 -0
- egse/images/play-button.svg +0 -8
- egse/images/play.png +0 -0
- egse/images/process-status.png +0 -0
- egse/images/restart.png +0 -0
- egse/images/search.png +0 -0
- egse/images/sma.png +0 -0
- egse/images/start.png +0 -0
- egse/images/stop-button.svg +0 -8
- egse/images/stop.png +0 -0
- egse/images/switch-off.svg +0 -48
- egse/images/switch-on.svg +0 -48
- egse/images/undo.png +0 -0
- egse/images/update-button.svg +0 -11
- egse/imageviewer/exposureselection.py +0 -475
- egse/imageviewer/imageviewer.py +0 -198
- egse/imageviewer/matchfocalplane.py +0 -179
- egse/imageviewer/subfieldposition.py +0 -133
- egse/lampcontrol/__init__.py +0 -4
- egse/lampcontrol/beaglebone/beaglebone.py +0 -178
- egse/lampcontrol/beaglebone/beaglebone.yaml +0 -62
- egse/lampcontrol/beaglebone/beaglebone_cs.py +0 -106
- egse/lampcontrol/beaglebone/beaglebone_devif.py +0 -150
- egse/lampcontrol/beaglebone/beaglebone_protocol.py +0 -73
- egse/lampcontrol/energetiq/__init__.py +0 -22
- egse/lampcontrol/energetiq/eq99.yaml +0 -98
- egse/lampcontrol/energetiq/lampEQ99.py +0 -283
- egse/lampcontrol/energetiq/lampEQ99_cs.py +0 -128
- egse/lampcontrol/energetiq/lampEQ99_devif.py +0 -158
- egse/lampcontrol/energetiq/lampEQ99_encode_decode_errors.py +0 -73
- egse/lampcontrol/energetiq/lampEQ99_protocol.py +0 -71
- egse/lampcontrol/energetiq/lampEQ99_ui.py +0 -465
- egse/lib/CentOS-7/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/CentOS-8/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/CentOS-8/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Debian/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Debian/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Debian/libetherspacelink_v35_21.dylib +0 -0
- egse/lib/Linux/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Linux/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/Ubuntu-20/ESL-RMAP_v34_86.dylib +0 -0
- egse/lib/Ubuntu-20/EtherSpaceLink_v34_86.dylib +0 -0
- egse/lib/gssw/python3-gssw_2.2.3+31f63c9f-1_all.deb +0 -0
- egse/lib/ximc/__pycache__/pyximc.cpython-38 2.pyc +0 -0
- egse/lib/ximc/__pycache__/pyximc.cpython-38.pyc +0 -0
- egse/lib/ximc/libximc.framework/Frameworks/libbindy.dylib +0 -0
- egse/lib/ximc/libximc.framework/Frameworks/libxiwrapper.dylib +0 -0
- egse/lib/ximc/libximc.framework/Headers/ximc.h +0 -5510
- egse/lib/ximc/libximc.framework/Resources/Info.plist +0 -42
- egse/lib/ximc/libximc.framework/Resources/keyfile.sqlite +0 -0
- egse/lib/ximc/libximc.framework/libbindy.so +0 -0
- egse/lib/ximc/libximc.framework/libximc +0 -0
- egse/lib/ximc/libximc.framework/libximc.so +0 -0
- egse/lib/ximc/libximc.framework/libximc.so.7.0.0 +0 -0
- egse/lib/ximc/libximc.framework/libxiwrapper.so +0 -0
- egse/lib/ximc/pyximc.py +0 -922
- egse/listener.py +0 -179
- egse/logger/__init__.py +0 -243
- egse/logger/log_cs.py +0 -321
- egse/metrics.py +0 -102
- egse/mixin.py +0 -464
- egse/monitoring.py +0 -95
- egse/ni/alarms/__init__.py +0 -26
- egse/ni/alarms/cdaq9375.py +0 -300
- egse/ni/alarms/cdaq9375.yaml +0 -89
- egse/ni/alarms/cdaq9375_cs.py +0 -130
- egse/ni/alarms/cdaq9375_devif.py +0 -183
- egse/ni/alarms/cdaq9375_protocol.py +0 -48
- egse/obs_inspection.py +0 -165
- egse/observer.py +0 -41
- egse/obsid.py +0 -163
- egse/powermeter/__init__.py +0 -0
- egse/powermeter/ni/__init__.py +0 -38
- egse/powermeter/ni/cdaq9184.py +0 -224
- egse/powermeter/ni/cdaq9184.yaml +0 -73
- egse/powermeter/ni/cdaq9184_cs.py +0 -130
- egse/powermeter/ni/cdaq9184_devif.py +0 -201
- egse/powermeter/ni/cdaq9184_protocol.py +0 -48
- egse/powermeter/ni/cdaq9184_ui.py +0 -544
- egse/powermeter/thorlabs/__init__.py +0 -25
- egse/powermeter/thorlabs/pm100a.py +0 -380
- egse/powermeter/thorlabs/pm100a.yaml +0 -132
- egse/powermeter/thorlabs/pm100a_cs.py +0 -136
- egse/powermeter/thorlabs/pm100a_devif.py +0 -127
- egse/powermeter/thorlabs/pm100a_protocol.py +0 -80
- egse/powermeter/thorlabs/pm100a_ui.py +0 -725
- egse/process.py +0 -451
- egse/procman/__init__.py +0 -834
- egse/procman/cannot_start_process_popup.py +0 -43
- egse/procman/procman.yaml +0 -49
- egse/procman/procman_cs.py +0 -201
- egse/procman/procman_ui.py +0 -2081
- egse/protocol.py +0 -605
- egse/proxy.py +0 -531
- egse/randomwalk.py +0 -140
- egse/reg.py +0 -585
- egse/reload.py +0 -122
- egse/reprocess.py +0 -693
- egse/resource.py +0 -333
- egse/rmap.py +0 -406
- egse/rst.py +0 -135
- egse/search.py +0 -182
- egse/serialdevice.py +0 -190
- egse/services.py +0 -247
- egse/services.yaml +0 -68
- egse/settings.py +0 -379
- egse/settings.yaml +0 -980
- egse/setup.py +0 -1181
- egse/shutter/__init__.py +0 -0
- egse/shutter/thorlabs/__init__.py +0 -19
- egse/shutter/thorlabs/ksc101.py +0 -205
- egse/shutter/thorlabs/ksc101.yaml +0 -105
- egse/shutter/thorlabs/ksc101_cs.py +0 -136
- egse/shutter/thorlabs/ksc101_devif.py +0 -201
- egse/shutter/thorlabs/ksc101_protocol.py +0 -71
- egse/shutter/thorlabs/ksc101_ui.py +0 -548
- egse/shutter/thorlabs/sc10.py +0 -82
- egse/shutter/thorlabs/sc10.yaml +0 -52
- egse/shutter/thorlabs/sc10_controller.py +0 -81
- egse/shutter/thorlabs/sc10_cs.py +0 -108
- egse/shutter/thorlabs/sc10_interface.py +0 -25
- egse/shutter/thorlabs/sc10_simulator.py +0 -30
- egse/simulator.py +0 -41
- egse/slack.py +0 -61
- egse/socketdevice.py +0 -218
- egse/sockets.py +0 -218
- egse/spw.py +0 -1401
- egse/stages/__init__.py +0 -12
- egse/stages/aerotech/ensemble.py +0 -245
- egse/stages/aerotech/ensemble.yaml +0 -205
- egse/stages/aerotech/ensemble_controller.py +0 -275
- egse/stages/aerotech/ensemble_cs.py +0 -110
- egse/stages/aerotech/ensemble_interface.py +0 -132
- egse/stages/aerotech/ensemble_parameters.py +0 -433
- egse/stages/aerotech/ensemble_simulator.py +0 -27
- egse/stages/aerotech/mgse_sim.py +0 -188
- egse/stages/arun/smd3.py +0 -110
- egse/stages/arun/smd3.yaml +0 -68
- egse/stages/arun/smd3_controller.py +0 -470
- egse/stages/arun/smd3_cs.py +0 -112
- egse/stages/arun/smd3_interface.py +0 -53
- egse/stages/arun/smd3_simulator.py +0 -27
- egse/stages/arun/smd3_stop.py +0 -16
- egse/stages/huber/__init__.py +0 -49
- egse/stages/huber/smc9300.py +0 -920
- egse/stages/huber/smc9300.yaml +0 -63
- egse/stages/huber/smc9300_cs.py +0 -178
- egse/stages/huber/smc9300_devif.py +0 -345
- egse/stages/huber/smc9300_protocol.py +0 -113
- egse/stages/huber/smc9300_sim.py +0 -547
- egse/stages/huber/smc9300_ui.py +0 -973
- egse/state.py +0 -173
- egse/statemachine.py +0 -274
- egse/storage/__init__.py +0 -1067
- egse/storage/persistence.py +0 -2295
- egse/storage/storage.yaml +0 -79
- egse/storage/storage_cs.py +0 -231
- egse/styles/dark.qss +0 -343
- egse/styles/default.qss +0 -48
- egse/synoptics/__init__.py +0 -417
- egse/synoptics/syn.yaml +0 -9
- egse/synoptics/syn_cs.py +0 -195
- egse/system.py +0 -1611
- egse/tcs/__init__.py +0 -14
- egse/tcs/tcs.py +0 -879
- egse/tcs/tcs.yaml +0 -14
- egse/tcs/tcs_cs.py +0 -202
- egse/tcs/tcs_devif.py +0 -292
- egse/tcs/tcs_protocol.py +0 -180
- egse/tcs/tcs_sim.py +0 -177
- egse/tcs/tcs_ui.py +0 -543
- egse/tdms.py +0 -171
- egse/tempcontrol/__init__.py +0 -23
- egse/tempcontrol/agilent/agilent34970.py +0 -109
- egse/tempcontrol/agilent/agilent34970.yaml +0 -44
- egse/tempcontrol/agilent/agilent34970_cs.py +0 -114
- egse/tempcontrol/agilent/agilent34970_devif.py +0 -182
- egse/tempcontrol/agilent/agilent34970_protocol.py +0 -96
- egse/tempcontrol/agilent/agilent34972.py +0 -111
- egse/tempcontrol/agilent/agilent34972.yaml +0 -44
- egse/tempcontrol/agilent/agilent34972_cs.py +0 -115
- egse/tempcontrol/agilent/agilent34972_devif.py +0 -189
- egse/tempcontrol/agilent/agilent34972_protocol.py +0 -98
- egse/tempcontrol/beaglebone/beaglebone.py +0 -341
- egse/tempcontrol/beaglebone/beaglebone.yaml +0 -110
- egse/tempcontrol/beaglebone/beaglebone_cs.py +0 -117
- egse/tempcontrol/beaglebone/beaglebone_protocol.py +0 -134
- egse/tempcontrol/beaglebone/beaglebone_ui.py +0 -674
- egse/tempcontrol/digalox/digalox.py +0 -115
- egse/tempcontrol/digalox/digalox.yaml +0 -36
- egse/tempcontrol/digalox/digalox_cs.py +0 -108
- egse/tempcontrol/digalox/digalox_protocol.py +0 -56
- egse/tempcontrol/keithley/__init__.py +0 -33
- egse/tempcontrol/keithley/daq6510.py +0 -662
- egse/tempcontrol/keithley/daq6510.yaml +0 -105
- egse/tempcontrol/keithley/daq6510_cs.py +0 -163
- egse/tempcontrol/keithley/daq6510_devif.py +0 -343
- egse/tempcontrol/keithley/daq6510_protocol.py +0 -79
- egse/tempcontrol/keithley/daq6510_sim.py +0 -186
- egse/tempcontrol/lakeshore/__init__.py +0 -33
- egse/tempcontrol/lakeshore/lsci.py +0 -361
- egse/tempcontrol/lakeshore/lsci.yaml +0 -162
- egse/tempcontrol/lakeshore/lsci_cs.py +0 -174
- egse/tempcontrol/lakeshore/lsci_devif.py +0 -292
- egse/tempcontrol/lakeshore/lsci_protocol.py +0 -76
- egse/tempcontrol/lakeshore/lsci_ui.py +0 -387
- egse/tempcontrol/ni/__init__.py +0 -0
- egse/tempcontrol/spid/spid.py +0 -109
- egse/tempcontrol/spid/spid.yaml +0 -81
- egse/tempcontrol/spid/spid_controller.py +0 -279
- egse/tempcontrol/spid/spid_cs.py +0 -136
- egse/tempcontrol/spid/spid_protocol.py +0 -107
- egse/tempcontrol/spid/spid_ui.py +0 -723
- egse/tempcontrol/srs/__init__.py +0 -22
- egse/tempcontrol/srs/ptc10.py +0 -867
- egse/tempcontrol/srs/ptc10.yaml +0 -227
- egse/tempcontrol/srs/ptc10_cs.py +0 -128
- egse/tempcontrol/srs/ptc10_devif.py +0 -116
- egse/tempcontrol/srs/ptc10_protocol.py +0 -39
- egse/tempcontrol/srs/ptc10_ui.py +0 -906
- egse/ups/apc/apc.py +0 -236
- egse/ups/apc/apc.yaml +0 -45
- egse/ups/apc/apc_cs.py +0 -101
- egse/ups/apc/apc_protocol.py +0 -125
- egse/user.yaml +0 -7
- egse/vacuum/beaglebone/beaglebone.py +0 -149
- egse/vacuum/beaglebone/beaglebone.yaml +0 -44
- egse/vacuum/beaglebone/beaglebone_cs.py +0 -108
- egse/vacuum/beaglebone/beaglebone_devif.py +0 -159
- egse/vacuum/beaglebone/beaglebone_protocol.py +0 -192
- egse/vacuum/beaglebone/beaglebone_ui.py +0 -638
- egse/vacuum/instrutech/igm402.py +0 -91
- egse/vacuum/instrutech/igm402.yaml +0 -90
- egse/vacuum/instrutech/igm402_controller.py +0 -124
- egse/vacuum/instrutech/igm402_cs.py +0 -108
- egse/vacuum/instrutech/igm402_interface.py +0 -49
- egse/vacuum/instrutech/igm402_simulator.py +0 -36
- egse/vacuum/keller/kellerBus.py +0 -256
- egse/vacuum/keller/leo3.py +0 -100
- egse/vacuum/keller/leo3.yaml +0 -38
- egse/vacuum/keller/leo3_controller.py +0 -81
- egse/vacuum/keller/leo3_cs.py +0 -101
- egse/vacuum/keller/leo3_interface.py +0 -33
- egse/vacuum/mks/evision.py +0 -86
- egse/vacuum/mks/evision.yaml +0 -75
- egse/vacuum/mks/evision_cs.py +0 -101
- egse/vacuum/mks/evision_devif.py +0 -313
- egse/vacuum/mks/evision_interface.py +0 -60
- egse/vacuum/mks/evision_simulator.py +0 -24
- egse/vacuum/mks/evision_ui.py +0 -701
- egse/vacuum/pfeiffer/acp40.py +0 -87
- egse/vacuum/pfeiffer/acp40.yaml +0 -60
- egse/vacuum/pfeiffer/acp40_controller.py +0 -117
- egse/vacuum/pfeiffer/acp40_cs.py +0 -109
- egse/vacuum/pfeiffer/acp40_interface.py +0 -40
- egse/vacuum/pfeiffer/acp40_simulator.py +0 -37
- egse/vacuum/pfeiffer/tc400.py +0 -87
- egse/vacuum/pfeiffer/tc400.yaml +0 -83
- egse/vacuum/pfeiffer/tc400_controller.py +0 -136
- egse/vacuum/pfeiffer/tc400_cs.py +0 -109
- egse/vacuum/pfeiffer/tc400_interface.py +0 -70
- egse/vacuum/pfeiffer/tc400_simulator.py +0 -35
- egse/vacuum/pfeiffer/tpg261.py +0 -80
- egse/vacuum/pfeiffer/tpg261.yaml +0 -66
- egse/vacuum/pfeiffer/tpg261_controller.py +0 -150
- egse/vacuum/pfeiffer/tpg261_cs.py +0 -109
- egse/vacuum/pfeiffer/tpg261_interface.py +0 -59
- egse/vacuum/pfeiffer/tpg261_simulator.py +0 -23
- egse/version.py +0 -174
- egse/visitedpositions.py +0 -398
- egse/windowing.py +0 -213
- egse/zmq/__init__.py +0 -28
- egse/zmq/spw.py +0 -160
- egse/zmq_ser.py +0 -41
- scripts/alerts/cold.yaml +0 -278
- scripts/alerts/example_alerts.yaml +0 -54
- scripts/alerts/transition.yaml +0 -14
- scripts/alerts/warm.yaml +0 -49
- scripts/analyse_n_fee_hk_data.py +0 -52
- scripts/check_hdf5_files.py +0 -192
- scripts/check_register_sync.py +0 -47
- scripts/check_tcs_calib_coef.py +0 -90
- scripts/correct_ccd_cold_temperature_cal.py +0 -157
- scripts/create_hdf5_report.py +0 -293
- scripts/csl_model.py +0 -420
- scripts/csl_restore_setup.py +0 -229
- scripts/export-grafana-dashboards.py +0 -49
- scripts/fdir/cs_recovery/fdir_cs_recovery.py +0 -54
- scripts/fdir/fdir_table.yaml +0 -70
- scripts/fdir/fdir_test_recovery.py +0 -10
- scripts/fdir/hw_recovery/fdir_agilent_hw_recovery.py +0 -73
- scripts/fdir/limit_recovery/fdir_agilent_limit.py +0 -61
- scripts/fdir/limit_recovery/fdir_bb_heater_limit.py +0 -59
- scripts/fdir/limit_recovery/fdir_ensemble_limit.py +0 -33
- scripts/fdir/limit_recovery/fdir_pressure_limit_recovery.py +0 -71
- scripts/fix_csv.py +0 -80
- scripts/ias/correct_ccd_temp_cal_elfique.py +0 -43
- scripts/ias/correct_ccd_temp_cal_floreffe.py +0 -43
- scripts/ias/correct_trp_swap_achel.py +0 -199
- scripts/inta/correct_ccd_temp_cal_duvel.py +0 -43
- scripts/inta/correct_ccd_temp_cal_gueuze.py +0 -43
- scripts/n_fee_supply_voltage_calculation.py +0 -92
- scripts/playground.py +0 -30
- scripts/print_hdf5_hk_data.py +0 -68
- scripts/print_register_map.py +0 -43
- scripts/remove_lines_between_matches.py +0 -188
- scripts/sron/commanding/control_heaters.py +0 -44
- scripts/sron/commanding/pumpdown.py +0 -46
- scripts/sron/commanding/set_pid_setpoint.py +0 -19
- scripts/sron/commanding/shutdown_bbb_heaters.py +0 -10
- scripts/sron/commanding/shutdown_pumps.py +0 -33
- scripts/sron/correct_mgse_coordinates_brigand_chimay.py +0 -272
- scripts/sron/correct_trp_swap_brigand.py +0 -204
- scripts/sron/gimbal_conversions.py +0 -75
- scripts/sron/tm_gen/tm_gen_agilent.py +0 -37
- scripts/sron/tm_gen/tm_gen_heaters.py +0 -4
- scripts/sron/tm_gen/tm_gen_spid.py +0 -13
- scripts/update_operational_cgse.py +0 -268
- scripts/update_operational_cgse_old.py +0 -273
egse/hk.py
DELETED
|
@@ -1,791 +0,0 @@
|
|
|
1
|
-
import csv
|
|
2
|
-
import datetime
|
|
3
|
-
import logging
|
|
4
|
-
from enum import Enum
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from typing import Union, Optional
|
|
7
|
-
|
|
8
|
-
import dateutil.parser as date_parser
|
|
9
|
-
import numpy as np
|
|
10
|
-
|
|
11
|
-
from egse.config import find_files
|
|
12
|
-
from egse.env import get_data_storage_location
|
|
13
|
-
from egse.obsid import ObservationIdentifier
|
|
14
|
-
from egse.obsid import obsid_from_storage
|
|
15
|
-
from egse.settings import Settings
|
|
16
|
-
from egse.setup import SetupError, load_setup, Setup
|
|
17
|
-
from egse.system import SECONDS_IN_A_DAY
|
|
18
|
-
from egse.system import read_last_line
|
|
19
|
-
from egse.system import read_last_lines
|
|
20
|
-
from egse.system import str_to_datetime
|
|
21
|
-
from egse.system import time_since_epoch_1958
|
|
22
|
-
|
|
23
|
-
logger = logging.getLogger(__name__)
|
|
24
|
-
|
|
25
|
-
SITE_ID = Settings.load("SITE").ID
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
class TmDictionaryColumns(str, Enum):
|
|
29
|
-
""" Enumeration of the relevant columns in the TM dictionary spreadsheet.
|
|
30
|
-
|
|
31
|
-
The relevant columns are:
|
|
32
|
-
|
|
33
|
-
- STORAGE_MNEMONIC: Column with the storage mnemonic of the process that generated the HK;
|
|
34
|
-
- CORRECT_HK_NAMES: Column with the correct HK names (that can be used in `get_housekeeping`);
|
|
35
|
-
- ORIGINAL_EGSE_HK_NAMES: Column with the names that were originally used in `get_housekeeping` the device
|
|
36
|
-
protocol;
|
|
37
|
-
- SYNOPTICS_ORIGIN_SRON: Column with the SRON-specific HK names (that will also be stored as synoptics);
|
|
38
|
-
- SYNOPTICS_ORIGIN_IAS: Column with the IAS-specific HK names (that will also be stored as synoptics);
|
|
39
|
-
- SYNOPTICS_ORIGIN_INTA: Column with the INTA-specific HK names (that will also be stored as synoptics);
|
|
40
|
-
- CAL_OFFSET_B: Column with offset b for the linear calibration curve;
|
|
41
|
-
- CAL_SLOPE_A: Column with slope a for the linear calibration curve;
|
|
42
|
-
- TIMESTAMP_NAMES: Column with the name of the timestamps.
|
|
43
|
-
- DASHBOARD: Column with the name of the dashboard that holds the HK metric
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
|
-
STORAGE_MNEMONIC = "Storage mnemonic"
|
|
47
|
-
CORRECT_HK_NAMES = "CAM EGSE mnemonic"
|
|
48
|
-
ORIGINAL_EGSE_HK_NAMES = "Original name in EGSE"
|
|
49
|
-
SYNOPTICS_ORIGIN_CSL = "Origin of synoptics at CSL"
|
|
50
|
-
SYNOPTICS_ORIGIN_SRON = " Origin of synoptics at SRON"
|
|
51
|
-
SYNOPTICS_ORIGIN_IAS = " Origin of synoptics at IAS"
|
|
52
|
-
SYNOPTICS_ORIGIN_INTA = " Origin of synoptics at INTA"
|
|
53
|
-
CAL_OFFSET_B = "offset b cal1"
|
|
54
|
-
CAL_SLOPE_A = "slope a cal1"
|
|
55
|
-
TIMESTAMP_NAMES = "Name of corresponding timestamp"
|
|
56
|
-
DESCRIPTION = "Description"
|
|
57
|
-
DASHBOARD = "MON screen"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
class HKError(Exception):
|
|
61
|
-
"""An HK-specific error."""
|
|
62
|
-
pass
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def get_housekeeping(hk_name: str, obsid: Union[ObservationIdentifier, str, int] = None, od: str = None,
|
|
66
|
-
time_window: int = None, data_dir=None, setup: Optional[Setup] = None):
|
|
67
|
-
"""
|
|
68
|
-
Returns the timestamp(s) and housekeeping value(s) for the housekeeping parameter with the given name.
|
|
69
|
-
|
|
70
|
-
It is possible to indicate for which obsid or which OD the housekeeping is to be returned. If neither of them is
|
|
71
|
-
specified, the latest daily files are used.
|
|
72
|
-
|
|
73
|
-
When the time window has not been specified, the last timestamp and housekeeping value will be returned for the
|
|
74
|
-
given OD. It is possible that a component stopped writing HK for some reason, and that the last housekeeping value
|
|
75
|
-
is older than you would want. It is therefore important to inspect the corresponding timestamp.
|
|
76
|
-
|
|
77
|
-
When the time window has been specified, the relevant housekeeping will be read:
|
|
78
|
-
|
|
79
|
-
* determine the sampling rate (compare the timestamps for the last 2 lines in the housekeeping file);
|
|
80
|
-
* determine how many samples we need to read (starting at the back);
|
|
81
|
-
* read the required number of line, starting at the back;
|
|
82
|
-
* for each of the read lines, append the timestamp and HK value to the arrays that will be returned
|
|
83
|
-
|
|
84
|
-
Args:
|
|
85
|
-
hk_name: Name of the housekeeping parameter.
|
|
86
|
-
obsid: Observation identifier. This can be an ObservationIdentifier object, a string in format TEST_LAB or
|
|
87
|
-
TEST_LAB_SETUP, or an integer representing the test ID; optional.
|
|
88
|
-
od: Identifier for the OD (yyyymmdd); optional.
|
|
89
|
-
time_window: Length of the time window over which to retrieve the housekeeping [s]. The time window ends at
|
|
90
|
-
the moment this method is called. If not given, the latest housekeeping value is returned.
|
|
91
|
-
data_dir: Folder (with sub-folders /daily and /obs) in which the HK files are stored. If this argument is not
|
|
92
|
-
provided, the data_dir will be determined from the environment variable PLATO_DATA_STORAGE_LOCATION.
|
|
93
|
-
setup: Setup
|
|
94
|
-
|
|
95
|
-
Raises:
|
|
96
|
-
A HKError when one of the following problems occur
|
|
97
|
-
* no obsid nor an od argument was provided
|
|
98
|
-
* no HK measures were found for the given parameter and obsid/od
|
|
99
|
-
|
|
100
|
-
Returns:
|
|
101
|
-
- If the time window has not been specified: the most recent timestamp and housekeeping value.
|
|
102
|
-
- If the time window has been specified: an array of timestamps and an array of housekeeping values, belonging
|
|
103
|
-
to the specified time window.
|
|
104
|
-
|
|
105
|
-
"""
|
|
106
|
-
|
|
107
|
-
setup = setup or load_setup()
|
|
108
|
-
|
|
109
|
-
# Either specify the obsid or the OD (or neither of them) but not both
|
|
110
|
-
|
|
111
|
-
if obsid is not None and od is not None:
|
|
112
|
-
|
|
113
|
-
raise HKError(f"Both the obsid ({obsid}) and the OD ({od}) were specified.")
|
|
114
|
-
|
|
115
|
-
# Specified obsid (as integer or as string)
|
|
116
|
-
|
|
117
|
-
data_dir = data_dir or get_data_storage_location()
|
|
118
|
-
|
|
119
|
-
if obsid:
|
|
120
|
-
|
|
121
|
-
try:
|
|
122
|
-
return _get_housekeeping_obsid(hk_name, data_dir, obsid=obsid, time_window=time_window, setup=setup)
|
|
123
|
-
except (ValueError, StopIteration, FileNotFoundError) as exc:
|
|
124
|
-
raise HKError(f"No HK found for {hk_name} for obsid {obsid} at {SITE_ID}") from exc
|
|
125
|
-
|
|
126
|
-
# Specified OD
|
|
127
|
-
|
|
128
|
-
if od:
|
|
129
|
-
|
|
130
|
-
try:
|
|
131
|
-
return _get_housekeeping_od(hk_name, data_dir, od=od, time_window=time_window, setup=setup)
|
|
132
|
-
except (ValueError, StopIteration, FileNotFoundError) as exc:
|
|
133
|
-
raise HKError(f"No HK found for {hk_name} for OD {od} at {SITE_ID}") from exc
|
|
134
|
-
|
|
135
|
-
# Didn't specify neither the obsid nor the OD
|
|
136
|
-
|
|
137
|
-
try:
|
|
138
|
-
return _get_housekeeping_daily(hk_name, data_dir, time_window=time_window, setup=setup)
|
|
139
|
-
except (ValueError, StopIteration, FileNotFoundError) as exc:
|
|
140
|
-
raise HKError(f"No HK found for {hk_name} for today at {SITE_ID}") from exc
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def _get_housekeeping(hk_name: str, timestamp_name: str, hk_dir: str, files, time_window: int = None):
|
|
144
|
-
""" Return the timestamp(s) and HK value(s) for the HK parameter with the given name, for the given files.
|
|
145
|
-
|
|
146
|
-
When the time window has not been specified, the last timestamp and HK value will be returned for the given OD.
|
|
147
|
-
It is possible that a component stopped writing HK for some reason, and that the last HK value is older than you
|
|
148
|
-
would want. It is therefore important to inspect the corresponding timestamp.
|
|
149
|
-
|
|
150
|
-
When the time window has been specified, the relevant HK will be read:
|
|
151
|
-
- determine the sampling rate (compare the timestamps for the last 2 lines in the HK file);
|
|
152
|
-
- determine how many samples we need to read (starting at the back);
|
|
153
|
-
- read the required number of line, starting at the back;
|
|
154
|
-
- for each of the read lines, append the timestamp and HK value to the arrays that will be returned
|
|
155
|
-
|
|
156
|
-
Args:
|
|
157
|
-
- hk_name: Name of the housekeeping parameter.
|
|
158
|
-
- timestamp_name: Name of the corresponding timestamp.
|
|
159
|
-
- hk_dir: Directory with the housekeeping files.
|
|
160
|
-
- files: Relative filepath of the selected housekeeping files.
|
|
161
|
-
- time_window: Length of the time window over which to retrieve the housekeeping [s]. The time window ends at
|
|
162
|
-
the moment this method is called. If not given, the latest HK-value is returned.
|
|
163
|
-
|
|
164
|
-
Returns:
|
|
165
|
-
- If the time window has not been specified: the most recent timestamp and housekeeping value.
|
|
166
|
-
- If the time window has been specified: an array of timestamps and an array of housekeeping values, belonging
|
|
167
|
-
to the specified time window.
|
|
168
|
-
"""
|
|
169
|
-
|
|
170
|
-
filename = files[-1]
|
|
171
|
-
|
|
172
|
-
# Indices of the columns we need
|
|
173
|
-
|
|
174
|
-
timestamp_index, hk_index = get_indices(hk_dir + filename, hk_name, timestamp_name)
|
|
175
|
-
|
|
176
|
-
# No time window specified: return the last value
|
|
177
|
-
|
|
178
|
-
if time_window is None:
|
|
179
|
-
|
|
180
|
-
return get_last_non_empty(hk_dir + filename, timestamp_index, hk_index)
|
|
181
|
-
|
|
182
|
-
# Time window specified
|
|
183
|
-
|
|
184
|
-
else:
|
|
185
|
-
|
|
186
|
-
# We will return an array of timestamps and an array of HK values
|
|
187
|
-
|
|
188
|
-
timestamp_array = np.array([])
|
|
189
|
-
hk_array = np.array([])
|
|
190
|
-
|
|
191
|
-
with open(hk_dir + filename) as file:
|
|
192
|
-
|
|
193
|
-
csv_reader = csv.reader(file)
|
|
194
|
-
next(csv_reader)
|
|
195
|
-
first_timepoint = next(csv_reader)[0].split(",")[timestamp_index] # Skip the header
|
|
196
|
-
|
|
197
|
-
last_timepoint = read_last_line(hk_dir + filename).split(",")[timestamp_index]
|
|
198
|
-
elapsed = (str_to_datetime(last_timepoint) - str_to_datetime(first_timepoint)).total_seconds()
|
|
199
|
-
|
|
200
|
-
# The time window is shorter than the timespan covered by the file
|
|
201
|
-
|
|
202
|
-
if time_window < elapsed:
|
|
203
|
-
|
|
204
|
-
sampling_rate = get_sampling_rate(hk_dir + filename, timestamp_name) # Time between subsequent samples
|
|
205
|
-
num_samples = int(round(time_window / sampling_rate))
|
|
206
|
-
|
|
207
|
-
lines = read_last_lines(hk_dir + filename, num_samples)
|
|
208
|
-
|
|
209
|
-
for line in lines:
|
|
210
|
-
|
|
211
|
-
line = line.split(",")
|
|
212
|
-
|
|
213
|
-
timestamp_array = np.append(timestamp_array, line[timestamp_index])
|
|
214
|
-
hk_array = np.append(hk_array, line[hk_index])
|
|
215
|
-
|
|
216
|
-
# The time window is longer than the timespan covered by the file: read all lines
|
|
217
|
-
|
|
218
|
-
else:
|
|
219
|
-
|
|
220
|
-
with open(hk_dir + filename) as file:
|
|
221
|
-
|
|
222
|
-
csv_reader = csv.reader(file)
|
|
223
|
-
next(csv_reader) # Skip the header
|
|
224
|
-
|
|
225
|
-
for row in csv_reader:
|
|
226
|
-
|
|
227
|
-
timestamp_array = np.append(timestamp_array, row[timestamp_index])
|
|
228
|
-
hk_array = np.append(hk_array, row[hk_index])
|
|
229
|
-
|
|
230
|
-
for index in range(len(timestamp_array)):
|
|
231
|
-
|
|
232
|
-
timestamp_array[index] = time_since_epoch_1958(timestamp_array[index])
|
|
233
|
-
|
|
234
|
-
return timestamp_array, hk_array
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
def _get_housekeeping_od(hk_name: str, data_dir, od: str, time_window: int = None, setup: Optional[Setup] = None):
|
|
238
|
-
""" Return the timestamp(s) and HK value(s) for the HK parameter with the given name, for the given OD.
|
|
239
|
-
|
|
240
|
-
When the time window has not been specified, the last timestamp and HK value will be returned for the given OD.
|
|
241
|
-
It is possible that a component stopped writing HK for some reason, and that the last HK value is older than you
|
|
242
|
-
would want. It is therefore important to inspect the corresponding timestamp.
|
|
243
|
-
|
|
244
|
-
When the time window has been specified, the relevant HK will be read:
|
|
245
|
-
- determine the sampling rate (compare the timestamps for the last 2 lines in the HK file);
|
|
246
|
-
- determine how many samples we need to read (starting at the back);
|
|
247
|
-
- read the required number of line, starting at the back;
|
|
248
|
-
- for each of the read lines, append the timestamp and HK value to the arrays that will be returned
|
|
249
|
-
|
|
250
|
-
Args:
|
|
251
|
-
- hk_name: Name of the housekeeping parameter.
|
|
252
|
-
- data_dir: Folder (with sub-folders /daily and /obs) in which the HK files are stored.
|
|
253
|
-
- od: Identifier for the OD (yyyymmdd).
|
|
254
|
-
- time_window: Length of the time window over which to retrieve the housekeeping [s]. The time window ends at
|
|
255
|
-
the moment this method is called. If not given, the latest HK-value is returned.
|
|
256
|
-
- setup: Setup.
|
|
257
|
-
|
|
258
|
-
Returns:
|
|
259
|
-
- If the time window has not been specified: the most recent timestamp and HK value.
|
|
260
|
-
- If the time window has been specified: an array of timestamps and an array of HK values, belonging to the
|
|
261
|
-
specified time window.
|
|
262
|
-
"""
|
|
263
|
-
|
|
264
|
-
setup = setup or load_setup()
|
|
265
|
-
hk_dir = f"{data_dir}/daily/" # Where the HK is stored
|
|
266
|
-
|
|
267
|
-
try:
|
|
268
|
-
|
|
269
|
-
origin, timestamp_name = get_hk_info(hk_name, setup=setup)
|
|
270
|
-
|
|
271
|
-
except KeyError:
|
|
272
|
-
|
|
273
|
-
raise HKError(f"Cannot determine which EGSE component generated HK parameter {hk_name}")
|
|
274
|
-
|
|
275
|
-
hk_dir += f"{od}/"
|
|
276
|
-
hk_files = [f"{od}_{SITE_ID}_{origin}.csv"]
|
|
277
|
-
|
|
278
|
-
return _get_housekeeping(hk_name, timestamp_name, hk_dir, hk_files, time_window=time_window)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
def _get_housekeeping_obsid(hk_name: str, data_dir, obsid: Union[ObservationIdentifier, str, int],
|
|
282
|
-
time_window: int = None, setup: Optional[Setup] = None):
|
|
283
|
-
""" Return the timestamp(s) and HK value(s) for the HK parameter with the given name, for the given obsid.
|
|
284
|
-
|
|
285
|
-
When the time window has not been specified, the last timestamp and HK value will be returned for the given obsid.
|
|
286
|
-
It is possible that a component stopped writing HK for some reason, and that the last HK value is older than you
|
|
287
|
-
would want. It is therefore important to inspect the corresponding timestamp.
|
|
288
|
-
|
|
289
|
-
When the time window has been specified, the relevant HK will be read:
|
|
290
|
-
- determine the sampling rate (compare the timestamps for the last 2 lines in the HK file);
|
|
291
|
-
- determine how many samples we need to read (starting at the back);
|
|
292
|
-
- read the required number of line, starting at the back;
|
|
293
|
-
- for each of the read lines, append the timestamp and HK value to the arrays that will be returned
|
|
294
|
-
|
|
295
|
-
Args:
|
|
296
|
-
- hk_name: Name of the housekeeping parameter.
|
|
297
|
-
- data_dir: Folder (with sub-folders /daily and /obs) in which the HK files are stored.
|
|
298
|
-
- obsid: Observation identifier. This can be an ObservationIdentifier object, a string in format TEST_LAB or
|
|
299
|
-
TEST_LAB_SETUP, or an integer representing the test ID.
|
|
300
|
-
- time_window: Length of the time window over which to retrieve the housekeeping [s]. The time window ends at
|
|
301
|
-
the moment this method is called. If not given, the latest HK-value is returned.
|
|
302
|
-
- setup: Setup.
|
|
303
|
-
|
|
304
|
-
Returns:
|
|
305
|
-
- If the time window has not been specified: the most recent timestamp and HK value.
|
|
306
|
-
- If the time window has been specified: an array of timestamps and an array of HK values, belonging to the
|
|
307
|
-
specified time window.
|
|
308
|
-
"""
|
|
309
|
-
|
|
310
|
-
setup = setup or load_setup()
|
|
311
|
-
|
|
312
|
-
hk_dir = f"{data_dir}/obs/" # Where the HK is stored
|
|
313
|
-
|
|
314
|
-
try:
|
|
315
|
-
|
|
316
|
-
origin, timestamp_name = get_hk_info(hk_name, setup=setup)
|
|
317
|
-
|
|
318
|
-
except KeyError:
|
|
319
|
-
|
|
320
|
-
raise HKError(f"Cannot determine which EGSE component generated HK parameter {hk_name}")
|
|
321
|
-
|
|
322
|
-
obsid = obsid_from_storage(obsid, data_dir=data_dir) # Convert the obsid to the correct format
|
|
323
|
-
|
|
324
|
-
hk_dir += f"{obsid}/"
|
|
325
|
-
pattern = f"{obsid}_{origin}_*.csv"
|
|
326
|
-
hk_files = sorted(find_files(pattern=pattern, root=hk_dir))
|
|
327
|
-
|
|
328
|
-
if len(hk_files) == 0:
|
|
329
|
-
|
|
330
|
-
raise HKError(f"No HK found for the {origin} at {SITE_ID} for obsid {obsid}")
|
|
331
|
-
|
|
332
|
-
hk_files = [hk_files[-1].name]
|
|
333
|
-
|
|
334
|
-
return _get_housekeeping(hk_name, timestamp_name, hk_dir, hk_files, time_window=time_window)
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
def _get_housekeeping_daily(hk_name: str, data_dir, time_window: int = None, setup: Optional[Setup] = None):
|
|
338
|
-
""" Return the timestamp(s) and HK value(s) for the HK parameter with the given name.
|
|
339
|
-
|
|
340
|
-
When the time window has not been specified, the last timestamp and HK value will be returned. It is possible that
|
|
341
|
-
a component stopped writing HK for some reason, and that the last HK value is older than you would want. It is
|
|
342
|
-
therefore important to inspect the corresponding timestamp.
|
|
343
|
-
|
|
344
|
-
When the time window has been specified, it is possible that we have to fetch the HK from multiple files,
|
|
345
|
-
depending on the length of the time window:
|
|
346
|
-
|
|
347
|
-
* Oldest file (i.e. the HK file in which the first timestamp in the specified time window is held): only part
|
|
348
|
-
of it will have to be read (start reading at the back):
|
|
349
|
-
- determine the filename;
|
|
350
|
-
- determine the sampling rate (compare the timestamps for the last 2 lines in the HK file);
|
|
351
|
-
- determine how many samples we need to read (starting at the back);
|
|
352
|
-
- read the required number of line, starting at the back;
|
|
353
|
-
- for each of the read lines, append the timestamp and HK value to the arrays that will be returned.
|
|
354
|
-
* Any other files: entire file will have to be read:
|
|
355
|
-
- determine the filename;
|
|
356
|
-
- read all lines;
|
|
357
|
-
- for each line: append the timestamp and HK value to the arrays that will be returned.
|
|
358
|
-
|
|
359
|
-
Args:
|
|
360
|
-
- hk_name: Name of the housekeeping parameter.
|
|
361
|
-
- data_dir: Folder (with sub-folders /daily and /obs) in which the HK files are stored.
|
|
362
|
-
- time_window: Length of the time window over which to retrieve the housekeeping [s]. The time window ends at
|
|
363
|
-
the moment this method is called. If not given, the latest HK-value is returned.
|
|
364
|
-
- setup: Setup.
|
|
365
|
-
|
|
366
|
-
Returns:
|
|
367
|
-
- If the time window has not been specified: the most recent timestamp and HK value.
|
|
368
|
-
- If the time window has been specified: an array of timestamps and an array of HK values, belonging to the
|
|
369
|
-
specified time window.
|
|
370
|
-
"""
|
|
371
|
-
|
|
372
|
-
setup = setup or load_setup()
|
|
373
|
-
hk_dir = f"{data_dir}/daily/" # Where the HK is stored
|
|
374
|
-
|
|
375
|
-
try:
|
|
376
|
-
|
|
377
|
-
origin, timestamp_name = get_hk_info(hk_name, setup=setup)
|
|
378
|
-
|
|
379
|
-
except KeyError:
|
|
380
|
-
|
|
381
|
-
raise HKError(f"Cannot determine which EGSE component generated HK parameter {hk_name}")
|
|
382
|
-
|
|
383
|
-
# No time window specified: return the last value
|
|
384
|
-
|
|
385
|
-
if time_window is None:
|
|
386
|
-
|
|
387
|
-
# Look for the last file of this component
|
|
388
|
-
|
|
389
|
-
timestamp = datetime.datetime.now(tz=datetime.timezone.utc).strftime("%Y%m%d")
|
|
390
|
-
hk_dir += f"{timestamp}/"
|
|
391
|
-
filename = f"{timestamp}_{SITE_ID}_{origin}.csv"
|
|
392
|
-
|
|
393
|
-
timestamp_index, hk_index = get_indices(hk_dir + filename, hk_name, timestamp_name)
|
|
394
|
-
return get_last_non_empty(hk_dir + filename, timestamp_index, hk_index)
|
|
395
|
-
|
|
396
|
-
# Time window specified
|
|
397
|
-
|
|
398
|
-
else:
|
|
399
|
-
|
|
400
|
-
# We will return an array of timestamps and an array of HK values
|
|
401
|
-
|
|
402
|
-
timestamp_array = np.array([])
|
|
403
|
-
hk_array = np.array([])
|
|
404
|
-
|
|
405
|
-
# Go back in time from this very moment and determine:
|
|
406
|
-
# - which timespan the most recent HK file covers (i.e. how much time has elapsed since midnight)
|
|
407
|
-
# - what the time is at the start of the time window
|
|
408
|
-
|
|
409
|
-
now = datetime.datetime.utcnow()
|
|
410
|
-
elapsed_since_midnight = now.microsecond * 1e-6 + now.second + 60 * (now.minute + 60 * now.hour)
|
|
411
|
-
start_time = now - datetime.timedelta(seconds=time_window)
|
|
412
|
-
start_od = f"{start_time.year}{start_time.month:02d}{start_time.day:02d}"
|
|
413
|
-
|
|
414
|
-
# Determine which columns will be needed from which file
|
|
415
|
-
|
|
416
|
-
filename = f"{start_od}/{start_od}_{SITE_ID}_{origin}.csv"
|
|
417
|
-
|
|
418
|
-
if Path(hk_dir + filename).exists():
|
|
419
|
-
|
|
420
|
-
timestamp_index, hk_index = get_indices(hk_dir + filename, hk_name, timestamp_name)
|
|
421
|
-
|
|
422
|
-
# Determine how many time samples you need to read in the first relevant HK file (starting from the back)
|
|
423
|
-
|
|
424
|
-
sampling_rate = get_sampling_rate(hk_dir + filename, timestamp_name) # Time between subsequent samples
|
|
425
|
-
|
|
426
|
-
if time_window <= elapsed_since_midnight:
|
|
427
|
-
|
|
428
|
-
num_samples_first_day = int(round(time_window / sampling_rate))
|
|
429
|
-
|
|
430
|
-
else:
|
|
431
|
-
|
|
432
|
-
time_window_first_day = (time_window - elapsed_since_midnight) % SECONDS_IN_A_DAY
|
|
433
|
-
num_samples_first_day = int(round(time_window_first_day / sampling_rate)) # TODO Round or floor?
|
|
434
|
-
|
|
435
|
-
# Read the required number of lines in the relevant HK file (starting from the back of the file)
|
|
436
|
-
|
|
437
|
-
lines_first_day = read_last_lines(hk_dir + filename, num_samples_first_day)
|
|
438
|
-
|
|
439
|
-
for line in lines_first_day:
|
|
440
|
-
|
|
441
|
-
line = line.split(",")
|
|
442
|
-
|
|
443
|
-
timestamp_array = np.append(timestamp_array, line[timestamp_index])
|
|
444
|
-
hk_array = np.append(hk_array, line[hk_index])
|
|
445
|
-
|
|
446
|
-
# In case we also need to read more recent files
|
|
447
|
-
# (those will have to be read entirely)
|
|
448
|
-
|
|
449
|
-
else:
|
|
450
|
-
|
|
451
|
-
logger.warning(f"No HK available for {origin} on "
|
|
452
|
-
f"{start_time.day}/{start_time.month}/{start_time.year}")
|
|
453
|
-
|
|
454
|
-
day = (start_time + datetime.timedelta(days=1)).date() # The day after the first day
|
|
455
|
-
last_day = datetime.date(now.year, now.month, now.day) # Today
|
|
456
|
-
|
|
457
|
-
while day <= last_day:
|
|
458
|
-
|
|
459
|
-
od = f"{day.year}{day.month:02d}{day.day:02d}"
|
|
460
|
-
filename = f"{od}/{od}_{SITE_ID}_{origin}.csv"
|
|
461
|
-
|
|
462
|
-
if Path(hk_dir + filename).exists():
|
|
463
|
-
|
|
464
|
-
with open(hk_dir + filename) as file:
|
|
465
|
-
|
|
466
|
-
csv_reader = csv.reader(file)
|
|
467
|
-
|
|
468
|
-
header = next(csv_reader) # Skip the header
|
|
469
|
-
timestamp_index = header.index("timestamp")
|
|
470
|
-
try:
|
|
471
|
-
hk_index = header.index(hk_name)
|
|
472
|
-
except ValueError:
|
|
473
|
-
raise HKError(f"Cannot find column {hk_name} in {filename}")
|
|
474
|
-
|
|
475
|
-
for row in csv_reader:
|
|
476
|
-
|
|
477
|
-
timestamp_array = np.append(timestamp_array, row[timestamp_index])
|
|
478
|
-
hk_array = np.append(hk_array, row[hk_index])
|
|
479
|
-
|
|
480
|
-
else:
|
|
481
|
-
|
|
482
|
-
logger.warning(f"No HK available for {origin} on {day.day}/{day.month}/{day.year}")
|
|
483
|
-
|
|
484
|
-
day += datetime.timedelta(days=1)
|
|
485
|
-
|
|
486
|
-
for index in range(len(timestamp_array)):
|
|
487
|
-
|
|
488
|
-
timestamp_array[index] = time_since_epoch_1958(timestamp_array[index])
|
|
489
|
-
|
|
490
|
-
return timestamp_array, hk_array
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
def get_last_non_empty(filename: str, timestamp_index: int, hk_index: int):
|
|
494
|
-
""" Return the timestamp and HK value for last real value.
|
|
495
|
-
|
|
496
|
-
Args:
|
|
497
|
-
- filename: HK file in which to look for the given HK parameter.
|
|
498
|
-
- timestamp_index: Index of the column with the timestamps.
|
|
499
|
-
- hk_index: Index of the column with the HK parameter with the given name.
|
|
500
|
-
|
|
501
|
-
Returns: The timestamp and HK value with the last real value.
|
|
502
|
-
"""
|
|
503
|
-
|
|
504
|
-
timestamp = None
|
|
505
|
-
hk_value = " "
|
|
506
|
-
|
|
507
|
-
filename = Path(filename)
|
|
508
|
-
|
|
509
|
-
if not filename.exists():
|
|
510
|
-
return None
|
|
511
|
-
|
|
512
|
-
# Declaring variable to implement exponential search
|
|
513
|
-
|
|
514
|
-
try:
|
|
515
|
-
|
|
516
|
-
num_lines = 1
|
|
517
|
-
|
|
518
|
-
while hk_value == " " or hk_value == "":
|
|
519
|
-
|
|
520
|
-
pos = num_lines + 1
|
|
521
|
-
|
|
522
|
-
# List to store last N lines
|
|
523
|
-
|
|
524
|
-
lines = []
|
|
525
|
-
|
|
526
|
-
with open(filename) as f:
|
|
527
|
-
|
|
528
|
-
while len(lines) <= num_lines:
|
|
529
|
-
|
|
530
|
-
try:
|
|
531
|
-
|
|
532
|
-
f.seek(-pos, 2)
|
|
533
|
-
|
|
534
|
-
except IOError:
|
|
535
|
-
|
|
536
|
-
f.seek(0)
|
|
537
|
-
break
|
|
538
|
-
|
|
539
|
-
finally:
|
|
540
|
-
|
|
541
|
-
lines = list(f)
|
|
542
|
-
|
|
543
|
-
# Increasing value of variable exponentially
|
|
544
|
-
|
|
545
|
-
pos *= 2
|
|
546
|
-
|
|
547
|
-
last_line = lines[-num_lines].rstrip("\r").split(",")
|
|
548
|
-
timestamp, hk_value = last_line[timestamp_index], last_line[hk_index]
|
|
549
|
-
|
|
550
|
-
num_lines += 1
|
|
551
|
-
|
|
552
|
-
return time_since_epoch_1958(timestamp), hk_value
|
|
553
|
-
|
|
554
|
-
except IndexError:
|
|
555
|
-
return None, None
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
def get_indices(filename: str, hk_name: str, timestamp_name: str):
|
|
559
|
-
""" Return the column number of the timestamp and given HK parameter in the given HK file.
|
|
560
|
-
|
|
561
|
-
Args:
|
|
562
|
-
- filename: HK file in which to look for the given HK parameter.
|
|
563
|
-
- hk_name: Name of the HK parameter.
|
|
564
|
-
- timestamp_name: Name of the corresponding timestamp.
|
|
565
|
-
|
|
566
|
-
Returns:
|
|
567
|
-
- Index of the column with the timestamps.
|
|
568
|
-
- Index of the column with the HK parameter with the given name.
|
|
569
|
-
"""
|
|
570
|
-
|
|
571
|
-
with open(filename, "r") as f:
|
|
572
|
-
|
|
573
|
-
reader = csv.reader(f)
|
|
574
|
-
header = next(reader) # Skip the header
|
|
575
|
-
|
|
576
|
-
timestamp_index = header.index(timestamp_name)
|
|
577
|
-
# timestamp_index = 0
|
|
578
|
-
|
|
579
|
-
try:
|
|
580
|
-
|
|
581
|
-
hk_index = header.index(hk_name)
|
|
582
|
-
|
|
583
|
-
except ValueError:
|
|
584
|
-
|
|
585
|
-
raise HKError(f"Cannot find column {hk_name} in {filename}")
|
|
586
|
-
|
|
587
|
-
return timestamp_index, hk_index
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
def get_sampling_rate(filename: str, timestamp_name: str):
|
|
591
|
-
""" Return the sampling rate for the HK file with the given name [s].
|
|
592
|
-
|
|
593
|
-
The sampling rate is determine as the difference between the timestamps of the last two lines of the HK file.
|
|
594
|
-
|
|
595
|
-
Args:
|
|
596
|
-
- filename: Name of the HK file. We do not check explicitly whether this file exists.
|
|
597
|
-
|
|
598
|
-
Returns: Sampling rate for the HK file with the given name [s].
|
|
599
|
-
"""
|
|
600
|
-
|
|
601
|
-
# Determine which column comprises the timestamp
|
|
602
|
-
|
|
603
|
-
with open(filename, "r") as f:
|
|
604
|
-
|
|
605
|
-
reader = csv.reader(f)
|
|
606
|
-
header = next(reader) # Skip the header
|
|
607
|
-
|
|
608
|
-
timestamp_index = header.index(timestamp_name)
|
|
609
|
-
|
|
610
|
-
# Read the last 2 lines and extract the timestamps for these lines
|
|
611
|
-
|
|
612
|
-
eof = read_last_lines(filename, 2)
|
|
613
|
-
|
|
614
|
-
penultimate_timestamp = date_parser.parse(eof[0].split(",")[timestamp_index])
|
|
615
|
-
last_timestamp = date_parser.parse(eof[1].split(",")[timestamp_index])
|
|
616
|
-
|
|
617
|
-
# Calculate the sampling rate [s]
|
|
618
|
-
|
|
619
|
-
return (last_timestamp - penultimate_timestamp).total_seconds()
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
def convert_hk_names(original_hk: dict, conversion_dict: dict) -> dict:
|
|
623
|
-
"""
|
|
624
|
-
Converts the names of the HK parameters in the given dictionary.
|
|
625
|
-
|
|
626
|
-
The names/keys in the given dictionary of HK parameters (original_hk) are replaced by the names
|
|
627
|
-
from the given conversion dictionary. The original dictionary is left unchanged, a new dictionary is
|
|
628
|
-
returned.
|
|
629
|
-
|
|
630
|
-
Args:
|
|
631
|
-
- original_hk: Original dictionary of HK parameters.
|
|
632
|
-
- conversion_dict: Dictionary with the original HK names as keys and the new HK names as values.
|
|
633
|
-
|
|
634
|
-
Returns:
|
|
635
|
-
A new dictionary of HK parameters with the corrected HK names.
|
|
636
|
-
"""
|
|
637
|
-
|
|
638
|
-
converted_hk = {}
|
|
639
|
-
|
|
640
|
-
for orig_key in original_hk:
|
|
641
|
-
|
|
642
|
-
try:
|
|
643
|
-
new_key = conversion_dict[orig_key]
|
|
644
|
-
except KeyError:
|
|
645
|
-
new_key = orig_key # no conversion, just copy the key:value pair
|
|
646
|
-
|
|
647
|
-
converted_hk[new_key] = original_hk[orig_key]
|
|
648
|
-
|
|
649
|
-
return converted_hk
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
def read_conversion_dict(storage_mnemonic: str, use_site: bool = False, setup: Optional[Setup] = None):
|
|
653
|
-
""" Read the HK spreadsheet and compose conversion dictionary for HK names.
|
|
654
|
-
|
|
655
|
-
The spreadsheet contains the following information:
|
|
656
|
-
|
|
657
|
-
- storage mnemonic of the component that generates the HK
|
|
658
|
-
- original HK name (as is comes from the device itself)
|
|
659
|
-
- HK name with the correct prefix
|
|
660
|
-
- name of the column (in the HK file) with the corresponding timestamp
|
|
661
|
-
|
|
662
|
-
Args:
|
|
663
|
-
- storage_mnemonic: Storage mnemonic of the component for which to compose the conversion dictionary
|
|
664
|
-
- use_site: Indicate whether or not the prefixes of the new HK names are TH-specific
|
|
665
|
-
- setup: Setup.
|
|
666
|
-
|
|
667
|
-
Returns: Dictionary with the original HK names as keys and the converted HK names as values.
|
|
668
|
-
"""
|
|
669
|
-
|
|
670
|
-
setup = setup or load_setup()
|
|
671
|
-
|
|
672
|
-
try:
|
|
673
|
-
hk_info_table = setup.telemetry.dictionary
|
|
674
|
-
except AttributeError:
|
|
675
|
-
raise SetupError("Version of the telemetry dictionary not specified in the current setup")
|
|
676
|
-
|
|
677
|
-
storage_mnemonic_col = hk_info_table[TmDictionaryColumns.STORAGE_MNEMONIC].values
|
|
678
|
-
correct_name_col = hk_info_table[TmDictionaryColumns.CORRECT_HK_NAMES].values
|
|
679
|
-
original_name_col = hk_info_table[TmDictionaryColumns.ORIGINAL_EGSE_HK_NAMES].values
|
|
680
|
-
|
|
681
|
-
selection = np.where(storage_mnemonic_col == storage_mnemonic)
|
|
682
|
-
|
|
683
|
-
correct_name_col = correct_name_col[selection]
|
|
684
|
-
original_name_col = original_name_col[selection]
|
|
685
|
-
|
|
686
|
-
if use_site:
|
|
687
|
-
|
|
688
|
-
th_prefix = f"G{SITE_ID}_"
|
|
689
|
-
|
|
690
|
-
th_conversion_dict = {}
|
|
691
|
-
|
|
692
|
-
for (original_name, correct_name) in zip(original_name_col, correct_name_col):
|
|
693
|
-
if str.startswith(str(correct_name), th_prefix):
|
|
694
|
-
th_conversion_dict[original_name] = correct_name
|
|
695
|
-
|
|
696
|
-
return th_conversion_dict
|
|
697
|
-
|
|
698
|
-
else:
|
|
699
|
-
|
|
700
|
-
return dict(zip(original_name_col, correct_name_col))
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
def get_hk_info(hk_name: str, setup: Optional[Setup] = None):
|
|
704
|
-
""" Read the HK spreadsheet and extract information for the given HK parameter.
|
|
705
|
-
|
|
706
|
-
The spreadsheet contains the following information:
|
|
707
|
-
|
|
708
|
-
- storage mnemonic of the component that generates the HK
|
|
709
|
-
- original HK name
|
|
710
|
-
- HK name with the correct prefix
|
|
711
|
-
- name of the column (in the HK file) with the corresponding timestamp
|
|
712
|
-
|
|
713
|
-
Args:
|
|
714
|
-
- hk_name: Name of the HK parameter.
|
|
715
|
-
- setup: Setup.
|
|
716
|
-
|
|
717
|
-
Returns:
|
|
718
|
-
- storage mnemonic of the component that generates the given HK parameter
|
|
719
|
-
- name of the column in the HK file with the corresponding timestamp
|
|
720
|
-
"""
|
|
721
|
-
|
|
722
|
-
setup = setup or load_setup()
|
|
723
|
-
hk_info_table = setup.telemetry.dictionary
|
|
724
|
-
|
|
725
|
-
storage_mnemonic = hk_info_table[TmDictionaryColumns.STORAGE_MNEMONIC].values
|
|
726
|
-
hk_names = hk_info_table[TmDictionaryColumns.CORRECT_HK_NAMES].values
|
|
727
|
-
timestamp_col = hk_info_table[TmDictionaryColumns.TIMESTAMP_NAMES].values
|
|
728
|
-
|
|
729
|
-
selection = np.where(hk_names == hk_name)
|
|
730
|
-
|
|
731
|
-
try:
|
|
732
|
-
return storage_mnemonic[selection][0], timestamp_col[selection][0]
|
|
733
|
-
except IndexError:
|
|
734
|
-
raise HKError(f"HK parameter {hk_name} unknown")
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
def get_storage_mnemonics(setup: Setup = None):
|
|
738
|
-
""" Return the list of the storage mnemonics from the TM dictionary.
|
|
739
|
-
|
|
740
|
-
Args:
|
|
741
|
-
- setup: Setup.
|
|
742
|
-
|
|
743
|
-
Returns: List of the storage mnemonics from the TM dictionary.
|
|
744
|
-
"""
|
|
745
|
-
|
|
746
|
-
setup = setup or load_setup()
|
|
747
|
-
|
|
748
|
-
hk_info_table = setup.telemetry.dictionary
|
|
749
|
-
storage_mnemonics = hk_info_table[TmDictionaryColumns.STORAGE_MNEMONIC].values
|
|
750
|
-
|
|
751
|
-
return np.unique(storage_mnemonics)
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
def get_housekeeping_names(name_filter=None, device_filter=None, setup: Setup = None):
|
|
755
|
-
""" Return HK names, storage mnemonic, and description.
|
|
756
|
-
|
|
757
|
-
The TM dictionary is read into a Pandas DataFrame. If a device filter is given, only the rows pertaining to the
|
|
758
|
-
given storage mnemonic are kept. If a name filter is given, only the rows for which the HK parameter name contains
|
|
759
|
-
the given name filter are kept.
|
|
760
|
-
|
|
761
|
-
The result is returned as a Pandas DataFrame with the following columns:
|
|
762
|
-
- "CAM EGSE mnemonic": Name of the HK parameter;
|
|
763
|
-
- "Storage mnemonic": Storage mnemonic of the device producing the HK;
|
|
764
|
-
- "Description": Description of the HK parameter.
|
|
765
|
-
|
|
766
|
-
Synopsis:
|
|
767
|
-
- get_housekeeping_names(name_filter="RAW", device_filter="N-FEE-HK")
|
|
768
|
-
- get_housekeeping_names(name_filter="RAW", device_filter="N-FEE-HK", setup=setup)
|
|
769
|
-
|
|
770
|
-
Args:
|
|
771
|
-
- name_filter: Filter the HK dataframe, based on (a part of) the name of the HK parameter(s)
|
|
772
|
-
- device: Filter the HK dataframe, based on the given storage mmenmonic
|
|
773
|
-
- setup: Setup.
|
|
774
|
-
|
|
775
|
-
Returns: Pandas DataFrame with the HK name, storage mnemonic, and description of the HK parameters that pass the
|
|
776
|
-
given filter.
|
|
777
|
-
"""
|
|
778
|
-
|
|
779
|
-
setup = setup or load_setup()
|
|
780
|
-
|
|
781
|
-
hk_info_table = setup.telemetry.dictionary
|
|
782
|
-
hk_info_table.dropna(subset=[TmDictionaryColumns.CORRECT_HK_NAMES], inplace=True)
|
|
783
|
-
|
|
784
|
-
if device_filter:
|
|
785
|
-
hk_info_table = hk_info_table.loc[hk_info_table[TmDictionaryColumns.STORAGE_MNEMONIC] == device_filter]
|
|
786
|
-
|
|
787
|
-
if name_filter:
|
|
788
|
-
hk_info_table = hk_info_table.query(f'`{TmDictionaryColumns.CORRECT_HK_NAMES}`.str.contains("{name_filter}")')
|
|
789
|
-
|
|
790
|
-
return hk_info_table[[TmDictionaryColumns.CORRECT_HK_NAMES, TmDictionaryColumns.STORAGE_MNEMONIC,
|
|
791
|
-
TmDictionaryColumns.DESCRIPTION]]
|