11from abc import abstractmethod , ABC
22from pathlib import Path
33from typing import List , Union , Tuple
4+ import warnings
45
56from astropy import wcs
67import astropy .units as u
78from s3path import S3Path
89from astropy .coordinates import SkyCoord
910import numpy as np
1011
11- from astrocut .exceptions import InvalidInputError , InvalidQueryError
12+ from astrocut .exceptions import InputWarning , InvalidInputError , InvalidQueryError
1213
1314from . import log
14- from .utils .utils import _handle_verbose , parse_size_input
15+ from .utils .utils import _handle_verbose
1516
1617
1718class Cutout (ABC ):
@@ -60,13 +61,15 @@ def __init__(self, input_files: List[Union[str, Path, S3Path]], coordinates: Uni
6061 self ._input_files = input_files
6162
6263 # Get coordinates as a SkyCoord object
63- if coordinates and not isinstance (coordinates , SkyCoord ):
64+ if isinstance (coordinates , tuple ):
65+ coordinates = SkyCoord (* coordinates , unit = 'deg' )
66+ elif not isinstance (coordinates , SkyCoord ):
6467 coordinates = SkyCoord (coordinates , unit = 'deg' )
6568 self ._coordinates = coordinates
6669 log .debug ('Coordinates: %s' , self ._coordinates )
6770
6871 # Turning the cutout size into an array of two values
69- self ._cutout_size = parse_size_input (cutout_size )
72+ self ._cutout_size = self . parse_size_input (cutout_size )
7073 log .debug ('Cutout size: %s' , self ._cutout_size )
7174
7275 # Assigning other attributes
@@ -84,6 +87,54 @@ def __init__(self, input_files: List[Union[str, Path, S3Path]], coordinates: Uni
8487 self ._output_dir = output_dir
8588 self ._verbose = verbose
8689
90+ def parse_size_input (self , cutout_size ):
91+ """
92+ Makes the given cutout size into a length 2 array.
93+
94+ Parameters
95+ ----------
96+ cutout_size : int, array-like, `~astropy.units.Quantity`
97+ The size of the cutout array. If ``cutout_size`` is a scalar number or a scalar
98+ `~astropy.units.Quantity`, then a square cutout of ``cutout_size`` will be created.
99+ If ``cutout_size`` has two elements, they should be in ``(ny, nx)`` order. Scalar numbers
100+ in ``cutout_size`` are assumed to be in units of pixels. `~astropy.units.Quantity` objects
101+ must be in pixel or angular units.
102+
103+ Returns
104+ -------
105+ response : array
106+ Length two cutout size array, in the form [ny, nx].
107+ """
108+
109+ # Making size into an array [ny, nx]
110+ if np .isscalar (cutout_size ):
111+ cutout_size = np .repeat (cutout_size , 2 )
112+
113+ if isinstance (cutout_size , u .Quantity ):
114+ cutout_size = np .atleast_1d (cutout_size )
115+ if len (cutout_size ) == 1 :
116+ cutout_size = np .repeat (cutout_size , 2 )
117+ elif not isinstance (cutout_size , np .ndarray ):
118+ cutout_size = np .array (cutout_size )
119+
120+ if len (cutout_size ) > 2 :
121+ warnings .warn ('Too many dimensions in cutout size, only the first two will be used.' ,
122+ InputWarning )
123+ cutout_size = cutout_size [:2 ]
124+
125+
126+ for dim in cutout_size :
127+ # Raise error if either dimension is not a positive number
128+ if dim <= 0 :
129+ raise InvalidInputError ('Cutout size dimensions must be greater than zero. '
130+ f'Provided size: ({ cutout_size [0 ]} , { cutout_size [1 ]} )' )
131+
132+ # Raise error if either dimension is not an pixel or angular Quantity
133+ if isinstance (dim , u .Quantity ) and dim .unit != u .pixel and dim .unit .physical_type != 'angle' :
134+ raise InvalidInputError (f'Cutout size unit { dim .unit .aliases [0 ]} is not supported.' )
135+
136+ return cutout_size
137+
87138 def _get_cutout_limits (self , img_wcs : wcs .WCS ) -> np .ndarray :
88139 """
89140 Returns the x and y pixel limits for the cutout.
0 commit comments