def test_multiple_ext_cutouts(): test_subject = OpenCADCCutout() cutout_file_name_path = test_context.random_test_file_name_path() cutout_regions = [ PixelCutoutHDU([(1, 100), (1, 100)], "1"), PixelCutoutHDU([(1, 100), (1, 100)], "3") ] with open(cutout_file_name_path, 'wb') as output_writer, \ open(target_file_name, 'rb') as input_reader: test_subject.cutout(cutout_regions, input_reader, output_writer, 'FITS') expected = fits.open(target_file_name, do_not_scale_image_data=True) actual = fits.open(cutout_file_name_path, do_not_scale_image_data=True) assert len(actual) == 3 # test primary header unchanged assert len(expected[0].header) == len(actual[0].header) for key in expected[0].header.keys(): assert expected[0].header[key] == actual[0].header[key] # check BSCALE and BZERO correct in cutout file assert expected[1].header['BSCALE'] == actual[1].header['BSCALE'] assert expected[1].header['BZERO'] == actual[1].header['BZERO'] assert expected[3].header['BSCALE'] == actual[2].header['BSCALE'] assert expected[3].header['BZERO'] == actual[2].header['BZERO']
def test_extract(): data_shape = (9, 4) data = np.arange(36).reshape(data_shape) test_subject = CutoutND(data) cutout_region = PixelCutoutHDU([(4, 18)]) cutout = test_subject.extract(cutout_region.get_ranges()) expected_data = np.array([[3], [7], [11], [15], [19], [23], [27], [31], [35]]) np.testing.assert_array_equal(expected_data, cutout.data, 'Arrays do not match.')
def test_is_extension_requested(): test_subject = FITSHelper(io.BytesIO(), io.BytesIO()) dimension = PixelCutoutHDU([(400, 800)], extension=1) assert not test_subject._is_extension_requested('4', ('EXN', 4), dimension) dimension = PixelCutoutHDU([(400, 800)]) assert not test_subject._is_extension_requested('4', ('NOM', 1), dimension) dimension = PixelCutoutHDU([(400, 800)], extension=2) assert test_subject._is_extension_requested('2', ('NOM', 7), dimension)
def test_astropy_scaling(): test_subject = OpenCADCCutout() cutout_file_name_path = test_context.random_test_file_name_path() cutout_regions = [PixelCutoutHDU([], "2")] # Write out a test file with the test result FITS data. with open(cutout_file_name_path, 'wb') as output_writer, \ open(target_file_name, 'rb') as input_reader: test_subject.cutout(cutout_regions, input_reader, output_writer, 'FITS') # now check that BZERO and BSCALE have not been changed expected = fits.open(target_file_name, do_not_scale_image_data=True) actual = fits.open(cutout_file_name_path, do_not_scale_image_data=True) # check headers and data not changed. Except ... # expected missing keywords from actual: PCOUNT, XTENSION and GCOUNT # added to actual: SIMPLE del expected[2].header['PCOUNT'] del expected[2].header['XTENSION'] del expected[2].header['GCOUNT'] assert 'SIMPLE' in actual[0].header del actual[0].header['SIMPLE'] assert len(expected[2].header) == len(actual[0].header) for key in expected[2].header.keys(): assert expected[2].header[key] == actual[0].header[key] np.testing.assert_array_equal(expected[2].data, actual[0].data, 'Arrays do not match.') # do a cutout cutout_regions = [PixelCutoutHDU([(1, 100), (1, 100)], "3")] # Write out a test file with the test result FITS data. with open(cutout_file_name_path, 'wb') as output_writer, \ open(target_file_name, 'rb') as input_reader: test_subject.cutout(cutout_regions, input_reader, output_writer, 'FITS') # now check that BZERO and BSCALE have not been changed expected = fits.open(target_file_name, do_not_scale_image_data=True) actual = fits.open(cutout_file_name_path, do_not_scale_image_data=True) # check only expected headers changed # changed headers del expected[3].header['PCOUNT'] del expected[3].header['XTENSION'] del expected[3].header['GCOUNT'] assert 'SIMPLE' in actual[0].header del actual[0].header['SIMPLE'] assert len(expected[3].header) == len(actual[0].header) for key in expected[3].header.keys(): if key == 'NAXIS1' or key == 'NAXIS2': assert actual[0].header[key] == 100 else: assert expected[3].header[key] == actual[0].header[key]
def test_create(): test_subject = PixelCutoutHDU([(1, 200), (305, 600)], 7) assert test_subject.get_extension() == 7, 'Wrong extension.' test_subject = PixelCutoutHDU([(1, 200), (30)], 'SCI,5') assert test_subject.get_extension() == ('SCI', 5), 'Wrong extension.' test_subject = PixelCutoutHDU(extension='5') assert test_subject.get_extension() == 5, 'Wrong extension.'
def test__check_hdu_list(): in_io = io.BytesIO(b'TEST STRING HERE') out_io = io.BytesIO() test_subject = FITSHelper(in_io, out_io) dimensions = [PixelCutoutHDU([(20, 35), (40, 50)], extension=1)] hdu_list = _create_hdu_list() assert test_subject._check_hdu_list(dimensions, hdu_list), 'Should match.'
def test_construct(): test_subject = OpenCADCCutout() with pytest.raises(ValueError) as ve: test_subject.cutout([]) assert '{}'.format(ve) == 'No Cutout regions specified.', \ 'Wrong error message.' with pytest.raises(ValueError) as ve: test_subject.cutout([PixelCutoutHDU([(8, 10)])], input_reader=None) assert '{}'.format(ve) == 'No input source specified.', \ 'Wrong error message.' with pytest.raises(ValueError) as ve: test_subject.cutout([PixelCutoutHDU([(8, 10)])], output_writer=None) assert '{}'.format(ve) == 'No output target specified.', \ 'Wrong error message.'
def test_construct(): test_subject = OpenCADCCutout() with pytest.raises(ValueError) as ve: test_subject.cutout([]) assert str(ve.value) == 'No Cutout regions specified.', \ 'Wrong error message.' with pytest.raises(FileNotFoundError): test_subject.cutout([PixelCutoutHDU([(8, 10)])], input_reader=open('/no/such/file'))
def test__check_hdu_list(): in_io = io.BytesIO(b'TEST STRING HERE') out_io = io.BytesIO() test_subject = FITSHelper(in_io, out_io) dimensions = [PixelCutoutHDU([(20, 35), (40, 50)], extension=1)] hdu_list = _create_hdu_list() has_match = test_subject._check_hdu_list(dimensions, hdu_list) logging.debug('Output from _check_hdu_list() is {}'.format(has_match)) assert has_match, 'Should match.'
def test_get_shape(): test_subject = PixelCutoutHDU([(1, 200), (305, 600)]) shape = test_subject.get_shape() assert shape == (200, 296), 'Wrong shape output.' test_subject = PixelCutoutHDU([(10, 20), (30)]) shape = test_subject.get_shape() assert shape == (11, 1), 'Wrong shape output.'
def test_get_position(): test_subject = PixelCutoutHDU([(1, 200), (305, 360), (400, 1000)]) position = test_subject.get_position() assert position == (99, 331, 699), 'Wrong position output.' test_subject = PixelCutoutHDU([(10, 20), (30), (400, 406)]) position = test_subject.get_position() assert position == (14, 29, 402), 'Wrong position output.'
def test_get_ranges(): test_subject = PixelCutoutHDU([(1, 200), (305, 600)]) ranges = test_subject.get_ranges() assert ranges == [(1, 200), (305, 600)], 'Wrong ranges output.' test_subject = PixelCutoutHDU([(10, 20), (30)]) ranges = test_subject.get_ranges() assert ranges == [(10, 20), (30, 30)], 'Wrong ranges output.'
def test_multiple_cutouts_single_ext(): test_subject = OpenCADCCutout() cutout_file_name_path = test_context.random_test_file_name_path() cutout_regions = [ PixelCutoutHDU([(1, 100), (1, 100)], "1"), PixelCutoutHDU([(200, 300), (2, 300)], "1") ] with open(cutout_file_name_path, 'wb') as output_writer, \ open(target_file_name, 'rb') as input_reader: test_subject.cutout(cutout_regions, input_reader, output_writer, 'FITS') expected = fits.open(target_file_name, do_not_scale_image_data=True) actual = fits.open(cutout_file_name_path, do_not_scale_image_data=True) # cutouts in the same extension => no extra primary HDU assert len(actual) == 2 # test primary header changed assert len(expected[0].header) != len(actual[0].header) # check BSCALE and BZERO correct in cutout file assert expected[1].header['BSCALE'] == actual[0].header['BSCALE'] assert expected[1].header['BZERO'] == actual[0].header['BZERO'] assert expected[1].header['BSCALE'] == actual[1].header['BSCALE'] assert expected[1].header['BZERO'] == actual[1].header['BZERO']
def test_simple_cutout(): test_subject = OpenCADCCutout() cutout_file_name_path = test_context.random_test_file_name_path() logger.info('Testing with {}'.format(cutout_file_name_path)) cutout_regions = [PixelCutoutHDU([(300, 800), (810, 1000)])] # Write out a test file with the test result FITS data. with open(cutout_file_name_path, 'ab+') as output_writer, \ open(target_file_name, 'rb') as input_reader: test_subject.cutout(cutout_regions, input_reader, output_writer, 'FITS') with fits.open(expected_cutout_file_name, mode='readonly') \ as expected_hdu_list, \ fits.open(cutout_file_name_path, mode='readonly') \ as result_hdu_list: fits_diff = fits.FITSDiff(expected_hdu_list, result_hdu_list) np.testing.assert_array_equal( (), fits_diff.diff_hdu_count, 'HDU count diff should be empty.') for extension, result_hdu in enumerate(result_hdu_list): expected_hdu = expected_hdu_list[extension] expected_wcs = WCS(header=expected_hdu.header) result_wcs = WCS(header=result_hdu.header) np.testing.assert_array_equal( expected_wcs.wcs.crpix, result_wcs.wcs.crpix, 'Wrong CRPIX values.') np.testing.assert_array_equal( expected_wcs.wcs.crval, result_wcs.wcs.crval, 'Wrong CRVAL values.') assert expected_hdu.header['NAXIS1'] \ == result_hdu.header['NAXIS1'], 'Wrong NAXIS1 values.' assert expected_hdu.header['NAXIS2'] \ == result_hdu.header['NAXIS2'], 'Wrong NAXIS2 values.' assert expected_hdu.header.get( 'CHECKSUM') is None, 'Should not contain CHECKSUM.' assert expected_hdu.header.get( 'DATASUM') is None, 'Should not contain DATASUM.' np.testing.assert_array_equal( np.squeeze(expected_hdu.data), result_hdu.data, 'Arrays do not match.')
def test_create(): test_subject = PixelCutoutHDU([(1, 200), (305, 600)], 7) assert test_subject.get_extension() == 7, 'Wrong extension.' test_subject = PixelCutoutHDU([(1, 200), (30)], 'SCI,5') assert test_subject.get_extension() == ('SCI', 5), 'Wrong extension.' test_subject = PixelCutoutHDU([(99, 101), (44, 66)], 'AMS ,2') assert test_subject.get_extension() == ('AMS', 2), \ 'Wrong extension (didn' 't filter out spaces)' test_subject = PixelCutoutHDU([(12, 30)], 'EXT,0') assert test_subject.get_extension() == ('EXT', 1) with pytest.raises(ValueError, match=r"Specifying XTENSION return type " r"is not supported\."): PixelCutoutHDU([(23, 67), (23, 89)], extension='SCI, 3, i') test_subject = PixelCutoutHDU(extension='5') assert test_subject.get_extension() == 5, 'Wrong extension.' test_subject = PixelCutoutHDU([()]) assert test_subject.get_extension() == 0
def parse(self, pixel_range_input_str): """ Parse a string range. :param pixel_range_input_str: The string to parse. :return List of PixelCutoutHDU instances Example: rp = PixelRangeInputParser() rp.parse('[0][1]') => [PixelCutoutHDU((1,1), extension='0')] rp.parse('[99:112]') => [PixelCutoutHDU((99,112), extension='0')] rp.parse('[SCI][99:112][5]') => [PixelCutoutHDU((99,112), extension=SCI), PixelCutoutHDU(extension='5')] rp.parse('[IMG,2][100:112][6][300:600]') => [PixelCutoutHDU((100,112), extension='IMG,2'), PixelCutoutHDU((300,600), extension='6')] """ rs = pixel_range_input_str.strip() if not self.is_pixel_cutout(rs): raise PixelRangeInputParserError( 'Not a valid pixel cutout string "{}".'.format(rs)) # List of ranges in format [ext][pixel ranges] ranges = re.findall(self.match_pattern, rs) if not ranges: raise PixelRangeInputParserError( 'Invalid range specified. Should be in the format of {} \ (i.e.[0][8:35]), or single digit(i.e. 9). '.format( self.match_pattern)) parsed_items = [] for r in ranges: pixel_ranges = [] extension = '0' split_items = list( map(lambda x: x.split('[')[1], list(filter(None, r.split(']'))))) l_items = len(split_items) if l_items == 2: extension = split_items[0] pixel_ranges = list( map( self._to_range_tuple, list(filter(None, split_items[1].split(self.separator))))) elif l_items == 1: item = split_items[0] if item.count(self.delimiter) > 0: pixel_ranges = list( map(self._to_range_tuple, list(filter(None, item.split(self.separator))))) else: extension = item else: raise PixelRangeInputParserError( 'Nothing usable for range {}'.format(r)) parsed_items.append( PixelCutoutHDU(dimension_ranges=pixel_ranges, extension=extension)) return parsed_items