def test_get_circle_cutout_pixels_iris_no_overlap(): header_filename = os.path.join(TESTDATA_DIR, IRIS_3D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) circle = Circle(20.0, 20.0, 0.1) test_subject = Transform() try: test_subject.get_circle_cutout_pixels(circle, header, 1, 2) assert False, 'Should raise NoContentError.' except NoContentError: assert True
def do_pos_circle(circle): cutout = ['{} 140 0 0.1'.format(circle)] test_subject = Transform() shapes = test_subject.world_to_shape(cutout) assert shapes is not None assert len(shapes) == 1 circle = shapes[0] assert isinstance(circle, Circle) assert circle.ra == 140.0 assert circle.dec == 0.0 assert circle.radius == 0.1
def test_band_tiled_multi_chunk(): header_filename = os.path.join(TESTDATA_DIR, TILED_MULTICHUNK_HEADER) header = fits.Header.fromtextfile(header_filename) energy = Energy(371.0e-9, 372.0e-9) test_subject = Transform() pixels = test_subject.get_energy_cutout_pixels(energy, header, 3) assert pixels is not None assert len(pixels) == 2 # SODA returns [0][1:2724,1:3] assert pixels[0] == 1 assert pixels[1] == 2724
def test_band_no_overlap(): header_filename = os.path.join(TESTDATA_DIR, CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) header.append(('RESTFRQ', 1.420406E9)) energy = Energy(212.0, 213.0) test_subject = Transform() try: test_subject.get_energy_cutout_pixels(energy, header, 3) assert False, 'Should raise NoContentError' except NoContentError as e: assert isinstance(e, NoContentError)
def test__append_world_to_circle_pixels(): cutouts = [(0, 0), (1, 256), (1, 256)] pixels = (1, 1089, None, 1089) header_filename = os.path.join(TESTDATA_DIR, VLASS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) test_subject = Transform() try: test_subject._append_world_to_circle_pixels(header, 1, 2, pixels, cutouts) assert False, 'Should throw NoContentError for missing value.' except NoContentError as nce: assert '{}'.format(nce) == 'Unable to create bounding box.', \ 'Wrong message.'
def test_interval_polygon(): header_filename = os.path.join(TESTDATA_DIR, QUERY_HEADER) header = fits.Header.fromtextfile(header_filename) # CW winding direction polygon = Polygon([[139.9, -0.1], [140.1, -0.1], [140.1, 0.1], [139.9, 0.1]]) test_subject = Transform() try: test_subject.get_polygon_cutout_pixels(polygon, header, 1, 2) assert False except ValueError: assert True
def test_get_circle_cutout_pixels_cgps_galactic(): header_filename = os.path.join(TESTDATA_DIR, CGPS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) circle = Circle(25.0, 60.0, 0.5) test_subject = Transform() pixels = test_subject.get_circle_cutout_pixels(circle, header, 1, 2) # SODA returns [0][350:584,136:370] assert pixels is not None assert pixels[0] == 367 assert pixels[1] == 568 assert pixels[2] == 152 assert pixels[3] == 353
def test_get_circle_cutout_pixels_vlass(): header_filename = os.path.join(TESTDATA_DIR, VLASS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) circle = Circle(168.34719985367971, 76.18699791158396, 0.010) test_subject = Transform() pixels = test_subject.get_circle_cutout_pixels(circle, header, 1, 2) assert pixels is not None assert len(pixels) == 4 assert pixels[0] == 2940 assert pixels[1] == 3061 assert pixels[2] == 4193 assert pixels[3] == 4314
def test_circle(): header_filename = os.path.join(TESTDATA_DIR, QUERY_HEADER) header = fits.Header.fromtextfile(header_filename) circle = Circle(140.0, 0.0, 0.1) test_subject = Transform() pixels = test_subject.get_circle_cutout_pixels(circle, header, 1, 2) # SODA returns [0][271:279,254:262,*] assert pixels is not None assert len(pixels) == 4 assert pixels[0] == 271 assert pixels[1] == 280 assert pixels[2] == 253 assert pixels[3] == 262
def test_get_polygon_cutout_pixels_vlass(): header_filename = os.path.join(TESTDATA_DIR, VLASS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) polygon = Polygon([[168.34, 76.18], [168.34, 76.19], [168.35, 76.19]]) test_subject = Transform() pixels = test_subject.get_polygon_cutout_pixels(polygon, header, 1, 2) # SODA returns cutout=[0][2997:3011,4211:4272,*,*] assert pixels is not None assert len(pixels) == 4 assert pixels[0] == 2996 assert pixels[1] == 3012 assert pixels[2] == 4211 assert pixels[3] == 4272
def test_get_energy_cutout_pixels_jcmt(): header_filename = os.path.join(TESTDATA_DIR, JCMT_3D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) # cdelt3 from caom2: 3.05140426249E-5 header.append(('CDELT3', 3.05140426249E-5)) energy = Energy(0.00091067, 0.00091012) test_subject = Transform() pixels = test_subject.get_energy_cutout_pixels(energy, header, 3) # caom2ops returns cutout=[0][*,*,290:6810]&cutout=[1][*,*,290:6810] assert pixels is not None assert len(pixels) == 2 assert pixels[0] == 290 assert pixels[1] == 6810
def test_get_circle_cutout_pixels_iris_all_overlap(): header_filename = os.path.join(TESTDATA_DIR, IRIS_3D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) circle = Circle(140.0, 0.0, 10.0) test_subject = Transform() pixels = test_subject.get_circle_cutout_pixels(circle, header, 1, 2) # cutout pixels: -125:676, -143:659 # cutout returning entire image returns empty list assert pixels is not None assert len(pixels) == 4 assert pixels[0] == 1 assert pixels[1] == 500 assert pixels[2] == 1 assert pixels[3] == 500
def test_pos_band(): header_filename = os.path.join(TESTDATA_DIR, CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) header.append(('RESTFRQ', 1.420406E9)) world = ['circle 25.0 60.0 0.5', 'BAND 211.0e-3 211.05e-3'] test_subject = Transform() pixel_cutout_hdu = test_subject.world_to_pixels(world, header) # SODA returns [0][350:584,136:370,91:177,*] assert pixel_cutout_hdu is not None ranges = pixel_cutout_hdu.get_ranges() assert len(ranges) == 4 assert ranges[0] == (367, 568) assert ranges[1] == (152, 353) assert ranges[2] == (91, 178) assert ranges[3] == (1, 1)
def test_polygon(): header_filename = os.path.join(TESTDATA_DIR, QUERY_HEADER) header = fits.Header.fromtextfile(header_filename) # CCW winding direction polygon = Polygon([[139.9, 0.1], [140.1, 0.1], [140.1, -0.1], [139.9, -0.1]]) test_subject = Transform() pixels = test_subject.get_polygon_cutout_pixels(polygon, header, 1, 2) # SODA returns [0][271:279,254:262,*] assert pixels is not None assert len(pixels) == 4 assert pixels[0] == 271 assert pixels[1] == 280 assert pixels[2] == 253 assert pixels[3] == 263
def test_get_energy_cutout_pixels_cgps_raises_error(): """ CPGS cube lacks rest wavelength or frequency for wcslib to do the transform from VELO-LFR to WAVE-???, and the python wcslib wrapper will raise a ValueError. """ header_filename = os.path.join(TESTDATA_DIR, CGPS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) energy = Energy(211.0e-3, 211.05e-3) test_subject = Transform() try: test_subject.get_energy_cutout_pixels(energy, header, 3) assert False, 'Should raise ValueError.' except ValueError: assert True
def test_get_energy_cutout_pixels_vlass(): """ BAND 0.04456576 0.11662493 cutout=[1:2] """ header_filename = os.path.join(TESTDATA_DIR, VLASS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) energy = Energy(0.04456576, 0.11662493) test_subject = Transform() pixels = test_subject.get_energy_cutout_pixels(energy, header, 3) # SODA returns cutout=[0][*,*,1:2,*] # library returns (before clipping) [2.79849082, 0.79277332] pixels assert pixels is not None assert len(pixels) == 2 assert pixels[0] == 1 assert pixels[1] == 3
def test_get_polarization_cutout_pixels_cgps(): """ CTYPE4 = 'STOKES ' / 4TH COORDINATE TYPE CRVAL4 = 1.000000000000E+00 / REF. COORD. 1-4=I,Q,U,V CRPIX4 = 1.00 / REF. PIXEL CDELT4 = 1.0000000E+00 / DELTA COORD. CROTA4 = 0.00 / ROTATION ANGLE (DEG) """ header_filename = os.path.join(TESTDATA_DIR, CGPS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) polarization = Polarization([PolarizationState.I]) test_subject = Transform() pixels = test_subject.get_polarization_cutout_pixels( polarization, header, 4) # SODA returns [*,*,*,1:1] assert pixels is not None assert len(pixels) == 2 assert pixels[0] == 1 assert pixels[1] == 1
def test_band(): header_filename = os.path.join(TESTDATA_DIR, CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) header.append(('RESTFRQ', 1.420406E9)) # energy from caom2 # bandpassName: 21 cm # resolvingPower: null # specsys: LSRK # ssysobs: null # restfrq: 1.420406E9 # restwav: null # velosys: null # zsource: null # ssyssrc: null # velang: null # ctype: VRAD # cunit: m/s # syser: # rnder: # naxis: 272 # crpix: 145.0 # crval: -60000.0 # cdelt: -824.46002 # bounds: null # range: null energy = Energy(211.0e-3, 211.05e-3) test_subject = Transform() pixels = test_subject.get_energy_cutout_pixels(energy, header, 3) assert pixels is not None assert len(pixels) == 2 # SODA returns [0][*,*,91:177,*] assert pixels[0] == 91 assert pixels[1] == 178
def test_parse_world(): test_subject = Transform() world = 'CIRCLE 1.0 2.0 3.0' circle = test_subject.parse_world(world) assert circle is not None assert isinstance(circle, Circle) assert circle.ra == 1.0 assert circle.dec == 2.0 assert circle.radius == 3.0 world = 'POLYGON 1.0 2.0 3.0 4.0 5.0 6.0' polygon = test_subject.parse_world(world) assert polygon is not None assert isinstance(polygon, Polygon) vertices = polygon.vertices assert len(vertices) == 3 assert vertices[0][0] == 1.0 assert vertices[0][1] == 2.0 assert vertices[1][0] == 3.0 assert vertices[1][1] == 4.0 assert vertices[2][0] == 5.0 assert vertices[2][1] == 6.0 world = 'BAND 1.0 2.0' energy = test_subject.parse_world(world) assert energy is not None assert isinstance(energy, Energy) assert energy.lower == 1.0 assert energy.upper == 2.0 world = 'TIME 1.0 2.0' time = test_subject.parse_world(world) assert time is not None assert isinstance(time, Time) assert time.lower == 1.0 assert time.upper == 2.0 world = 'POL I V' polarization = test_subject.parse_world(world) assert polarization is not None assert isinstance(polarization, Polarization) states = polarization.states assert len(states) == 2 assert states[0] == PolarizationState.I assert states[1] == PolarizationState.V
def test_world_to_pixels_vlass(): """ CIRCLE 168.34719985367971 76.18699791158396 0.01 BAND 0.04456576 0.11662493 POL I cutout=[0][2938:3062,4191:4316,1:2,1:1] """ header_filename = os.path.join(TESTDATA_DIR, VLASS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) world = [ 'circle 168.34719985367971 76.18699791158396 0.01', 'BAND 0.04456576 0.11662493', 'POL I' ] test_subject = Transform() pixel_cutout_hdu = test_subject.world_to_pixels(world, header) assert pixel_cutout_hdu is not None ranges = pixel_cutout_hdu.get_ranges() assert len(ranges) == 4 # assert ranges[0] == (2940, 3061) assert ranges[1] == (4193, 4314) assert ranges[2] == (1, 3) assert ranges[3] == (1, 1)
def _check_hdu_list(self, cutout_dimensions, hdu_list): has_match = False pixel_matches_left = len(cutout_dimensions) for curr_extension_idx, hdu in enumerate(hdu_list): # If we encounter a PrimaryHDU, write it at the top and continue. if isinstance(hdu, PrimaryHDU) and hdu.data is None: logger.debug('Appending Primary from index {}'.format( curr_extension_idx)) fits.append(filename=self.output_writer, header=hdu.header, data=None, overwrite=False, output_verify='silentfix', checksum='remove') elif hdu.is_image: header = hdu.header ext_name = header.get('EXTNAME') ext_ver = header.get('EXTVER', 0) curr_ext_name_ver = None if ext_name is not None: curr_ext_name_ver = (ext_name, ext_ver) try: if isinstance(cutout_dimensions[0], PixelCutoutHDU): for cutout_dimension in cutout_dimensions: if self._is_extension_requested( curr_extension_idx, curr_ext_name_ver, cutout_dimension): logger.debug( '*** Extension {} does match ({} | {})'. format(cutout_dimension.get_extension(), curr_extension_idx, curr_ext_name_ver)) pixel_matches_left -= 1 self._pixel_cutout(header, hdu.data, cutout_dimension) has_match = True if pixel_matches_left == 0: return has_match else: logger.debug('Handling WCS transform.') # Handle WCS transform. transform = Transform() transformed_cutout_dimension = \ transform.world_to_pixels(cutout_dimensions, header) logger.debug('Transformed {} into {}'.format( cutout_dimensions, transformed_cutout_dimension)) self._pixel_cutout(header, hdu.data, transformed_cutout_dimension) has_match = True except NoContentError: # Skip for now as we're iterating the loop. logger.debug('No overlap with extension {}'.format( curr_extension_idx)) logger.debug('Finished extension {}'.format(curr_extension_idx)) logger.debug('Has match in list? -- {}'.format(has_match)) return has_match
def test_get_polarization_cutout_pixels_vlass(): """ Polarization states for header are I, Q, U, V (1, 2, 3, 4) """ header_filename = os.path.join(TESTDATA_DIR, VLASS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) polarization = Polarization([PolarizationState.I]) test_subject = Transform() pixels = test_subject.get_polarization_cutout_pixels( polarization, header, 4) # SODA returns [*,*,*,1:1] assert pixels is not None assert len(pixels) == 2 assert pixels[0] == 1 assert pixels[1] == 1 polarization = Polarization([PolarizationState.I, PolarizationState.Q]) pixels = test_subject.get_polarization_cutout_pixels( polarization, header, 4) # should return [1:2] assert pixels is not None assert len(pixels) == 2 assert pixels[0] == 1 assert pixels[1] == 2 polarization = Polarization( [PolarizationState.I, PolarizationState.Q, PolarizationState.U]) pixels = test_subject.get_polarization_cutout_pixels( polarization, header, 4) # should return [1:3] assert pixels is not None assert len(pixels) == 2 assert pixels[0] == 1 assert pixels[1] == 3 polarization = Polarization([ PolarizationState.I, PolarizationState.Q, PolarizationState.U, PolarizationState.V ]) pixels = test_subject.get_polarization_cutout_pixels( polarization, header, 4) # should return [1:4] assert pixels is not None assert len(pixels) == 2 assert pixels[0] == 1 assert pixels[1] == 4 polarization = Polarization([PolarizationState.I, PolarizationState.V]) pixels = test_subject.get_polarization_cutout_pixels( polarization, header, 4) # should return [1:4] assert pixels is not None assert len(pixels) == 2 assert pixels[0] == 1 assert pixels[1] == 4
def test_world_to_shape(): test_subject = Transform() world = ['CIRCLE 1.0 2.0 3.0', 'CIRCLE 4.0 5.0 6.0'] try: shapes = test_subject.world_to_shape(world) assert False, 'Should raise ValueError' except ValueError: assert True world = ['CIRCLE 1.0 2.0 3.0', 'POLYGON 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0'] try: shapes = test_subject.world_to_shape(world) assert False, 'Should raise ValueError' except ValueError: assert True world = [ 'POLYGON 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0', 'POLYGON 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5' ] try: shapes = test_subject.world_to_shape(world) assert False, 'Should raise ValueError' except ValueError: assert True world = ['BAND 1.0 2.0 3.0', 'BAND 4.0 5.0 6.0'] try: shapes = test_subject.world_to_shape(world) assert False, 'Should raise ValueError' except ValueError: assert True world = ['TIME 1.0 2.0 3.0', 'TIME 4.0 5.0 6.0'] try: shapes = test_subject.world_to_shape(world) assert False, 'Should raise ValueError' except ValueError: assert True world = ['POL I V', 'POL Q U'] try: shapes = test_subject.world_to_shape(world) assert False, 'Should raise ValueError' except ValueError: assert True world = ['CIRCLE 1.0 2.0 3.0', 'BAND 4.0 5.0', 'TIME 6.0 7.0', 'POL I V'] shapes = test_subject.world_to_shape(world) assert shapes is not None assert len(shapes) == 4 circle = shapes[0] assert circle is not None assert isinstance(circle, Circle) assert circle.ra == 1.0 assert circle.dec == 2.0 assert circle.radius == 3.0 energy = shapes[1] assert energy is not None assert isinstance(energy, Energy) assert energy.lower == 4.0 assert energy.upper == 5.0 time = shapes[2] assert time is not None assert isinstance(time, Time) assert time.lower == 6.0 assert time.upper == 7.0 polarization = shapes[3] assert polarization is not None assert isinstance(polarization, Polarization) states = polarization.states assert len(states) == 2 assert states[0] == PolarizationState.I assert states[1] == PolarizationState.V world = [ 'POLYGON 1.0 1.5 2.0 2.5 3.0 3.5', 'BAND 4.0 5.0', 'TIME 6.0 7.0', 'POL I V' ] shapes = test_subject.world_to_shape(world) assert shapes is not None assert len(shapes) == 4 polygon = shapes[0] assert polygon is not None assert isinstance(polygon, Polygon) vertices = polygon.vertices assert len(vertices) == 3 assert vertices[0][0] == 1.0 assert vertices[0][1] == 1.5 assert vertices[1][0] == 2.0 assert vertices[1][1] == 2.5 assert vertices[2][0] == 3.0 assert vertices[2][1] == 3.5 energy = shapes[1] assert energy is not None assert isinstance(energy, Energy) assert energy.lower == 4.0 assert energy.upper == 5.0 time = shapes[2] assert time is not None assert isinstance(time, Time) assert time.lower == 6.0 assert time.upper == 7.0 polarization = shapes[3] assert polarization is not None assert isinstance(polarization, Polarization) states = polarization.states assert len(states) == 2 assert states[0] == PolarizationState.I assert states[1] == PolarizationState.V
def test_world_to_pixels_no_content(): header_filename = os.path.join(TESTDATA_DIR, VLASS_4D_CUBE_HEADER) header = fits.Header.fromtextfile(header_filename) # circle no content query = [ 'CIRCLE -168.34719985367971 -76.18699791158396 0.01', 'BAND 0.04456576 0.11662493', 'POL I' ] test_subject = Transform() try: test_subject.world_to_pixels(query, header) assert False, 'Should raise NoContentError' except NoContentError: assert True # polygon no content query = [ 'POLYGON -168.34 -76.18 -168.34 -76.19 -168.35 -76.19', 'BAND 0.04456576 0.11662493', 'POL I' ] test_subject = Transform() try: test_subject.world_to_pixels(query, header) assert False, 'Should raise NoContentError' except NoContentError: assert True # energy no content query = [ 'CIRCLE 168.34719985367971 76.18699791158396 0.01', 'BAND 0.14456576 0.21662493', 'POL I' ] test_subject = Transform() try: test_subject.world_to_pixels(query, header) assert False, 'Should raise NoContentError' except NoContentError: assert True # polarization no content query = [ 'CIRCLE 168.34719985367971 76.18699791158396 0.01', 'BAND 0.04456576 0.11662493', 'POL LL' ] test_subject = Transform() try: test_subject.world_to_pixels(query, header) assert False, 'Should raise NoContentError' except NoContentError: assert True
def _check_hdu_list(self, cutout_dimensions, hdu_list): has_match = False len_cutout_dimensions = len(cutout_dimensions) if len_cutout_dimensions > 0: result_hdu_list = None if self._require_primary_hdu(cutout_dimensions) and \ hdu_list[0].header['NAXIS'] == 0: # add the PrimaryHDU from the original HDU list result_hdu_list = fits.HDUList([hdu_list[0]]) # Check for a pixel cutout if isinstance(cutout_dimensions[0], PixelCutoutHDU): for cutout_dimension in cutout_dimensions: ext = cutout_dimension.get_extension() ext_idx = hdu_list.index_of(ext) hdu = hdu_list[ext_idx] # Entire extension was requested. if not cutout_dimension.get_ranges(): logger.debug( 'Appending entire extension {}'.format(ext)) result_hdu_list = self._add_hdu(hdu, result_hdu_list) has_match = True else: try: result_hdu_list = self._add_hdu( self._pixel_cutout(hdu, cutout_dimension), result_hdu_list) has_match = True logger.debug( 'Successfully cutout from {} ({})'.format( ext, ext_idx)) except NoContentError: logger.debug( 'Skipping non-overlapping cutout {}'.format( cutout_dimension)) else: # Skip the primary as it should be written out already. for hdu in hdu_list: if hdu.is_image and hdu.data is not None: transform = Transform() logger.debug( 'Transforming {}'.format(cutout_dimensions)) transformed_cutout_dimension = \ transform.world_to_pixels( cutout_dimensions, hdu.header) logger.debug('Transformed {} into {}'.format( cutout_dimensions, transformed_cutout_dimension)) try: result_hdu_list = self._add_hdu(self._pixel_cutout( hdu, transformed_cutout_dimension), result_hdu_list) has_match = True except NoContentError: logger.debug( 'Skipping non-overlapping cutout {}'.format( cutout_dimensions)) # time to write the cutout file result_hdu_list.writeto( self.output_writer, output_verify='ignore', checksum='remove') else: raise NoContentError('No overlap found (No cutout specified).') logger.debug('Has match in list? -- {}'.format(has_match)) return has_match