From 7ec9b9ea62a9c42777f0bb838dfec0554987c0de Mon Sep 17 00:00:00 2001 From: elanaku Date: Mon, 11 Nov 2024 12:52:28 -0300 Subject: [PATCH 01/10] Add CBP setup to MTCalSys --- .../observatory/control/maintel/mtcalsys.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/python/lsst/ts/observatory/control/maintel/mtcalsys.py b/python/lsst/ts/observatory/control/maintel/mtcalsys.py index 1046eaf1..5366ead9 100644 --- a/python/lsst/ts/observatory/control/maintel/mtcalsys.py +++ b/python/lsst/ts/observatory/control/maintel/mtcalsys.py @@ -136,6 +136,7 @@ def __init__( self.linearstage_led_focus_index = 2 self.linearstage_laser_focus_index = 3 self.linearstage_select_index = 4 + self.cbp_index = 1 super().__init__( components=[ @@ -148,6 +149,7 @@ def __init__( f"LinearStage:{self.linearstage_led_focus_index}", f"LinearStage:{self.linearstage_laser_focus_index}", f"LinearStage:{self.linearstage_select_index}", + f"CBP:{self.cbp_index}", ], domain=domain, log=log, @@ -339,6 +341,47 @@ async def setup_laser( await self.change_laser_optical_configuration(optical_configuration) await self.change_laser_wavelength(wavelength, use_projector) + async def setup_cbp( + self, + azimuth: float, + elevation: float, + mask: typing.Optional[int] = None, + focus: typing.Optional[float] = None, + rotation: typing.Optional[int] = None, + ) -> None: + """Perform all steps for preparing the CBP for measurements. + + Parameters + ---------- + az : `float` + Azimuth of CBP in degrees + el : `float` + Elevation of CBP in degrees + mask : `int` + Mask number to use + focus: `float` + Focus position in um + rot: `int` + Rotator position of mask in degrees + Default 0 + use_projector : `bool` + identifies if you are using the projector while + changing the wavelength + Default True + """ + timeout = 60 + await self.rem.cbp.cmd_move.set_start( + azimuth=azimuth, elevation=elevation, timeout=timeout + ) + if focus is not None: + await self.rem.cbp.cmd_setFocus.set_start(focus=focus, timeout=timeout) + if mask is not None: + await self.rem.cmd_changeMask.set_start(mask=mask, timeout=timeout) + if rotation is not None: + await self.rem.cmd_changeMaskRotation.set_start( + mask_rotation=rotation, timeout=timeout + ) + async def get_laser_parameters(self) -> tuple: """Get laser configuration From eca9df5fff79a36c63764873e5d07568d9139cbe Mon Sep 17 00:00:00 2001 From: elanaku Date: Mon, 11 Nov 2024 13:45:39 -0300 Subject: [PATCH 02/10] Add CBPCalibration and CBP calibration types --- .../observatory/control/maintel/mtcalsys.py | 30 +++++++++++++++++++ .../ts/observatory/control/utils/enums.py | 2 ++ 2 files changed, 32 insertions(+) diff --git a/python/lsst/ts/observatory/control/maintel/mtcalsys.py b/python/lsst/ts/observatory/control/maintel/mtcalsys.py index 5366ead9..21b22acf 100644 --- a/python/lsst/ts/observatory/control/maintel/mtcalsys.py +++ b/python/lsst/ts/observatory/control/maintel/mtcalsys.py @@ -130,6 +130,8 @@ def __init__( ) -> None: self.electrometer_projector_index = 103 + self.electrometer_cbp_index = 101 + self.electrometer_cbpcal_index = 102 self.fiberspectrograph_blue_index = 1 self.fiberspectrograph_red_index = 2 self.linearstage_led_select_index = 1 @@ -145,6 +147,8 @@ def __init__( f"FiberSpectrograph:{self.fiberspectrograph_blue_index}", f"FiberSpectrograph:{self.fiberspectrograph_red_index}", f"Electrometer:{self.electrometer_projector_index}", + f"Electrometer:{self.electrometer_cbp_index}", + f"Electrometer:{self.electrometer_cbpcal_index}", f"LinearStage:{self.linearstage_led_select_index}", f"LinearStage:{self.linearstage_led_focus_index}", f"LinearStage:{self.linearstage_laser_focus_index}", @@ -202,6 +206,32 @@ async def setup_calsys(self, sequence_name: str) -> None: await self.linearstage_projector_select.cmd_moveAbsolute.set_start( distance=self.ls_select_led_location, timeout=self.long_timeout ) + elif calibration_type == CalibrationType.CBPCalibration: + await self.setup_cbp( + config_data["cbp_azimuth"], + config_data["cbp_elevation"], + config_data["cbp_mask"], + config_data["cbp_focus"], + config_data["cbp_rotation"], + ) + await self.setup_electrometers( + mode=str(config_data["electrometer_mode"]), + range=float(config_data["electrometer_range"]), + integration_time=float(config_data["electrometer_integration_time"]), + ) + elif calibration_type == CalibrationType.CBP: + await self.setup_cbp( + config_data["cbp_azimuth"], + config_data["cbp_elevation"], + config_data["cbp_mask"], + config_data["cbp_focus"], + config_data["cbp_rotation"], + ) + await self.setup_electrometers( + mode=str(config_data["electrometer_mode"]), + range=float(config_data["electrometer_range"]), + integration_time=float(config_data["electrometer_integration_time"]), + ) else: await self.linearstage_led_select.cmd_moveAbsolute.set_start( distance=self.led_rest_position, timeout=self.long_timeout diff --git a/python/lsst/ts/observatory/control/utils/enums.py b/python/lsst/ts/observatory/control/utils/enums.py index d9f00d94..7172debc 100644 --- a/python/lsst/ts/observatory/control/utils/enums.py +++ b/python/lsst/ts/observatory/control/utils/enums.py @@ -158,6 +158,8 @@ class CalibrationType(enum.IntEnum): WhiteLight = 1 Mono = 2 + CBP = 3 + CBPCalibration = 4 # TODO: (DM-46168) Revert workaround for TunableLaser XML changes From b8249d45b94293a5d6b2ed2024c9603b0b901222 Mon Sep 17 00:00:00 2001 From: elanaku Date: Mon, 11 Nov 2024 18:29:01 -0300 Subject: [PATCH 03/10] Add setup_electrometers --- .../observatory/control/maintel/mtcalsys.py | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/python/lsst/ts/observatory/control/maintel/mtcalsys.py b/python/lsst/ts/observatory/control/maintel/mtcalsys.py index 21b22acf..c9fb037f 100644 --- a/python/lsst/ts/observatory/control/maintel/mtcalsys.py +++ b/python/lsst/ts/observatory/control/maintel/mtcalsys.py @@ -147,8 +147,8 @@ def __init__( f"FiberSpectrograph:{self.fiberspectrograph_blue_index}", f"FiberSpectrograph:{self.fiberspectrograph_red_index}", f"Electrometer:{self.electrometer_projector_index}", - f"Electrometer:{self.electrometer_cbp_index}", - f"Electrometer:{self.electrometer_cbpcal_index}", + f"ElectrometerCBP:{self.electrometer_cbp_index}", + f"ElectrometerCBPCal:{self.electrometer_cbpcal_index}", f"LinearStage:{self.linearstage_led_select_index}", f"LinearStage:{self.linearstage_led_focus_index}", f"LinearStage:{self.linearstage_laser_focus_index}", @@ -206,7 +206,9 @@ async def setup_calsys(self, sequence_name: str) -> None: await self.linearstage_projector_select.cmd_moveAbsolute.set_start( distance=self.ls_select_led_location, timeout=self.long_timeout ) - elif calibration_type == CalibrationType.CBPCalibration: + elif (calibration_type == CalibrationType.CBPCalibration) or ( + calibration_type == CalibrationType.CBP + ): await self.setup_cbp( config_data["cbp_azimuth"], config_data["cbp_elevation"], @@ -219,19 +221,12 @@ async def setup_calsys(self, sequence_name: str) -> None: range=float(config_data["electrometer_range"]), integration_time=float(config_data["electrometer_integration_time"]), ) - elif calibration_type == CalibrationType.CBP: - await self.setup_cbp( - config_data["cbp_azimuth"], - config_data["cbp_elevation"], - config_data["cbp_mask"], - config_data["cbp_focus"], - config_data["cbp_rotation"], - ) - await self.setup_electrometers( - mode=str(config_data["electrometer_mode"]), - range=float(config_data["electrometer_range"]), - integration_time=float(config_data["electrometer_integration_time"]), + await self.setup_laser( + config_data["laser_mode"], + config_data["wavelength"], + config_data["optical_configuration"], ) + await self.laser_start_propagate() else: await self.linearstage_led_select.cmd_moveAbsolute.set_start( distance=self.led_rest_position, timeout=self.long_timeout @@ -927,6 +922,14 @@ async def take_fiber_spectrum( def electrometer(self) -> salobj.Remote: return getattr(self.rem, f"electrometer_{self.electrometer_projector_index}") + @property + def electrometerCBP(self) -> salobj.Remote: + return getattr(self.rem, f"electrometer_{self.electrometer_cbp_index}") + + @property + def electrometerCBPCal(self) -> salobj.Remote: + return getattr(self.rem, f"electrometer_{self.electrometer_cbpcal_index}") + @property def fiberspectrograph_red(self) -> salobj.Remote: return getattr( From 6a17b0cb36da754796ae7d79d40db10e89b055a5 Mon Sep 17 00:00:00 2001 From: elanaku Date: Mon, 11 Nov 2024 18:41:53 -0300 Subject: [PATCH 04/10] Editing yaml file --- .../ts/observatory/control/data/mtcalsys.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/python/lsst/ts/observatory/control/data/mtcalsys.yaml b/python/lsst/ts/observatory/control/data/mtcalsys.yaml index 41c5a16a..3e1df4c5 100644 --- a/python/lsst/ts/observatory/control/data/mtcalsys.yaml +++ b/python/lsst/ts/observatory/control/data/mtcalsys.yaml @@ -87,3 +87,20 @@ laser_functional: use_fiberspectrograph_blue: false exposure_times: - 15.0 + +cbp_calibration: + calib_type: CBPCalibration + use_camera: false + wavelength: 700 + wavelength_width: 800 + wavelength_resolution: 50 + use_cbpelectrometer: true + use_cbpcalelectrometer: true + use_fiberspectrograph_red: false + use_fiberspectrograph_blue: false + electrometer_integration_time: 0.001 + electrometer_mode: CHARGE + electrometer_range: 2e-6 + laser_mode: BURST + optical_configuration: F1_SCU + exposure_times: 30 From 56f6da2c0bdb05f9fac7cfc1f4a3978d2f3df3e3 Mon Sep 17 00:00:00 2001 From: elanaku Date: Mon, 11 Nov 2024 19:29:56 -0300 Subject: [PATCH 05/10] Add news fragment --- doc/news/DM-47497.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/news/DM-47497.feature.rst diff --git a/doc/news/DM-47497.feature.rst b/doc/news/DM-47497.feature.rst new file mode 100644 index 00000000..e7d9773a --- /dev/null +++ b/doc/news/DM-47497.feature.rst @@ -0,0 +1 @@ +Add CBP to MTCalsys. \ No newline at end of file From 2d78c13f1da55a9b494688cb270a70a8531ec718 Mon Sep 17 00:00:00 2001 From: elanaku Date: Mon, 11 Nov 2024 20:22:34 -0300 Subject: [PATCH 06/10] Change schema and parameters --- .../ts/observatory/control/data/mtcalsys.yaml | 9 ++- .../control/data/mtcalsys_schema.yaml | 42 +++++++++++- .../observatory/control/maintel/mtcalsys.py | 65 ++++++++----------- .../ts/observatory/control/utils/enums.py | 2 - 4 files changed, 73 insertions(+), 45 deletions(-) diff --git a/python/lsst/ts/observatory/control/data/mtcalsys.yaml b/python/lsst/ts/observatory/control/data/mtcalsys.yaml index 3e1df4c5..ad98599e 100644 --- a/python/lsst/ts/observatory/control/data/mtcalsys.yaml +++ b/python/lsst/ts/observatory/control/data/mtcalsys.yaml @@ -82,18 +82,20 @@ laser_functional: use_camera: false optical_configuration: SCU wavelength: 500.0 - use_electrometer: false + use_flatfieldelectrometer: false use_fiberspectrograph_red: false use_fiberspectrograph_blue: false exposure_times: - 15.0 cbp_calibration: - calib_type: CBPCalibration + calib_type: Mono + use_cbp: true use_camera: false wavelength: 700 wavelength_width: 800 wavelength_resolution: 50 + use_flatfieldelectrometer: false use_cbpelectrometer: true use_cbpcalelectrometer: true use_fiberspectrograph_red: false @@ -103,4 +105,5 @@ cbp_calibration: electrometer_range: 2e-6 laser_mode: BURST optical_configuration: F1_SCU - exposure_times: 30 + exposure_times: + - 30.0 diff --git a/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml b/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml index 36d6da18..d1e8193e 100644 --- a/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml +++ b/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml @@ -66,10 +66,22 @@ properties: focus the laser light from the fiber. type: number default: 15.380 - use_electrometer: - description: Identifies if the electrometer will be used in the exposure. + use_cbp: + description: Identifies if the CBP will be used. + type: boolean + default: false + use_flatfieldelectrometer: + description: Identifies if the flatfield electrometer will be used in the exposure. type: boolean default: true + use_cbpelectrometer: + description: Identifies if the cbp electrometer will be used in the exposure. + type: boolean + default: false + use_cbpcalelectrometer: + description: Identifies if the cbpcal electrometer will be used in the exposure. + type: boolean + default: false use_fiberspectrograph_red: description: >- Identifies if the fiberspectrograph for red color will be used in the @@ -138,11 +150,35 @@ properties: - F2_SCU - F2_NO_SCU - F1_NO_SCU + cbp_elevation: + description: CBP elevation in degrees. + type: number + default: 0 + cbp_azimuth: + description: CBP azimuth in degrees. + type: number + default: 0 + cbp_mask: + description: CBP azimuth in degrees. + type: integer + default: 3 + minimum: 1 + maximum: 5 + cbp_rotation: + description: CBP mask rotator angle in degrees. + type: number + default: 0 + cbp_focus: + description: CBP focus position in um. + type: number + default: 6000 + minimum: 0 + maximum: 13000 required: - calib_type - wavelength - use_camera -- use_electrometer +- use_flatfieldelectrometer - use_fiberspectrograph_red - use_fiberspectrograph_blue - exposure_times diff --git a/python/lsst/ts/observatory/control/maintel/mtcalsys.py b/python/lsst/ts/observatory/control/maintel/mtcalsys.py index c9fb037f..68b26081 100644 --- a/python/lsst/ts/observatory/control/maintel/mtcalsys.py +++ b/python/lsst/ts/observatory/control/maintel/mtcalsys.py @@ -206,34 +206,29 @@ async def setup_calsys(self, sequence_name: str) -> None: await self.linearstage_projector_select.cmd_moveAbsolute.set_start( distance=self.ls_select_led_location, timeout=self.long_timeout ) - elif (calibration_type == CalibrationType.CBPCalibration) or ( - calibration_type == CalibrationType.CBP - ): - await self.setup_cbp( - config_data["cbp_azimuth"], - config_data["cbp_elevation"], - config_data["cbp_mask"], - config_data["cbp_focus"], - config_data["cbp_rotation"], - ) - await self.setup_electrometers( - mode=str(config_data["electrometer_mode"]), - range=float(config_data["electrometer_range"]), - integration_time=float(config_data["electrometer_integration_time"]), - ) - await self.setup_laser( - config_data["laser_mode"], - config_data["wavelength"], - config_data["optical_configuration"], - ) - await self.laser_start_propagate() else: - await self.linearstage_led_select.cmd_moveAbsolute.set_start( - distance=self.led_rest_position, timeout=self.long_timeout - ) - await self.linearstage_projector_select.cmd_moveAbsolute.set_start( - distance=self.ls_select_laser_location, timeout=self.long_timeout - ) + if config_data["use_cbp"]: + await self.setup_cbp( + config_data["cbp_azimuth"], + config_data["cbp_elevation"], + config_data["cbp_mask"], + config_data["cbp_focus"], + config_data["cbp_rotation"], + ) + await self.setup_electrometers( + mode=str(config_data["electrometer_mode"]), + range=float(config_data["electrometer_range"]), + integration_time=float( + config_data["electrometer_integration_time"] + ), + ) + else: + await self.linearstage_led_select.cmd_moveAbsolute.set_start( + distance=self.led_rest_position, timeout=self.long_timeout + ) + await self.linearstage_projector_select.cmd_moveAbsolute.set_start( + distance=self.ls_select_laser_location, timeout=self.long_timeout + ) await self.setup_laser( config_data["laser_mode"], config_data["wavelength"], @@ -370,9 +365,9 @@ async def setup_cbp( self, azimuth: float, elevation: float, - mask: typing.Optional[int] = None, - focus: typing.Optional[float] = None, - rotation: typing.Optional[int] = None, + mask: int, + focus: float, + rotation: float, ) -> None: """Perform all steps for preparing the CBP for measurements. @@ -389,10 +384,6 @@ async def setup_cbp( rot: `int` Rotator position of mask in degrees Default 0 - use_projector : `bool` - identifies if you are using the projector while - changing the wavelength - Default True """ timeout = 60 await self.rem.cbp.cmd_move.set_start( @@ -646,7 +637,7 @@ async def calculate_optimized_exposure_times( electrometer_integration_time=config_data[ "electrometer_integration_time" ], - use_electrometer=config_data["use_electrometer"], + use_electrometer=config_data["use_flatfieldelectrometer"], ) fiberspectrograph_exptimes_red = ( await self._calculate_fiberspectrograph_exposure_times( @@ -923,11 +914,11 @@ def electrometer(self) -> salobj.Remote: return getattr(self.rem, f"electrometer_{self.electrometer_projector_index}") @property - def electrometerCBP(self) -> salobj.Remote: + def electrometer_cbp(self) -> salobj.Remote: return getattr(self.rem, f"electrometer_{self.electrometer_cbp_index}") @property - def electrometerCBPCal(self) -> salobj.Remote: + def electrometer_cbp_cal(self) -> salobj.Remote: return getattr(self.rem, f"electrometer_{self.electrometer_cbpcal_index}") @property diff --git a/python/lsst/ts/observatory/control/utils/enums.py b/python/lsst/ts/observatory/control/utils/enums.py index 7172debc..d9f00d94 100644 --- a/python/lsst/ts/observatory/control/utils/enums.py +++ b/python/lsst/ts/observatory/control/utils/enums.py @@ -158,8 +158,6 @@ class CalibrationType(enum.IntEnum): WhiteLight = 1 Mono = 2 - CBP = 3 - CBPCalibration = 4 # TODO: (DM-46168) Revert workaround for TunableLaser XML changes From adf36dd79d4b19f891ccaa04edc0a9496efbd3ee Mon Sep 17 00:00:00 2001 From: elanaku Date: Mon, 11 Nov 2024 22:00:45 -0300 Subject: [PATCH 07/10] Add options for multiple electrometers --- .../observatory/control/maintel/mtcalsys.py | 101 +++++++++++++----- 1 file changed, 76 insertions(+), 25 deletions(-) diff --git a/python/lsst/ts/observatory/control/maintel/mtcalsys.py b/python/lsst/ts/observatory/control/maintel/mtcalsys.py index 68b26081..463fb483 100644 --- a/python/lsst/ts/observatory/control/maintel/mtcalsys.py +++ b/python/lsst/ts/observatory/control/maintel/mtcalsys.py @@ -147,8 +147,8 @@ def __init__( f"FiberSpectrograph:{self.fiberspectrograph_blue_index}", f"FiberSpectrograph:{self.fiberspectrograph_red_index}", f"Electrometer:{self.electrometer_projector_index}", - f"ElectrometerCBP:{self.electrometer_cbp_index}", - f"ElectrometerCBPCal:{self.electrometer_cbpcal_index}", + f"Electrometer:{self.electrometer_cbp_index}", + f"Electrometer:{self.electrometer_cbpcal_index}", f"LinearStage:{self.linearstage_led_select_index}", f"LinearStage:{self.linearstage_led_focus_index}", f"LinearStage:{self.linearstage_laser_focus_index}", @@ -568,6 +568,14 @@ async def run_calibration_sequence( wavelengths=calibration_wavelengths, config_data=config_data ) + electrometers_to_scan = [] + if config_data["use_cbpelectrometer"]: + electrometers_to_scan.append(self.electrometer_cbp) + if config_data["use_cbpcalelectrometer"]: + electrometers_to_scan.append(self.electrometer_cbp_cal) + if config_data["use_flatfieldelectrometer"]: + electrometers_to_scan.append(self.electrometer_flatfield) + for exposure in exposure_table: self.log.debug( f"Performing {calibration_type.name} calibration with {exposure.wavelength=}." @@ -584,6 +592,7 @@ async def run_calibration_sequence( fiber_spectrum_red_exposure_time=exposure.fiberspectrograph_red, fiber_spectrum_blue_exposure_time=exposure.fiberspectrograph_blue, electrometer_exposure_time=exposure.electrometer, + electrometers_to_scan=electrometers_to_scan, ) mtcamera_exposure_info.update(exposure_info) @@ -599,6 +608,7 @@ async def run_calibration_sequence( fiber_spectrum_red_exposure_time=exposure.fiberspectrograph_red, fiber_spectrum_blue_exposure_time=exposure.fiberspectrograph_blue, electrometer_exposure_time=exposure.electrometer, + electrometers_to_scan=electrometers_to_scan, ) mtcamera_exposure_info.update(exposure_info) @@ -745,6 +755,7 @@ async def _take_data( mtcamera_exptime: float, mtcamera_filter: str, exposure_metadata: dict, + electrometers_to_scan: list, fiber_spectrum_red_exposure_time: float | None, fiber_spectrum_blue_exposure_time: float | None, electrometer_exposure_time: float | None, @@ -770,10 +781,24 @@ async def _take_data( exposure_time=fiber_spectrum_blue_exposure_time, exposures_done=exposures_done, ) - electrometer_exposure_coroutine = self.take_electrometer_scan( - exposure_time=electrometer_exposure_time, - exposures_done=exposures_done, - ) + if (len(electrometers_to_scan) == 0) or (len(electrometers_to_scan) == 1): + electrometer_exposure_coroutine = self.take_electrometer_scan( + exposure_time=electrometer_exposure_time, + exposures_done=exposures_done, + electrometer_to_scan=electrometers_to_scan, + ) + else: + electrometer_exposure_coroutine_1 = self.take_electrometer_scan( + exposure_time=electrometer_exposure_time, + exposures_done=exposures_done, + electrometer_to_scan=electrometers_to_scan[0], + ) + electrometer_exposure_coroutine_2 = self.take_electrometer_scan( + exposure_time=electrometer_exposure_time, + exposures_done=exposures_done, + electrometer_to_scan=electrometers_to_scan[1], + ) + try: fiber_spectrum_red_exposure_task = asyncio.create_task( fiber_spectrum_red_exposure_coroutine @@ -781,23 +806,44 @@ async def _take_data( fiber_spectrum_blue_exposure_task = asyncio.create_task( fiber_spectrum_blue_exposure_coroutine ) - electrometer_exposure_task = asyncio.create_task( - electrometer_exposure_coroutine - ) + if (len(electrometers_to_scan) == 0) or (len(electrometers_to_scan) == 0): + electrometer_exposure_task = asyncio.create_task( + electrometer_exposure_coroutine + ) + else: + electrometer_exposure_task_1 = asyncio.create_task( + electrometer_exposure_coroutine_1 + ) + electrometer_exposure_task_2 = asyncio.create_task( + electrometer_exposure_coroutine_2 + ) mtcamera_exposure_id = await mtcamera_exposure_task finally: - exposures_done.set_result(True) - ( - fiber_spectrum_red_exposure_result, - fiber_spectrum_blue_exposure_result, - electrometer_exposure_result, - ) = await asyncio.gather( - fiber_spectrum_red_exposure_task, - fiber_spectrum_blue_exposure_task, - electrometer_exposure_task, - ) - + if (len(electrometers_to_scan) == 0) or (len(electrometers_to_scan) == 0): + exposures_done.set_result(True) + ( + fiber_spectrum_red_exposure_result, + fiber_spectrum_blue_exposure_result, + electrometer_exposure_result, + ) = await asyncio.gather( + fiber_spectrum_red_exposure_task, + fiber_spectrum_blue_exposure_task, + electrometer_exposure_task, + ) + else: + exposures_done.set_result(True) + ( + fiber_spectrum_red_exposure_result, + fiber_spectrum_blue_exposure_result, + electrometer_exposure_result_1, + electrometer_exposure_result_2, + ) = await asyncio.gather( + fiber_spectrum_red_exposure_task, + fiber_spectrum_blue_exposure_task, + electrometer_exposure_task_1, + electrometer_exposure_task_2, + ) return { mtcamera_exposure_id[0]: dict( fiber_spectrum_red_exposure_result=fiber_spectrum_red_exposure_result, @@ -810,6 +856,7 @@ async def take_electrometer_scan( self, exposure_time: float | None, exposures_done: asyncio.Future, + electrometer_to_scan: salobj, ) -> list[str]: """Perform an electrometer scan for the specified duration. @@ -819,6 +866,8 @@ async def take_electrometer_scan( Exposure time for the fiber spectrum (seconds). exposures_done : `asyncio.Future` A future indicating when the camera exposures where complete. + electrometer_to_scan : `salobj` + The electrometer that performs the scan. Returns ------- @@ -826,14 +875,14 @@ async def take_electrometer_scan( List of large file urls. """ - self.electrometer.evt_largeFileObjectAvailable.flush() + electrometer_to_scan.evt_largeFileObjectAvailable.flush() electrometer_exposures = list() if exposure_time is not None: try: - await self.electrometer.cmd_startScanDt.set_start( + await electrometer_to_scan.cmd_startScanDt.set_start( scanDuration=exposure_time, timeout=exposure_time + self.long_timeout, ) @@ -842,7 +891,7 @@ async def take_electrometer_scan( # Make sure that a new lfo was created try: - lfo = await self.electrometer.evt_largeFileObjectAvailable.next( + lfo = await electrometer_to_scan.evt_largeFileObjectAvailable.next( timeout=self.long_timeout, flush=False ) electrometer_exposures.append(lfo.url) @@ -853,7 +902,9 @@ async def take_electrometer_scan( "Time out waiting for electrometer data. Making sure electrometer " "is in enabled state and continuing." ) - await salobj.set_summary_state(self.electrometer, salobj.State.ENABLED) + await salobj.set_summary_state( + electrometer_to_scan, salobj.State.ENABLED + ) return electrometer_exposures async def take_fiber_spectrum( @@ -910,7 +961,7 @@ async def take_fiber_spectrum( return fiber_spectrum_exposures @property - def electrometer(self) -> salobj.Remote: + def electrometer_flatfield(self) -> salobj.Remote: return getattr(self.rem, f"electrometer_{self.electrometer_projector_index}") @property From c933b5e83f67ae87142bc2ba8165e8e74cd2a23e Mon Sep 17 00:00:00 2001 From: elanaku Date: Tue, 12 Nov 2024 10:21:34 -0300 Subject: [PATCH 08/10] Fix schema --- .../lsst/ts/observatory/control/data/mtcalsys_schema.yaml | 2 +- tests/maintel/test_mtcalsys.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml b/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml index d1e8193e..1408c910 100644 --- a/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml +++ b/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml @@ -132,7 +132,7 @@ properties: -1 for automatic range. Volts range from 0 to 210 Volts, Current range from 0 to 21e-3 Amps, Resistance from 0 to 100e18 Ohms, Charge from 0 to +2.1e-6 Coulombs. - type: number + type: float default: -1 exposure_times: description: List of Camera exposure times, in secs. diff --git a/tests/maintel/test_mtcalsys.py b/tests/maintel/test_mtcalsys.py index fdabcd87..7b0d066e 100644 --- a/tests/maintel/test_mtcalsys.py +++ b/tests/maintel/test_mtcalsys.py @@ -77,6 +77,8 @@ def setUpClass(cls) -> None: cls.image_index = index_generator() cls.electrometer_projector_index = index_generator() + cls.electrometer_cbp_index = index_generator() + cls.electrometer_cbpcal_index = index_generator() cls.fiberspectrograph_blue_index = index_generator() cls.fiberspectrograph_red_index = index_generator() cls.linearstage_led_select_index = index_generator() @@ -99,10 +101,10 @@ async def test_setup_electrometers(self) -> None: integration_time=float(config_data["electrometer_integration_time"]), ) - self.mtcalsys.electrometer.cmd_performZeroCalib.start.assert_awaited_with( + self.mtcalsys.electrometer_flatfield.cmd_performZeroCalib.start.assert_awaited_with( timeout=self.mtcalsys.long_timeout ) - self.mtcalsys.electrometer.cmd_setDigitalFilter.set_start.assert_awaited_with( + self.mtcalsys.electrometer_flatfield.cmd_setDigitalFilter.set_start.assert_awaited_with( activateFilter=False, activateAvgFilter=False, activateMedFilter=False, From a3aa397192b6070365c04a38c118af7802fd47d0 Mon Sep 17 00:00:00 2001 From: elanaku Date: Tue, 12 Nov 2024 11:10:41 -0300 Subject: [PATCH 09/10] Fixed bugs --- .../ts/observatory/control/data/mtcalsys.yaml | 4 ++-- .../control/data/mtcalsys_schema.yaml | 2 +- .../ts/observatory/control/maintel/mtcalsys.py | 17 ++++++++++++++--- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/python/lsst/ts/observatory/control/data/mtcalsys.yaml b/python/lsst/ts/observatory/control/data/mtcalsys.yaml index ad98599e..950ca99d 100644 --- a/python/lsst/ts/observatory/control/data/mtcalsys.yaml +++ b/python/lsst/ts/observatory/control/data/mtcalsys.yaml @@ -102,8 +102,8 @@ cbp_calibration: use_fiberspectrograph_blue: false electrometer_integration_time: 0.001 electrometer_mode: CHARGE - electrometer_range: 2e-6 - laser_mode: BURST + electrometer_range: 0.000002 + laser_mode: 2 optical_configuration: F1_SCU exposure_times: - 30.0 diff --git a/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml b/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml index 1408c910..d1e8193e 100644 --- a/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml +++ b/python/lsst/ts/observatory/control/data/mtcalsys_schema.yaml @@ -132,7 +132,7 @@ properties: -1 for automatic range. Volts range from 0 to 210 Volts, Current range from 0 to 21e-3 Amps, Resistance from 0 to 100e18 Ohms, Charge from 0 to +2.1e-6 Coulombs. - type: float + type: number default: -1 exposure_times: description: List of Camera exposure times, in secs. diff --git a/python/lsst/ts/observatory/control/maintel/mtcalsys.py b/python/lsst/ts/observatory/control/maintel/mtcalsys.py index 463fb483..41162f2b 100644 --- a/python/lsst/ts/observatory/control/maintel/mtcalsys.py +++ b/python/lsst/ts/observatory/control/maintel/mtcalsys.py @@ -785,7 +785,7 @@ async def _take_data( electrometer_exposure_coroutine = self.take_electrometer_scan( exposure_time=electrometer_exposure_time, exposures_done=exposures_done, - electrometer_to_scan=electrometers_to_scan, + electrometer_to_scan=electrometers_to_scan[0], ) else: electrometer_exposure_coroutine_1 = self.take_electrometer_scan( @@ -806,10 +806,20 @@ async def _take_data( fiber_spectrum_blue_exposure_task = asyncio.create_task( fiber_spectrum_blue_exposure_coroutine ) - if (len(electrometers_to_scan) == 0) or (len(electrometers_to_scan) == 0): + self.log.debug(f"Electrometers to scan are {electrometers_to_scan}") + self.log.debug( + f"number electrometers to scan are {len(electrometers_to_scan)}" + ) + if len(electrometers_to_scan) == 0: + electrometer_exposure_task = asyncio.create_task( + electrometer_exposure_coroutine + ) + self.log.debug("Number of electrometers is 0") + elif len(electrometers_to_scan) == 1: electrometer_exposure_task = asyncio.create_task( electrometer_exposure_coroutine ) + self.log.debug("Number of electrometers is 1") else: electrometer_exposure_task_1 = asyncio.create_task( electrometer_exposure_coroutine_1 @@ -817,10 +827,11 @@ async def _take_data( electrometer_exposure_task_2 = asyncio.create_task( electrometer_exposure_coroutine_2 ) + self.log.debug("Number of electrometers is 2") mtcamera_exposure_id = await mtcamera_exposure_task finally: - if (len(electrometers_to_scan) == 0) or (len(electrometers_to_scan) == 0): + if (len(electrometers_to_scan) == 0) or (len(electrometers_to_scan) == 1): exposures_done.set_result(True) ( fiber_spectrum_red_exposure_result, From 9adfbf8a9d97ce4673e8ea5845645978b1e53ae7 Mon Sep 17 00:00:00 2001 From: elanaku Date: Tue, 12 Nov 2024 11:11:31 -0300 Subject: [PATCH 10/10] Remove extra debug statements --- python/lsst/ts/observatory/control/maintel/mtcalsys.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/python/lsst/ts/observatory/control/maintel/mtcalsys.py b/python/lsst/ts/observatory/control/maintel/mtcalsys.py index 41162f2b..87ca73f4 100644 --- a/python/lsst/ts/observatory/control/maintel/mtcalsys.py +++ b/python/lsst/ts/observatory/control/maintel/mtcalsys.py @@ -806,20 +806,14 @@ async def _take_data( fiber_spectrum_blue_exposure_task = asyncio.create_task( fiber_spectrum_blue_exposure_coroutine ) - self.log.debug(f"Electrometers to scan are {electrometers_to_scan}") - self.log.debug( - f"number electrometers to scan are {len(electrometers_to_scan)}" - ) if len(electrometers_to_scan) == 0: electrometer_exposure_task = asyncio.create_task( electrometer_exposure_coroutine ) - self.log.debug("Number of electrometers is 0") elif len(electrometers_to_scan) == 1: electrometer_exposure_task = asyncio.create_task( electrometer_exposure_coroutine ) - self.log.debug("Number of electrometers is 1") else: electrometer_exposure_task_1 = asyncio.create_task( electrometer_exposure_coroutine_1 @@ -827,7 +821,6 @@ async def _take_data( electrometer_exposure_task_2 = asyncio.create_task( electrometer_exposure_coroutine_2 ) - self.log.debug("Number of electrometers is 2") mtcamera_exposure_id = await mtcamera_exposure_task finally: