diff --git a/corgidrp/l3_to_l4.py b/corgidrp/l3_to_l4.py index 2828007..c2c2abf 100644 --- a/corgidrp/l3_to_l4.py +++ b/corgidrp/l3_to_l4.py @@ -37,7 +37,7 @@ def find_star(input_dataset): return input_dataset.copy() -def crop(input_dataset,sizexy=60,centerxy=None): +def crop(input_dataset,sizexy=None,centerxy=None): """ Crop the Images in a Dataset to a desired field of view. Default behavior is to @@ -52,7 +52,8 @@ def crop(input_dataset,sizexy=60,centerxy=None): Args: input_dataset (corgidrp.data.Dataset): a dataset of Images (any level) sizexy (int or array of int): desired frame size, if only one number is provided the - desired shape is assumed to be square, otherwise xy order. Defaults to 60. + desired shape is assumed to be square, otherwise xy order. If not provided, + defaults to 60 for NFOV (narrow field-of-view) observations. Defaults to None. centerxy (float or array of float): desired center (xy order), should be a pixel intersection (a.k.a half-integer) otherwise the function rounds to the nearest intersection. Defaults to the "STARLOCX/Y" header values. @@ -65,7 +66,7 @@ def crop(input_dataset,sizexy=60,centerxy=None): dataset = input_dataset.copy() # Require even data shape - if not np.all(np.array(sizexy)%2==0): + if not sizexy is None and not np.all(np.array(sizexy)%2==0): raise UserWarning('Even sizexy is required.') # Need to loop over frames and reinit dataset because array sizes change @@ -77,9 +78,12 @@ def crop(input_dataset,sizexy=60,centerxy=None): dqhdr = frame.dq_hdr errhdr = frame.err_hdr - # Require that mode is HLC for now - if not prihdr['MODE'] == 'HLC': - raise UserWarning('Crop function is currently only configured for mode HLC.') + # Pick default crop size based on the size of the effective field of view (determined by the Lyot stop) + if sizexy is None: + if prihdr['LSAMNAME'] == 'NFOV': + sizexy = 60 + else: + raise UserWarning('Crop function is currently only configured for NFOV (narrow field-of-view) observations if sizexy is not provided.') # Assign new array sizes and center location frame_shape = frame.data.shape diff --git a/tests/test_crop.py b/tests/test_crop.py index 9630307..67fd8ce 100644 --- a/tests/test_crop.py +++ b/tests/test_crop.py @@ -28,9 +28,7 @@ def make_test_dataset(shape=[100,100],centxy=None): exthdr['STARLOCY'] = cent[0] exthdr['MASKLOCX'] = cent[1] exthdr['MASKLOCY'] = cent[0] - exthdr['CRPIX1'] = cent[1] + 1 - exthdr['CRPIX2'] = cent[0] + 1 - prihdr['MODE'] = 'HLC' + prihdr['LSAMNAME'] = 'NFOV' if len(shape) == 2: test_arr[int(cent[0]-0.5):int(cent[0]+1.5),int(cent[1]-0.5):int(cent[1]+1.5)] = 1 @@ -82,7 +80,7 @@ def test_2d_square_offcenter_crop(): raise Exception("Unexpected result for 2D square offcenter crop test.") def test_2d_rect_offcenter_crop(): - """ Test cropping off-center non-square data. + """ Tests cropping off-center non-square data. """ test_dataset = make_test_dataset(shape=[100,40],centxy=[24.5,49.5]) cropped_test_dataset = crop(test_dataset,sizexy=[20,10],centerxy=None) @@ -91,7 +89,7 @@ def test_2d_rect_offcenter_crop(): raise Exception("Unexpected result for 2D rect offcenter crop test.") def test_3d_rect_offcenter_crop(): - """ Test cropping 3D off-center non-square data. + """ Tests cropping 3D off-center non-square data. """ test_dataset = make_test_dataset(shape=[3,100,40],centxy=[24.5,49.5]) cropped_test_dataset = crop(test_dataset,sizexy=[20,10],centerxy=None) @@ -101,9 +99,9 @@ def test_3d_rect_offcenter_crop(): if not cropped_test_dataset[0].data == pytest.approx(goal_rect_arr3d): raise Exception("Unexpected result for 2D rect offcenter crop test.") - -def test_edge_of_FOV(): - """ Test cropping right at the edge of the data array. +def test_edge_of_detector(): + """ Tests that trying to crop a region right at the edge of the + detector succeeds. """ test_dataset = make_test_dataset(shape=[100,100],centxy=[94.5,94.5]) cropped_test_dataset = crop(test_dataset,sizexy=10,centerxy=None) @@ -111,8 +109,8 @@ def test_edge_of_FOV(): if not cropped_test_dataset[0].data == pytest.approx(goal_arr): raise Exception("Unexpected result for edge of FOV crop test.") -def test_outside_FOV(): - """ Test cropping over the edge of the data array. +def test_outside_detector_edge(): + """ Tests that trying to crop a region outside the detector fails. """ test_dataset = make_test_dataset(shape=[100,100],centxy=[95.5,95.5]) @@ -121,7 +119,8 @@ def test_outside_FOV(): _ = crop(test_dataset,sizexy=10,centerxy=None) def test_nonhalfinteger_centxy(): - """ Test trying to center the crop not on a pixel intersection. + """ Tests that trying to crop data to a center that is not at the intersection + of 4 pixels results in centering on the nearest pixel intersection. """ test_dataset = make_test_dataset(shape=[100,100],centxy=[49.5,49.5]) cropped_test_dataset = crop(test_dataset,sizexy=10,centerxy=[49.7,49.7]) @@ -130,7 +129,8 @@ def test_nonhalfinteger_centxy(): raise Exception("Unexpected result for non half-integer crop test.") def test_header_updates_2d(): - """ Test that the header values are updated correctly. + """ Tests that cropping works, and updates header values related to + pixel positions and data shapes correctly, for 3D data. """ test_dataset = make_test_dataset(shape=[100,100],centxy=[49.5,49.5]) @@ -167,7 +167,8 @@ def test_header_updates_2d(): raise Exception("Frame dq header kw NAXIS2 not updated correctly.") def test_header_updates_3d(): - """ Test that the header values are updated correctly. + """ Tests that cropping works, and updates header values related to pixel + positions and data shapes correctly, for 3D data. """ test_dataset = make_test_dataset(shape=[3,100,100],centxy=[49.5,49.5]) @@ -209,12 +210,34 @@ def test_header_updates_3d(): if not cropped_test_dataset[0].err_hdr["NAXIS3"] == 3: raise Exception("Frame err header kw NAXIS3 not updated correctly.") +def test_non_nfov_input(): + """ Crop function is not configured for non-NFOV observations and should + fail if the Lyot stop is not in the narrow FOV position, unless the desired + image size is provided manually. + """ + + test_dataset = make_test_dataset(shape=[100,100],centxy=[50.5,50.5]) + for frame in test_dataset: + frame.pri_hdr['LSAMNAME'] = 'WFOV' + + try: + _ = crop(test_dataset,sizexy=20,centerxy=None) + except: + raise ValueError('Cropping a non-NFOV observation failed even though sizexy was provided') + + + with pytest.raises(UserWarning): + _ = crop(test_dataset,sizexy=None,centerxy=None) + + if __name__ == "__main__": test_2d_square_center_crop() test_2d_square_offcenter_crop() test_2d_rect_offcenter_crop() - test_edge_of_FOV() - test_outside_FOV() + test_3d_rect_offcenter_crop() + test_edge_of_detector() + test_outside_detector_edge() test_nonhalfinteger_centxy() test_header_updates_2d() test_header_updates_3d() + test_non_nfov_input()