diff --git a/CHANGES.rst b/CHANGES.rst index f9d51287ce..44bd2278bc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -143,6 +143,8 @@ utils - Raising cleaner errors earlier when server returns with error. [#3284] +- ``return_frame`` parameter in ``utils.commons.parse_coordinates`` returns coordinates in the specified frame. [#3164] + 0.4.10 (2025-03-18) =================== @@ -2279,4 +2281,4 @@ Infrastructure, Utility and Other Changes and Additions 0.1 (2013-09-19) ================ -- Initial release. Includes features! +- Initial release. Includes features! \ No newline at end of file diff --git a/astroquery/mast/collections.py b/astroquery/mast/collections.py index bd14943a9c..ffab0d18f2 100644 --- a/astroquery/mast/collections.py +++ b/astroquery/mast/collections.py @@ -204,7 +204,7 @@ def query_region_async(self, coordinates, *, radius=0.2*u.deg, catalog="Hsc", """ # Put coordinates and radius into consistent format - coordinates = commons.parse_coordinates(coordinates) + coordinates = commons.parse_coordinates(coordinates, return_frame='icrs') # if radius is just a number we assume degrees radius = coord.Angle(radius, u.deg) diff --git a/astroquery/mast/missions.py b/astroquery/mast/missions.py index 49092206fe..a4402d6cd7 100644 --- a/astroquery/mast/missions.py +++ b/astroquery/mast/missions.py @@ -245,7 +245,7 @@ def query_region_async(self, coordinates, *, radius=3*u.arcmin, limit=5000, offs self._validate_criteria(**criteria) # Put coordinates and radius into consistent format - coordinates = commons.parse_coordinates(coordinates) + coordinates = commons.parse_coordinates(coordinates, return_frame='icrs') # If radius is just a number, assume arcminutes radius = coord.Angle(radius, u.arcmin) diff --git a/astroquery/mast/observations.py b/astroquery/mast/observations.py index cd0021a628..2503547036 100644 --- a/astroquery/mast/observations.py +++ b/astroquery/mast/observations.py @@ -22,8 +22,9 @@ from astropy.table import Table, Row, vstack from astroquery import log from astroquery.mast.cloud import CloudAccess +from astroquery.utils import commons -from ..utils import commons, async_to_sync +from ..utils import async_to_sync from ..utils.class_or_instance import class_or_instance from ..exceptions import (InvalidQueryError, RemoteServiceError, NoResultsWarning, InputWarning) @@ -234,7 +235,7 @@ def query_region_async(self, coordinates, *, radius=0.2*u.deg, pagesize=None, pa """ # Put coordinates and radius into consistent format - coordinates = commons.parse_coordinates(coordinates) + coordinates = commons.parse_coordinates(coordinates, return_frame='icrs') # if radius is just a number we assume degrees radius = coord.Angle(radius, u.deg) @@ -363,7 +364,7 @@ def query_region_count(self, coordinates, *, radius=0.2*u.deg, pagesize=None, pa """ # build the coordinates string needed by ObservationsClass._caom_filtered_position - coordinates = commons.parse_coordinates(coordinates) + coordinates = commons.parse_coordinates(coordinates, return_frame='icrs') # if radius is just a number we assume degrees radius = coord.Angle(radius, u.deg) diff --git a/astroquery/mast/tests/test_mast_remote.py b/astroquery/mast/tests/test_mast_remote.py index 3fa481e147..d1face7386 100644 --- a/astroquery/mast/tests/test_mast_remote.py +++ b/astroquery/mast/tests/test_mast_remote.py @@ -416,12 +416,6 @@ def test_mast_service_request(self): # Is result limited to ten rows assert len(result) == 10 - # Are the GALEX observations in the results table - assert "GALEX" in result['obs_collection'] - - # Are the two GALEX observations with obs_id 6374399093149532160 in the results table - assert len(result[np.where(result["obs_id"] == "6374399093149532160")]) == 2 - def test_mast_query(self): result = Mast.mast_query('Mast.Caom.Cone', ra=184.3, dec=54.5, radius=0.2) diff --git a/astroquery/mast/utils.py b/astroquery/mast/utils.py index 09c3695b43..60f9a04dc8 100644 --- a/astroquery/mast/utils.py +++ b/astroquery/mast/utils.py @@ -216,7 +216,8 @@ def parse_input_location(*, coordinates=None, objectname=None, resolver=None): Returns ------- response : `~astropy.coordinates.SkyCoord` - The given coordinates, or object's location as an `~astropy.coordinates.SkyCoord` object. + The given coordinates, or object's location as an `~astropy.coordinates.SkyCoord` object + in the ICRS frame. """ # Checking for valid input @@ -232,8 +233,9 @@ def parse_input_location(*, coordinates=None, objectname=None, resolver=None): if objectname: obj_coord = resolve_object(objectname, resolver=resolver) + # Parse coordinates, if given if coordinates: - obj_coord = commons.parse_coordinates(coordinates) + obj_coord = commons.parse_coordinates(coordinates, return_frame='icrs') return obj_coord diff --git a/astroquery/utils/commons.py b/astroquery/utils/commons.py index 6170d68777..2fec1e15dc 100644 --- a/astroquery/utils/commons.py +++ b/astroquery/utils/commons.py @@ -40,7 +40,7 @@ ASTROPY_LT_7_1_1 = not minversion('astropy', '7.1.1') -def parse_coordinates(coordinates): +def parse_coordinates(coordinates, *, return_frame=None): """ Takes a string or astropy.coordinates object. Checks if the string is parsable as an `astropy.coordinates` @@ -51,6 +51,10 @@ def parse_coordinates(coordinates): ---------- coordinates : str or `astropy.coordinates` object Astronomical coordinate + return_frame : `astropy.coordinates` frame + The frame to return the coordinates in. If None and ``coordinates`` is + a string, the frame will be ICRS. If ``coordinates`` is an `astropy.coordinates` object, the + frame will be the same as the input object. Returns ------- @@ -93,6 +97,11 @@ def parse_coordinates(coordinates): c = SkyCoord(coordinates) else: raise TypeError("Argument cannot be parsed as a coordinate") + + # Convert to requested frame, if given + if return_frame and c.frame.name != return_frame.lower(): + c = c.transform_to(return_frame) + return c diff --git a/astroquery/utils/tests/test_utils.py b/astroquery/utils/tests/test_utils.py index ce09b862ff..3132380e23 100644 --- a/astroquery/utils/tests/test_utils.py +++ b/astroquery/utils/tests/test_utils.py @@ -80,6 +80,30 @@ def test_parse_coordinates_4(): assert c.to_string() == coordinates +def test_parse_coordinates_return_frame(): + # String input should return in icrs frame + coords = commons.parse_coordinates('266.40498829 -28.93617776') + assert coords.frame.name == 'icrs' + + # SkyCoord input without return_frame should return in original frame + galactic = coord.SkyCoord('0 0', unit='deg', frame='galactic') + coords = commons.parse_coordinates(galactic) + assert coords.frame.name == 'galactic' + + # Parse a SkyCoord in galactic frame into icrs frame + galactic = coord.SkyCoord('0 0', unit='deg', frame='galactic') + icrs = galactic.transform_to('icrs') # Expected result + coords = commons.parse_coordinates(galactic, return_frame='icrs') + assert icrs.ra.deg == coords.ra.deg + assert icrs.dec.deg == coords.dec.deg + assert galactic.frame.name == 'galactic' + assert coords.frame.name == 'icrs' + + # ValueError if transformation fails + with pytest.raises(ValueError): + coords = commons.parse_coordinates(galactic, return_frame='invalid') + + col_1 = [1, 2, 3] col_2 = [0, 1, 0, 1, 0, 1] col_3 = ['v', 'w', 'x', 'y', 'z']