diff --git a/scopesim/effects/metis_wcu/metis_wcu.py b/scopesim/effects/metis_wcu/metis_wcu.py index 04e589af9..7f8659bc8 100644 --- a/scopesim/effects/metis_wcu/metis_wcu.py +++ b/scopesim/effects/metis_wcu/metis_wcu.py @@ -6,6 +6,7 @@ """ from typing import ClassVar +from collections.abc import Iterable import numpy as np from astropy.table import Table @@ -200,6 +201,46 @@ def set_lamp(self, lamp="bb"): self.compute_lamp_emission() self.compute_fp_emission() + def tune_laser(self, wavelength, force=False): + """Set the wavelength(s) of the tunable laser + + Parameters + ========== + wavelength : float, list, array [um] + The wavelength(s) at which the laser emits + force: boolean [True] <- currently not used + If True bypass the validation for the lasers available + wavelength range. + """ + if not isinstance(wavelength, Iterable): + wavelength = [wavelength] + if not force: + wavelength = self._validate_tunable(wavelength) + + # if nothing's there use a dummy value outside any range + # to prevent division by zero + if len(wavelength) == 0: + wavelength = [0.001] + + self.meta["laser_t_wave"] = wavelength + self.compute_lamp_emission() + self.compute_fp_emission() + + def _validate_tunable(self, wave): + """Validate wave against a wavelength range + + This is currently not used as there is no reliable + information on the tuning range of the QCL. + """ + lam_min, lam_max = self.meta["laser_t_wave_limits"] + + accept = [w for w in wave if (w >= lam_min) & (w <= lam_max)] + n_rejected = len(wave) - len(accept) + if n_rejected > 0: + logger.warning("Removed %d wavelengths outside allowed range (%.2f, %.2f) um", + n_rejected, lam_min, lam_max) + return accept + def get_wavelength(self): """Try to set the appropriate wavelength vector for mode and filter.""" # Need to provide for wcu_lms_extended @@ -423,24 +464,26 @@ def _laser_intensity(self): The function computes all three lasers at once. This is possible because the lines are so far apart that there is no band that sees them both. """ - print("Computing laser intensity") + logger.info("Computing laser intensity") lam = self.wavelength dlam = lam[1] - lam[0] mult_is = self.is_multiplication(lam) # Laser 1 (L band) # TODO move to yaml - lamc_l = 3.39 * u.um - power_l = 5e-3 * u.W / (c.c * c.h / lamc_l) * u.ph + lamc_l = self.meta["laser_l_wave"] * u.um + power_l = self.meta["laser_l_power"] * u.W / (c.c * c.h / lamc_l) * u.ph # Laser 2 (tunable), power divided among multiple lines - lam_t = seq(4.68, 4.78, 0.01) * u.um + if not isinstance(self.meta['laser_t_wave'], Iterable): + self.meta['laser_t_wave'] = [self.meta['laser_t_wave']] + lam_t = self.meta["laser_t_wave"] * u.um nline = len(lam_t) - power_t = 70e-3 * u.W / (c.c * c.h / lam) * u.ph / nline + power_t = self.meta["laser_t_power"] * u.W / (c.c * c.h / lam) * u.ph / nline # Laser 3 (M band) - lamc_m = 5.26 * u.um - power_m = 20e-3 * u.W / (c.c * c.h / lamc_m) * u.ph + lamc_m = self.meta["laser_m_wave"] * u.um + power_m = self.meta["laser_m_power"] * u.W / (c.c * c.h / lamc_m) * u.ph # Apply fibre transmission power_l *= self.fibre_trans diff --git a/scopesim/tests/tests_effects/test_MetisWCU.py b/scopesim/tests/tests_effects/test_MetisWCU.py index 5261e4065..8c8f63d47 100644 --- a/scopesim/tests/tests_effects/test_MetisWCU.py +++ b/scopesim/tests/tests_effects/test_MetisWCU.py @@ -40,6 +40,13 @@ def fixture_bbsource(): bb_temp=1000*u.K, is_temp=300*u.K, wcu_temp=300*u.K, + laser_l_wave=3.39, # [um] + laser_l_power=5e-3, # [W] + laser_t_wave=[4.70], # [um], array + laser_t_wave_limits=[1., 30.], # [um] + laser_t_power=70e-3, # [W] + laser_m_wave=5.26, # [um] + laser_m_power=20e-3, # [W] bb_aperture=1., bb_to_is=None, rho_tube=0.95, @@ -211,7 +218,18 @@ def test_laser_brighter_with_fibre_transmission(self, bbsource): bbsource.set_lamp("laser") intens_2 = np.sum(bbsource.intens_lamp) - assert intens_2 / intens_1 == ft_2 / ft_1 + npt.assert_allclose(intens_2 / intens_1, ft_2 / ft_1) + + + def test_can_tune_laser(self, bbsource): + bbsource.set_lamp("laser") + assert bbsource.meta["laser_t_wave"] == [4.70] + bbsource.tune_laser(4.72) + assert bbsource.meta["laser_t_wave"] == [4.72] + bbsource.tune_laser(np.linspace(4.68, 4.72, 10)) + assert len(bbsource.meta["laser_t_wave"]) == 10 + bbsource.tune_laser([]) + assert bbsource.meta["laser_t_wave"] == [0.001] @pytest.fixture(name="fpmask", scope="function")