Skip to content

Commit

Permalink
Merge pull request #290 from roman-corgi/crop_bugfix
Browse files Browse the repository at this point in the history
Bug Fix: Crop Function Checks for Correct Header Keyword
  • Loading branch information
maxwellmb authored Jan 27, 2025
2 parents aad3489 + f49f9bd commit a52916f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 21 deletions.
16 changes: 10 additions & 6 deletions corgidrp/l3_to_l4.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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
Expand Down
53 changes: 38 additions & 15 deletions tests/test_crop.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -101,18 +99,18 @@ 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)

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])
Expand All @@ -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])
Expand All @@ -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])
Expand Down Expand Up @@ -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])
Expand Down Expand Up @@ -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()

0 comments on commit a52916f

Please sign in to comment.