diff --git a/webbpsf/tests/test_miri.py b/webbpsf/tests/test_miri.py index 31e172d4..3795f463 100644 --- a/webbpsf/tests/test_miri.py +++ b/webbpsf/tests/test_miri.py @@ -96,8 +96,13 @@ def test_miri_nonsquare_detector(): assert miri.detector_position == (1023, 1031) def test_mode_switch(): + """Test switching between imaging and IFU modes, and switching IFU bands + Also checks this works to switch aperturenane, and conversely setting aperturename switches mode if needed. + Also checks that this automatically changes the rotation and pixelscale properties, as expected. + """ miri = webbpsf_core.MIRI() imager_rotation = miri._rotation + imager_pixscale = miri.pixelscale # Explicitly switch mode to IFU miri.mode = 'IFU' @@ -105,12 +110,15 @@ def test_mode_switch(): assert miri.detector =='MIRIFUSHORT' assert miri.aperturename.startswith('MIRIFU_CH') assert miri._rotation != imager_rotation + assert miri.pixelscale > imager_pixelscale # Explicitly switch back to imaging miri.mode = 'imaging' assert 'IFU' not in miri.aperturename assert miri.detector =='MIRIM' assert miri.aperturename.startswith('MIRIM_') assert miri._rotation == imager_rotation + assert miri.pixelscale == imager_pixelscale + # Implicitly switch to IFU miri.set_position_from_aperture_name('MIRIFU_CHANNEL3B') @@ -118,6 +126,7 @@ def test_mode_switch(): assert miri.detector =='MIRIFULONG' assert miri.aperturename == 'MIRIFU_CHANNEL3B' assert miri._rotation != imager_rotation + assert miri.pixelscale > imager_pixelscale # implicitly switch to imaging # LRS is an odd case, SLIT aper type but operates like in imaging mode @@ -126,6 +135,7 @@ def test_mode_switch(): assert miri.detector =='MIRIM' assert miri.aperturename.startswith('MIRIM_') assert miri._rotation == imager_rotation + assert miri.pixelscale == imager_pixelscale # And back to IFU again: miri.mode = 'IFU' @@ -133,12 +143,29 @@ def test_mode_switch(): assert miri.detector =='MIRIFUSHORT' assert miri.aperturename.startswith('MIRIFU_CH') assert miri._rotation != imager_rotation + assert miri.pixelscale > imager_pixelscale # band switching should toggle detector and aper name miri.band = '4C' assert miri.detector == 'MIRIFULONG' assert miri.aperturename == 'MIRIFU_CHANNEL4C' + assert miri.pixelscale > 3*imager_pixelscale miri.band = '2A' assert miri.detector == 'MIRIFUSHORT' assert miri.aperturename == 'MIRIFU_CHANNEL2A' + assert imager_pixelscale < miri.pixelscale < 2*imager_pixelscale + +def test_IFU_wavelengths(): + """ Test computing the wqvelength sampling for a sim IFU cube """ + miri = webbpsf_core.MIRI() + # check mode swith to IFU + miri.mode = 'IFU' + miri.band = '2A' + waves = miri.get_IFU_wavelengths() + assert isinstance(waves, u.Quantity) + + assert len(waves) > 900 # there are lots of wavelengths in MRScubes + # and test we can specify a reduced wavelength sampling: + for n in (10, 100): + assert len(miri.get_IFU_wavelengths(n)) == n diff --git a/webbpsf/tests/test_nirspec.py b/webbpsf/tests/test_nirspec.py index 3e5f9e3c..40a2aee0 100644 --- a/webbpsf/tests/test_nirspec.py +++ b/webbpsf/tests/test_nirspec.py @@ -52,6 +52,7 @@ def test_calc_datacube_fast(): def test_mode_switch(): + """ Test switch between IFU and imaging modes """ nrs = webbpsf_core.NIRSpec() # check mode swith to IFU nrs.mode = 'IFU' @@ -59,10 +60,25 @@ def test_mode_switch(): assert nrs.band == 'PRISM/CLEAR' # check switch of which IFU band - nrs.grating = 'G395H' + nrs.disperser = 'G395H' nrs.filter = 'F290LP' assert nrs.band == 'G395H/F290LP' # check mode switch back to imaging nrs.mode = 'imaging' assert 'IFU' not in nrs.aperturename + +def test_IFU_wavelengths(): + """ Test computing the wqvelength sampling for a sim IFU cube """ + nrs = webbpsf_core.NIRSpec() + # check mode swith to IFU + nrs.mode = 'IFU' + nrs.disperser = 'G235H' + nrs.filter = 'F170LP' + waves = nrs.get_IFU_wavelengths() + assert isinstance(waves, u.Quantity) + + assert len(waves) > 3000 # there are lots of wavelengths in the high-resolution grating cubes + # and test we can specify a reduced wavelength sampling: + for n in (10, 100): + assert len(nrs.get_IFU_wavelengths(n)) == n diff --git a/webbpsf/webbpsf_core.py b/webbpsf/webbpsf_core.py index 033d5672..1a265a55 100644 --- a/webbpsf/webbpsf_core.py +++ b/webbpsf/webbpsf_core.py @@ -961,6 +961,9 @@ def aperturename(self, value): self._aperturename = value # Update DetectorGeometry class self._detector_geom_info = DetectorGeometry(self.siaf, self._aperturename) + if not has_custom_pixelscale: + self.pixelscale = self._get_pixelscale_from_apername(value) + _log.debug( f"Pixelscale updated to {self.pixelscale} based on IFU cubepars for {value}") else: if self.detector not in value: @@ -2180,8 +2183,12 @@ def _get_pixelscale_from_apername(self, apername): """Simple utility function to look up pixelscale from apername""" if 'MIRIFU' in apername: - print('special case for MIRI IFU pixelscales') - return 0.1 + if apername.startswith('MIRIFU_CHANNEL'): + band = apername[-2:] + spaxelsize, _, _, _= self._IFU_bands_cubepars[band] + return spaxelsize + else: + raise RuntimeError(f"Not sure how to determine pixelscale for {apername}") else: return super()._get_pixelscale_from_apername(apername) @@ -2255,7 +2262,6 @@ def band(self, value): if value in self._IFU_bands_cubepars.keys(): self._band = value #self._slice_width = self._IFU_pixelscale[f"Ch{self._band[0]}"][0] - self.aperturename = 'MIRIFU_CHANNEL' + value # setting aperturename will also auto update self._rotation #self._rotation = self.MRS_rotation[self._band] @@ -2994,7 +3000,6 @@ def _tel_coords(self): def _get_pixelscale_from_apername(self, apername): """Simple utility function to look up pixelscale from apername""" if 'IFU' in apername: - print('DEBUG - special case for NIRSpec IFU pixelscales') return super()._get_pixelscale_from_apername('NRS1_FULL') else: return super()._get_pixelscale_from_apername(apername)