diff --git a/webbpsf/gridded_library.py b/webbpsf/gridded_library.py index d1b95040..48ed4087 100644 --- a/webbpsf/gridded_library.py +++ b/webbpsf/gridded_library.py @@ -222,7 +222,13 @@ def _set_psf_locations(self, num_psfs, psf_location, psf_location_list): location_list = psf_location_list else: - max_size = self.webb._detector_npixels - 1 + if isinstance(self.webb._detector_npixels, tuple): + max_size = min(self.webb._detector_npixels) - 1 # a tuple has been provided for non-square detector. + # This is only true for MIRI (1024, 1032) and it's a + # small enough effect that it's reasonable to treat + # it as square when choosing locatins here. + else: + max_size = self.webb._detector_npixels - 1 loc_list = [int(round(num * max_size)) for num in np.linspace(0, 1, self.length, endpoint=True)] location_list = list(itertools.product(loc_list, loc_list)) # list of tuples (x,y) (for WebbPSF) diff --git a/webbpsf/tests/test_miri.py b/webbpsf/tests/test_miri.py index 012dd5fb..0555544d 100644 --- a/webbpsf/tests/test_miri.py +++ b/webbpsf/tests/test_miri.py @@ -87,3 +87,10 @@ def test_miri_slit_apertures(): assert np.isclose(miri._tel_coords()[0].to_value(u.arcsec), ap.V2Ref) assert np.isclose(miri._tel_coords()[1].to_value(u.arcsec), ap.V3Ref) + +def test_miri_nonsquare_detector(): + """ Test that we can handle the slightly different + dimenssions in X and Y of the MIRI detector""" + miri = webbpsf_core.MIRI() + miri.detector_position = (1023, 1031) # recall this is X, Y order + assert miri.detector_position == (1023, 1031) diff --git a/webbpsf/webbpsf_core.py b/webbpsf/webbpsf_core.py index c69a14a9..b05f3979 100644 --- a/webbpsf/webbpsf_core.py +++ b/webbpsf/webbpsf_core.py @@ -303,9 +303,13 @@ def detector_position(self, position): raise ValueError("Detector pixel coordinates must be pairs of nonnegative numbers, not {}".format(position)) if x < 0 or y < 0: raise ValueError("Detector pixel coordinates must be nonnegative integers") - if x > self._detector_npixels - 1 or y > self._detector_npixels - 1: - raise ValueError("The maximum allowed detector pixel coordinate value is {}".format( - self._detector_npixels - 1)) + if isinstance(self._detector_npixels, tuple): + det_npix_y, det_npix_x = self._detector_npixels # A tuple has been provided for a non-square detector with different Y and X dimensions + else: + det_npix_y = det_npix_x = self._detector_npixels # same dimensions in both X and Y + + if x > det_npix_x- 1 or y > det_npix_y - 1: + raise ValueError(f"The maximum allowed detector pixel coordinate value is (X,Y) = ({det_npix_x-1}, {det_npix_y-1})") self._detector_position = (int(position[0]), int(position[1])) @@ -700,7 +704,11 @@ def psf_grid(self, num_psfs=16, all_detectors=True, save=False, detectors = self.detector if single_psf_centered is True: - psf_location = (int((self._detector_npixels - 1) / 2), int((self._detector_npixels - 1) / 2)) # center pt + if isinstance(self._detector_npixels, tuple): + det_npix_y, det_npix_x = self._detector_npixels # A tuple has been provided for a non-square detector with different Y and X dimensions + else: + det_npix_y = det_npix_x = self._detector_npixels # same dimensions in both X and Y + psf_location = ( int(det_npix_x - 1) // 2, int(det_npix_y - 1) // 2) # center pt else: psf_location = self.detector_position[::-1] # (y,x) @@ -1835,7 +1843,7 @@ def __init__(self): self._detectors = {'MIRIM': 'MIRIM_FULL'} # Mapping from user-facing detector names to SIAF entries. self.detector = self.detector_list[0] - self._detector_npixels = 1024 + self._detector_npixels = (1032, 1024) # MIRI detector is not square self.detector_position = (512, 512) self._si_wfe_class = optics.MIRIFieldDependentAberrationAndObscuration