def test_calc_cutout_boundary_x_converter(self): self.calculator = CutoutCalculator(200, 200) _, converter = self.calculator.build_cutout_str( 15, (400, 50), self.imgsize) assert_that(converter.convert((400, 50)), equal_to((101, 50))) assert_that(converter.convert((300, 1)), equal_to((1, 1)))
def test_build_cutout_str_inverted(self): self.calculator = CutoutCalculator(20, 20) cutout_str, _ = self.calculator.build_cutout_str("10", (20, 20), (200, 200), inverted=True) assert_that(cutout_str, equal_to("[10][190:170,190:170]"))
def test_calc_cutout_boundary_ymax_converter(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) _, converter = self.calculator.calc_cutout((100, 175), self.imgsize) assert_that(converter.convert((100, 175)), equal_to((51, 76))) assert_that(converter.convert((50, 100)), equal_to((1, 1))) assert_that(converter.convert((150, 200)), equal_to((101, 101)))
def test_calc_cutout_inverted(self): self.calculator = CutoutCalculator(20, 20) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((20, 20), (200, 200), inverted=True) assert_that(x0, equal_to(190)) assert_that(x1, equal_to(170)) assert_that(y0, equal_to(190)) assert_that(y1, equal_to(170))
def test_calc_cutout_internal_converter(self): self.calculator = CutoutCalculator(100, 200) _, converter = self.calculator.calc_cutout((500, 600), self.imgsize) assert_that(converter.convert((400, 550)), equal_to((1, 1))) assert_that(converter.convert((600, 550)), equal_to((201, 1))) assert_that(converter.convert((400, 650)), equal_to((1, 101))) assert_that(converter.convert((600, 650)), equal_to((201, 101))) assert_that(converter.convert((500, 600)), equal_to((101, 51)))
def test_calc_cutout_boundary_y(self): self.calculator = CutoutCalculator(200, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((400, 50), self.imgsize) assert_that(x0, equal_to(300)) assert_that(x1, equal_to(500)) assert_that(y0, equal_to(1)) assert_that(y1, equal_to(201))
def test_calc_cutout_internal_str_float(self): self.calculator = CutoutCalculator(100, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((500.00, 600.00), self.imgsize) assert_that(x0, equal_to(400)) assert_that(x1, equal_to(600)) assert_that(y0, equal_to(550)) assert_that(y1, equal_to(650))
def test_calc_cutout_inverted_converter(self): self.calculator = CutoutCalculator(20, 20) _, converter = self.calculator.calc_cutout((20, 20), (200, 200), inverted=True) assert_that(converter.convert((10, 10)), equal_to((0, 0))) assert_that(converter.convert((30, 10)), equal_to((20, 0))) assert_that(converter.convert((10, 30)), equal_to((0, 20))) assert_that(converter.convert((30, 30)), equal_to((20, 20))) assert_that(converter.convert((20, 20)), equal_to((10, 10)))
def test_calc_cutout_boundary_xmin(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((25, 100), self.imgsize) assert_that(x0, equal_to(1)) assert_that(x1, equal_to(101)) assert_that(y0, equal_to(50)) assert_that(y1, equal_to(150))
def test_cutout_near_edge(self): calculator = CutoutCalculator(250, 250) (x0, x1, y0, y1), _ = calculator.calc_cutout( (1970.17, 4611.65), (2112, 4644), inverted=False) assert_that(x0, equal_to(1845)) assert_that(x1, equal_to(2095)) assert_that(y0, equal_to(4394)) assert_that(y1, equal_to(4644))
def test_cutout_over_two_edges(self): calculator = CutoutCalculator(250, 250) (x0, x1, y0, y1), _ = calculator.calc_cutout( (1997.68, 4618.31), (2112, 4644), inverted=False) delta = 0.01 assert_that(x0, close_to(1862, delta)) assert_that(x1, close_to(2112, delta)) assert_that(y0, close_to(4394, delta)) assert_that(y1, close_to(4644, delta))
def test_cutout_near_edge(self): calculator = CutoutCalculator(250, 250) (x0, x1, y0, y1), _ = calculator.calc_cutout((1970.17, 4611.65), (2112, 4644), inverted=False) assert_that(x0, equal_to(1845)) assert_that(x1, equal_to(2095)) assert_that(y0, equal_to(4394)) assert_that(y1, equal_to(4644))
def test_converter_near_edge(self): calculator = CutoutCalculator(250, 250) _, converter = calculator.calc_cutout( (1970.17, 4611.65), (2112, 4644), inverted=False) x, y = converter.convert((1970.17, 4611.65)) delta = 0.01 # note 1-based indexing not 0 assert_that(x, close_to(126.17, delta)) assert_that(y, close_to(218.65, delta))
def __init__(self, slice_rows=500, slice_cols=500, vosclient=None): """ Constructor. Args: slice_rows, slice_cols: int The number of rows and columns (pixels) to slice out around the source. Leave as None to use default configuration values. """ super(ImageCutoutDownloader, self).__init__() self.cutout_calculator = CutoutCalculator(slice_rows, slice_cols)
def test_cutout_over_two_edges(self): calculator = CutoutCalculator(250, 250) (x0, x1, y0, y1), _ = calculator.calc_cutout((1997.68, 4618.31), (2112, 4644), inverted=False) delta = 0.01 assert_that(x0, close_to(1862, delta)) assert_that(x1, close_to(2112, delta)) assert_that(y0, close_to(4394, delta)) assert_that(y1, close_to(4644, delta))
def test_converter_near_edge(self): calculator = CutoutCalculator(250, 250) _, converter = calculator.calc_cutout((1970.17, 4611.65), (2112, 4644), inverted=False) x, y = converter.convert((1970.17, 4611.65)) delta = 0.01 # note 1-based indexing not 0 assert_that(x, close_to(126.17, delta)) assert_that(y, close_to(218.65, delta))
def test_calc_cutout_boundary_xmax(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((175, 100), self.imgsize) assert_that(x0, equal_to(100)) assert_that(x1, equal_to(200)) assert_that(y0, equal_to(50)) assert_that(y1, equal_to(150))
def test_build_cutout_str_converter(self): self.calculator = CutoutCalculator(100, 200) _, converter = self.calculator.build_cutout_str(15, (500, 600), self.imgsize) assert_that(converter.convert((400, 550)), equal_to((1, 1))) assert_that(converter.convert((600, 550)), equal_to((201, 1))) assert_that(converter.convert((400, 650)), equal_to((1, 101))) assert_that(converter.convert((600, 650)), equal_to((201, 101))) assert_that(converter.convert((500, 600)), equal_to((101, 51)))
def __init__(self, slice_rows=250, slice_cols=250, vosclient=None): """ Constructor. Args: slice_rows, slice_cols: int The number of rows and columns (pixels) to slice out around the source. Leave as None to use default configuration values. """ super(ImageCutoutDownloader, self).__init__(vosclient=vosclient) self.cutout_calculator = CutoutCalculator(slice_rows, slice_cols)
class ImageCutoutDownloader(Downloader): """ Downloads a slice of an image relevant to examining a (potential) source. """ def __init__(self, slice_rows=500, slice_cols=500, vosclient=None): """ Constructor. Args: slice_rows, slice_cols: int The number of rows and columns (pixels) to slice out around the source. Leave as None to use default configuration values. """ super(ImageCutoutDownloader, self).__init__(vosclient=vosclient) self.cutout_calculator = CutoutCalculator(slice_rows, slice_cols) def download_cutout(self, reading, focus=None, needs_apcor=False): """ Downloads a cutout of the FITS image for a given source reading. Args: source_reading: ossos.astrom.SourceReading The reading which will be the focus of the downloaded image. focus: tuple(int, int) The x, y coordinates that should be the focus of the downloaded image. These coordinates should be in terms of the source_reading parameter's coordinate system. Default value is None, in which case the source reading's x, y position is used as the focus. needs_apcor: bool If True, the apcor file with data needed for photometry calculations is downloaded in addition to the image. Defaults to False. Returns: cutout: ossos.downloads.data.SourceCutout """ if focus is None: focus = reading.source_point cutout_str, converter = self.cutout_calculator.build_cutout_str( reading.get_extension(), focus, reading.get_original_image_size(), dx = reading.dx, dy = reading.dy, inverted=reading.is_inverted()) image_uri = reading.get_image_uri() cutout = re.findall(r'(\d+)', cutout_str) y2 = int(cutout[-1]) y1 = int(cutout[-2]) logger.info("Calculated cutout: %s for %s" % (cutout_str, image_uri)) hdulist = self.download_hdulist(image_uri, view="cutout", cutout=cutout_str) # modify the DATASEC to account for possible flip/flop and changes in dimensions of the image. (NAXIS1, NAXIS2) = reading.get_original_image_size() DATASEC = hdulist[0].header.get('DATASEC',None) if DATASEC is not None: datasec = re.findall(r'(\d+)', DATASEC) if y2 < y1: x2 = int(NAXIS1) - int(datasec[0]) + 1 x1 = int(NAXIS1) - int(datasec[1]) + 1 y2 = int(NAXIS2) - int(datasec[2]) + 1 y1 = int(NAXIS2) - int(datasec[3]) + 1 logger.info("Flip/Flopped DATASEC from {} to [{}:{}:{}:{}]".format(DATASEC, x1,x2,y1,y2)) datasec = (x1,x2,y1,y2) (x1,y1) = converter.convert((int(datasec[0]),int(datasec[2]))) x1 = max(1,x1) y1 = max(1,y1) (x2,y2) = converter.convert((int(datasec[1]),int(datasec[3]))) x2 = min(x2, int(hdulist[0].header['NAXIS1'])) y2 = min(y2, int(hdulist[0].header['NAXIS2'])) datasec = "[{}:{},{}:{}]".format(x1,x2,y1,y2) logger.info("Trimmed and offset DATASEC from {} to {}".format(DATASEC, datasec)) hdulist[0].header['DATASEC'] = datasec apcor = None if needs_apcor: try: apcor = self.download_apcor(reading.get_apcor_uri()) except: apcor = None zmag = None try: zmag = self.download_zmag(reading.get_zmag_uri()) except Exception as e: logger.debug(str(e)) pass return SourceCutout(reading, hdulist, converter, apcor, zmag=zmag)
def test_calc_cutout_boundary_x_converter(self): self.calculator = CutoutCalculator(200, 200) _, converter = self.calculator.build_cutout_str(15, (400, 50), self.imgsize) assert_that(converter.convert((400, 50)), equal_to((101, 50))) assert_that(converter.convert((300, 1)), equal_to((1, 1)))
class CutoutCalculatorTest(unittest.TestCase): def setUp(self): self.imgsize = (2000, 2000) def test_calc_cutout_internal(self): self.calculator = CutoutCalculator(100, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((500, 600), self.imgsize) assert_that(x0, equal_to(400)) assert_that(x1, equal_to(600)) assert_that(y0, equal_to(550)) assert_that(y1, equal_to(650)) def test_calc_cutout_internal_str(self): self.calculator = CutoutCalculator(100, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((500, 600), self.imgsize) assert_that(x0, equal_to(400)) assert_that(x1, equal_to(600)) assert_that(y0, equal_to(550)) assert_that(y1, equal_to(650)) def test_calc_cutout_internal_str_float(self): self.calculator = CutoutCalculator(100, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((500.00, 600.00), self.imgsize) assert_that(x0, equal_to(400)) assert_that(x1, equal_to(600)) assert_that(y0, equal_to(550)) assert_that(y1, equal_to(650)) def test_build_cutout_str(self): self.calculator = CutoutCalculator(100, 200) cutout_str, _ = self.calculator.build_cutout_str(15, (500, 600), self.imgsize) assert_that(cutout_str, equal_to("[15][400:600,550:650]")) def test_calc_cutout_internal_converter(self): self.calculator = CutoutCalculator(100, 200) _, converter = self.calculator.calc_cutout((500, 600), self.imgsize) assert_that(converter.convert((400, 550)), equal_to((1, 1))) assert_that(converter.convert((600, 550)), equal_to((201, 1))) assert_that(converter.convert((400, 650)), equal_to((1, 101))) assert_that(converter.convert((600, 650)), equal_to((201, 101))) assert_that(converter.convert((500, 600)), equal_to((101, 51))) def test_build_cutout_str_converter(self): self.calculator = CutoutCalculator(100, 200) _, converter = self.calculator.build_cutout_str(15, (500, 600), self.imgsize) assert_that(converter.convert((400, 550)), equal_to((1, 1))) assert_that(converter.convert((600, 550)), equal_to((201, 1))) assert_that(converter.convert((400, 650)), equal_to((1, 101))) assert_that(converter.convert((600, 650)), equal_to((201, 101))) assert_that(converter.convert((500, 600)), equal_to((101, 51))) def test_calc_cutout_boundary_x(self): self.calculator = CutoutCalculator(200, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((50, 400), self.imgsize) assert_that(x0, equal_to(1)) assert_that(x1, equal_to(201)) assert_that(y0, equal_to(300)) assert_that(y1, equal_to(500)) def test_calc_cutout_boundary_y(self): self.calculator = CutoutCalculator(200, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((400, 50), self.imgsize) assert_that(x0, equal_to(300)) assert_that(x1, equal_to(500)) assert_that(y0, equal_to(1)) assert_that(y1, equal_to(201)) def test_calc_cutout_boundary_x_converter(self): self.calculator = CutoutCalculator(200, 200) _, converter = self.calculator.build_cutout_str(15, (50, 400), self.imgsize) assert_that(converter.convert((50, 400)), equal_to((50, 101))) assert_that(converter.convert((1, 300)), equal_to((1, 1))) def test_calc_cutout_boundary_x_converter(self): self.calculator = CutoutCalculator(200, 200) _, converter = self.calculator.build_cutout_str(15, (400, 50), self.imgsize) assert_that(converter.convert((400, 50)), equal_to((101, 50))) assert_that(converter.convert((300, 1)), equal_to((1, 1))) def test_calc_cutout_boundary_xmax(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((175, 100), self.imgsize) assert_that(x0, equal_to(100)) assert_that(x1, equal_to(200)) assert_that(y0, equal_to(50)) assert_that(y1, equal_to(150)) def test_calc_cutout_boundary_ymax(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((100, 175), self.imgsize) assert_that(x0, equal_to(50)) assert_that(x1, equal_to(150)) assert_that(y0, equal_to(100)) assert_that(y1, equal_to(200)) def test_calc_cutout_boundary_xmax_converter(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) _, converter = self.calculator.calc_cutout((175, 100), self.imgsize) assert_that(converter.convert((175, 100)), equal_to((76, 51))) assert_that(converter.convert((100, 50)), equal_to((1, 1))) assert_that(converter.convert((200, 150)), equal_to((101, 101))) def test_calc_cutout_boundary_xmin(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((25, 100), self.imgsize) assert_that(x0, equal_to(1)) assert_that(x1, equal_to(101)) assert_that(y0, equal_to(50)) assert_that(y1, equal_to(150)) def test_calc_cutout_boundary_xmin_converter(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) _, converter = self.calculator.calc_cutout((25, 100), self.imgsize) assert_that(converter.convert((25, 100)), equal_to((25, 51))) def test_calc_cutout_boundary_ymax_converter(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) _, converter = self.calculator.calc_cutout((100, 175), self.imgsize) assert_that(converter.convert((100, 175)), equal_to((51, 76))) assert_that(converter.convert((50, 100)), equal_to((1, 1))) assert_that(converter.convert((150, 200)), equal_to((101, 101))) def test_calc_cutout_inverted(self): self.calculator = CutoutCalculator(20, 20) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((20, 20), (200, 200), inverted=True) assert_that(x0, equal_to(190)) assert_that(x1, equal_to(170)) assert_that(y0, equal_to(190)) assert_that(y1, equal_to(170)) def test_calc_cutout_inverted_converter(self): self.calculator = CutoutCalculator(20, 20) _, converter = self.calculator.calc_cutout((20, 20), (200, 200), inverted=True) assert_that(converter.convert((10, 10)), equal_to((0, 0))) assert_that(converter.convert((30, 10)), equal_to((20, 0))) assert_that(converter.convert((10, 30)), equal_to((0, 20))) assert_that(converter.convert((30, 30)), equal_to((20, 20))) assert_that(converter.convert((20, 20)), equal_to((10, 10))) def test_build_cutout_str_inverted(self): self.calculator = CutoutCalculator(20, 20) cutout_str, _ = self.calculator.build_cutout_str("10", (20, 20), (200, 200), inverted=True) assert_that(cutout_str, equal_to("[10][190:170,190:170]")) def test_cutout_near_edge(self): calculator = CutoutCalculator(250, 250) (x0, x1, y0, y1), _ = calculator.calc_cutout( (1970.17, 4611.65), (2112, 4644), inverted=False) assert_that(x0, equal_to(1845)) assert_that(x1, equal_to(2095)) assert_that(y0, equal_to(4394)) assert_that(y1, equal_to(4644)) def test_converter_near_edge(self): calculator = CutoutCalculator(250, 250) _, converter = calculator.calc_cutout( (1970.17, 4611.65), (2112, 4644), inverted=False) x, y = converter.convert((1970.17, 4611.65)) delta = 0.01 # note 1-based indexing not 0 assert_that(x, close_to(126.17, delta)) assert_that(y, close_to(218.65, delta)) def test_cutout_over_two_edges(self): calculator = CutoutCalculator(250, 250) (x0, x1, y0, y1), _ = calculator.calc_cutout( (1997.68, 4618.31), (2112, 4644), inverted=False) delta = 0.01 assert_that(x0, close_to(1862, delta)) assert_that(x1, close_to(2112, delta)) assert_that(y0, close_to(4394, delta)) assert_that(y1, close_to(4644, delta)) def test_inverse_converter(self): original_coords_x = 1500 original_coords_y = 2000 converter = CoordinateConverter(1000, 500) new_coords_x, new_coords_y = converter.convert( (original_coords_x, original_coords_y)) assert_that(new_coords_x, equal_to(500)) assert_that(new_coords_y, equal_to(1500)) inverse_converter = converter.get_inverse_converter() final_x, final_y = inverse_converter.convert( (new_coords_x, new_coords_y)) assert_that(final_x, equal_to(original_coords_x)) assert_that(final_y, equal_to(original_coords_y))
def test_calc_cutout_boundary_xmin_converter(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) _, converter = self.calculator.calc_cutout((25, 100), self.imgsize) assert_that(converter.convert((25, 100)), equal_to((25, 51)))
def test_build_cutout_str(self): self.calculator = CutoutCalculator(100, 200) cutout_str, _ = self.calculator.build_cutout_str(15, (500, 600), self.imgsize) assert_that(cutout_str, equal_to("[15][400:600,550:650]"))
def test_build_cutout_str(self): self.calculator = CutoutCalculator(100, 200) cutout_str, _ = self.calculator.build_cutout_str( 15, (500, 600), self.imgsize) assert_that(cutout_str, equal_to("[15][400:600,550:650]"))
class CutoutCalculatorTest(unittest.TestCase): def setUp(self): self.imgsize = (2000, 2000) def test_calc_cutout_internal(self): self.calculator = CutoutCalculator(100, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((500, 600), self.imgsize) assert_that(x0, equal_to(400)) assert_that(x1, equal_to(600)) assert_that(y0, equal_to(550)) assert_that(y1, equal_to(650)) def test_calc_cutout_internal_str(self): self.calculator = CutoutCalculator(100, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((500, 600), self.imgsize) assert_that(x0, equal_to(400)) assert_that(x1, equal_to(600)) assert_that(y0, equal_to(550)) assert_that(y1, equal_to(650)) def test_calc_cutout_internal_str_float(self): self.calculator = CutoutCalculator(100, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((500.00, 600.00), self.imgsize) assert_that(x0, equal_to(400)) assert_that(x1, equal_to(600)) assert_that(y0, equal_to(550)) assert_that(y1, equal_to(650)) def test_build_cutout_str(self): self.calculator = CutoutCalculator(100, 200) cutout_str, _ = self.calculator.build_cutout_str( 15, (500, 600), self.imgsize) assert_that(cutout_str, equal_to("[15][400:600,550:650]")) def test_calc_cutout_internal_converter(self): self.calculator = CutoutCalculator(100, 200) _, converter = self.calculator.calc_cutout((500, 600), self.imgsize) assert_that(converter.convert((400, 550)), equal_to((1, 1))) assert_that(converter.convert((600, 550)), equal_to((201, 1))) assert_that(converter.convert((400, 650)), equal_to((1, 101))) assert_that(converter.convert((600, 650)), equal_to((201, 101))) assert_that(converter.convert((500, 600)), equal_to((101, 51))) def test_build_cutout_str_converter(self): self.calculator = CutoutCalculator(100, 200) _, converter = self.calculator.build_cutout_str( 15, (500, 600), self.imgsize) assert_that(converter.convert((400, 550)), equal_to((1, 1))) assert_that(converter.convert((600, 550)), equal_to((201, 1))) assert_that(converter.convert((400, 650)), equal_to((1, 101))) assert_that(converter.convert((600, 650)), equal_to((201, 101))) assert_that(converter.convert((500, 600)), equal_to((101, 51))) def test_calc_cutout_boundary_x(self): self.calculator = CutoutCalculator(200, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((50, 400), self.imgsize) assert_that(x0, equal_to(1)) assert_that(x1, equal_to(201)) assert_that(y0, equal_to(300)) assert_that(y1, equal_to(500)) def test_calc_cutout_boundary_y(self): self.calculator = CutoutCalculator(200, 200) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((400, 50), self.imgsize) assert_that(x0, equal_to(300)) assert_that(x1, equal_to(500)) assert_that(y0, equal_to(1)) assert_that(y1, equal_to(201)) def test_calc_cutout_boundary_x_converter(self): self.calculator = CutoutCalculator(200, 200) _, converter = self.calculator.build_cutout_str( 15, (50, 400), self.imgsize) assert_that(converter.convert((50, 400)), equal_to((50, 101))) assert_that(converter.convert((1, 300)), equal_to((1, 1))) def test_calc_cutout_boundary_x_converter(self): self.calculator = CutoutCalculator(200, 200) _, converter = self.calculator.build_cutout_str( 15, (400, 50), self.imgsize) assert_that(converter.convert((400, 50)), equal_to((101, 50))) assert_that(converter.convert((300, 1)), equal_to((1, 1))) def test_calc_cutout_boundary_xmax(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((175, 100), self.imgsize) assert_that(x0, equal_to(100)) assert_that(x1, equal_to(200)) assert_that(y0, equal_to(50)) assert_that(y1, equal_to(150)) def test_calc_cutout_boundary_ymax(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((100, 175), self.imgsize) assert_that(x0, equal_to(50)) assert_that(x1, equal_to(150)) assert_that(y0, equal_to(100)) assert_that(y1, equal_to(200)) def test_calc_cutout_boundary_xmax_converter(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) _, converter = self.calculator.calc_cutout((175, 100), self.imgsize) assert_that(converter.convert((175, 100)), equal_to((76, 51))) assert_that(converter.convert((100, 50)), equal_to((1, 1))) assert_that(converter.convert((200, 150)), equal_to((101, 101))) def test_calc_cutout_boundary_xmin(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((25, 100), self.imgsize) assert_that(x0, equal_to(1)) assert_that(x1, equal_to(101)) assert_that(y0, equal_to(50)) assert_that(y1, equal_to(150)) def test_calc_cutout_boundary_xmin_converter(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) _, converter = self.calculator.calc_cutout((25, 100), self.imgsize) assert_that(converter.convert((25, 100)), equal_to((25, 51))) def test_calc_cutout_boundary_ymax_converter(self): self.imgsize = (200, 200) self.calculator = CutoutCalculator(100, 100) _, converter = self.calculator.calc_cutout((100, 175), self.imgsize) assert_that(converter.convert((100, 175)), equal_to((51, 76))) assert_that(converter.convert((50, 100)), equal_to((1, 1))) assert_that(converter.convert((150, 200)), equal_to((101, 101))) def test_calc_cutout_inverted(self): self.calculator = CutoutCalculator(20, 20) (x0, x1, y0, y1), _ = self.calculator.calc_cutout((20, 20), (200, 200), inverted=True) assert_that(x0, equal_to(190)) assert_that(x1, equal_to(170)) assert_that(y0, equal_to(190)) assert_that(y1, equal_to(170)) def test_calc_cutout_inverted_converter(self): self.calculator = CutoutCalculator(20, 20) _, converter = self.calculator.calc_cutout((20, 20), (200, 200), inverted=True) assert_that(converter.convert((10, 10)), equal_to((0, 0))) assert_that(converter.convert((30, 10)), equal_to((20, 0))) assert_that(converter.convert((10, 30)), equal_to((0, 20))) assert_that(converter.convert((30, 30)), equal_to((20, 20))) assert_that(converter.convert((20, 20)), equal_to((10, 10))) def test_build_cutout_str_inverted(self): self.calculator = CutoutCalculator(20, 20) cutout_str, _ = self.calculator.build_cutout_str("10", (20, 20), (200, 200), inverted=True) assert_that(cutout_str, equal_to("[10][190:170,190:170]")) def test_cutout_near_edge(self): calculator = CutoutCalculator(250, 250) (x0, x1, y0, y1), _ = calculator.calc_cutout((1970.17, 4611.65), (2112, 4644), inverted=False) assert_that(x0, equal_to(1845)) assert_that(x1, equal_to(2095)) assert_that(y0, equal_to(4394)) assert_that(y1, equal_to(4644)) def test_converter_near_edge(self): calculator = CutoutCalculator(250, 250) _, converter = calculator.calc_cutout((1970.17, 4611.65), (2112, 4644), inverted=False) x, y = converter.convert((1970.17, 4611.65)) delta = 0.01 # note 1-based indexing not 0 assert_that(x, close_to(126.17, delta)) assert_that(y, close_to(218.65, delta)) def test_cutout_over_two_edges(self): calculator = CutoutCalculator(250, 250) (x0, x1, y0, y1), _ = calculator.calc_cutout((1997.68, 4618.31), (2112, 4644), inverted=False) delta = 0.01 assert_that(x0, close_to(1862, delta)) assert_that(x1, close_to(2112, delta)) assert_that(y0, close_to(4394, delta)) assert_that(y1, close_to(4644, delta)) def test_inverse_converter(self): original_coords_x = 1500 original_coords_y = 2000 converter = CoordinateConverter(1000, 500) new_coords_x, new_coords_y = converter.convert( (original_coords_x, original_coords_y)) assert_that(new_coords_x, equal_to(500)) assert_that(new_coords_y, equal_to(1500)) inverse_converter = converter.get_inverse_converter final_x, final_y = inverse_converter.convert( (new_coords_x, new_coords_y)) assert_that(final_x, equal_to(original_coords_x)) assert_that(final_y, equal_to(original_coords_y))
class ImageCutoutDownloader(Downloader): """ Downloads a slice of an image relevant to examining a (potential) source. """ def __init__(self, slice_rows=500, slice_cols=500, vosclient=None): """ Constructor. Args: slice_rows, slice_cols: int The number of rows and columns (pixels) to slice out around the source. Leave as None to use default configuration values. """ super(ImageCutoutDownloader, self).__init__() self.cutout_calculator = CutoutCalculator(slice_rows, slice_cols) def download_cutout(self, reading, focus=None, needs_apcor=False): """ Downloads a cutout of the FITS image for a given source reading. Args: source_reading: ossos.astrom.SourceReading The reading which will be the focus of the downloaded image. focus: tuple(int, int) The x, y coordinates that should be the focus of the downloaded image. These coordinates should be in terms of the source_reading parameter's coordinate system. Default value is None, in which case the source reading's x, y position is used as the focus. needs_apcor: bool If True, the apcor file with data needed for photometry calculations is downloaded in addition to the image. Defaults to False. Returns: cutout: ossos.downloads.data.SourceCutout """ if focus is None: focus = reading.source_point assert isinstance(reading, SourceReading) dx = dy = 2 * max(reading.dra, reading.ddec) dx = max(reading.dx, dx) dy = max(reading.dy, dy) (NAXIS1, NAXIS2) = reading.get_original_image_size() cutout_str, converter = self.cutout_calculator.build_cutout_str( reading.get_extension(), focus, (NAXIS1, NAXIS2), dx=dx, dy=dy, inverted=reading.is_inverted) image_uri = reading.get_image_uri() cutout = re.findall(r'(\d+)', cutout_str) y2 = int(cutout[-1]) y1 = int(cutout[-2]) logger.debug("Calculated cutout: %s for %s" % (cutout_str, image_uri)) hdulist = storage.get_image(expnum=reading.get_exposure_number(), ccd=reading.get_ccd_num(), cutout=cutout_str, version=reading.get_observation().ftype, prefix=reading.get_observation().fk, return_file=False) #hdulist = self.download_hdulist(image_uri, view="cutout", # cutout=cutout_str) # modify the DATASEC to account for possible flip/flop and changes in dimensions of the image. DATASEC = hdulist[0].header.get('DATASEC', None) if DATASEC is not None: datasec = re.findall(r'(\d+)', DATASEC) if y2 < y1: x2 = int(NAXIS1) - int(datasec[0]) + 1 x1 = int(NAXIS1) - int(datasec[1]) + 1 y2 = int(NAXIS2) - int(datasec[2]) + 1 y1 = int(NAXIS2) - int(datasec[3]) + 1 logger.debug( "Flip/Flopped DATASEC from {} to [{}:{}:{}:{}]".format( DATASEC, x1, x2, y1, y2)) datasec = (x1, x2, y1, y2) (x1, y1) = converter.convert((int(datasec[0]), int(datasec[2]))) x1 = max(1, x1) y1 = max(1, y1) (x2, y2) = converter.convert((int(datasec[1]), int(datasec[3]))) x2 = min(x2, int(hdulist[0].header['NAXIS1'])) y2 = min(y2, int(hdulist[0].header['NAXIS2'])) datasec = "[{}:{},{}:{}]".format(x1, x2, y1, y2) logger.debug("Trimmed and offset DATASEC from {} to {}".format( DATASEC, datasec)) hdulist[0].header['DATASEC'] = datasec apcor = None if needs_apcor: try: apcor = self.download_apcor(reading.get_apcor_uri()) except Exception as e: logger.error(str(e)) apcor = None zmag = None try: zmag = self.download_zmag(reading.get_zmag_uri()) except Exception as e: logger.error(str(e)) pass return SourceCutout(reading, hdulist, converter, apcor, zmag=zmag)
class ImageCutoutDownloader(Downloader): """ Downloads a slice of an image relevant to examining a (potential) source. """ def __init__(self, slice_rows=250, slice_cols=250, vosclient=None): """ Constructor. Args: slice_rows, slice_cols: int The number of rows and columns (pixels) to slice out around the source. Leave as None to use default configuration values. """ super(ImageCutoutDownloader, self).__init__(vosclient=vosclient) self.cutout_calculator = CutoutCalculator(slice_rows, slice_cols) def download_cutout(self, reading, focus=None, needs_apcor=False): """ Downloads a cutout of the FITS image for a given source reading. Args: source_reading: ossos.astrom.SourceReading The reading which will be the focus of the downloaded image. focus: tuple(int, int) The x, y coordinates that should be the focus of the downloaded image. These coordinates should be in terms of the source_reading parameter's coordinate system. Default value is None, in which case the source reading's x, y position is used as the focus. needs_apcor: bool If True, the apcor file with data needed for photometry calculations is downloaded in addition to the image. Defaults to False. Returns: cutout: ossos.downloads.data.SourceCutout """ if focus is None: focus = reading.source_point cutout_str, converter = self.cutout_calculator.build_cutout_str( reading.get_extension(), focus, reading.get_original_image_size(), inverted=reading.is_inverted()) image_uri = reading.get_image_uri() logger.debug("Calculated cutout: %s for %s" % (cutout_str, image_uri)) hdulist = self.download_hdulist(image_uri, view="cutout", cutout=cutout_str) apcor = None if needs_apcor: apcor = self.download_apcor(reading.get_apcor_uri()) return SourceCutout(reading, hdulist, converter, apcor)