|
12 | 12 | import requests
|
13 | 13 | import platform
|
14 | 14 |
|
15 |
| -import astropy.coordinates as coord |
| 15 | +from astropy.coordinates import SkyCoord |
16 | 16 | from astropy.table import unique, Table
|
| 17 | +from astropy import units as u |
17 | 18 |
|
18 | 19 | from .. import log
|
19 | 20 | from ..version import version
|
@@ -111,49 +112,82 @@ def resolve_object(objectname, resolver=None, resolve_all=False):
|
111 | 112 | response : `~astropy.coordinates.SkyCoord`
|
112 | 113 | The sky position of the given object.
|
113 | 114 | """
|
| 115 | + is_catalog = False # Flag to check if object name belongs to a MAST catalog |
| 116 | + catalog = None # Variable to store the catalog name |
| 117 | + objectname = objectname.strip() |
| 118 | + catalog_prefixes = { |
| 119 | + 'TIC ': 'TIC', |
| 120 | + 'KIC ': 'KEPLER', |
| 121 | + 'EPIC ': 'K2' |
| 122 | + } |
114 | 123 |
|
115 |
| - # Check that resolver is valid |
116 |
| - valid_resolvers = ['ned', 'simbad'] |
117 | 124 | if resolver:
|
118 |
| - if resolver.lower() not in valid_resolvers: |
| 125 | + # Check that resolver is valid |
| 126 | + resolver = resolver.upper() |
| 127 | + if resolver not in ('NED', 'SIMBAD'): |
119 | 128 | raise ResolverError('Invalid resolver. Must be "NED" or "SIMBAD".')
|
120 | 129 |
|
121 | 130 | if resolve_all:
|
| 131 | + # Warn if user is trying to use a resolver with resolve_all |
122 | 132 | warnings.warn('The resolver parameter is ignored when resolve_all is True. '
|
123 | 133 | 'Coordinates will be resolved using all available resolvers.', InputWarning)
|
124 |
| - resolver = None |
| 134 | + |
| 135 | + # Check if object belongs to a MAST catalog |
| 136 | + for prefix, name in catalog_prefixes.items(): |
| 137 | + if objectname.startswith(prefix): |
| 138 | + is_catalog = True |
| 139 | + catalog = name |
| 140 | + break |
| 141 | + |
| 142 | + # Whether to set resolveAll to True when making the HTTP request |
| 143 | + # Should be True when resolve_all = True or when object name belongs to a MAST catalog (TIC, KIC, EPIC, K2) |
| 144 | + use_resolve_all = resolve_all or is_catalog |
125 | 145 |
|
126 | 146 | # Send request to STScI Archive Name Translation Application (SANTA)
|
127 |
| - params = {'name': objectname, 'outputFormat': 'json', 'resolveAll': str(resolve_all).lower()} |
128 |
| - if resolver: |
| 147 | + params = {'name': objectname, |
| 148 | + 'outputFormat': 'json', |
| 149 | + 'resolveAll': use_resolve_all} |
| 150 | + if resolver and not use_resolve_all: |
129 | 151 | params['resolver'] = resolver
|
130 | 152 | response = _simple_request('http://mastresolver.stsci.edu/Santa-war/query', params)
|
131 | 153 | response.raise_for_status() # Raise any errors
|
132 |
| - result = response.json() |
133 |
| - |
134 |
| - if len(result['resolvedCoordinate']) == 0: |
135 |
| - if resolver: |
136 |
| - raise ResolverError("Could not resolve {} to a sky position using {}. " |
137 |
| - "Please try another resolver or set ``resolver=None`` to use the first " |
138 |
| - "compatible resolver.".format(objectname, resolver)) |
139 |
| - else: |
140 |
| - raise ResolverError("Could not resolve {} to a sky position.".format(objectname)) |
141 |
| - |
| 154 | + result = response.json().get('resolvedCoordinate', []) |
| 155 | + |
| 156 | + # If a resolver is specified and resolve_all is False, find and return the result for that resolver |
| 157 | + if resolver and not resolve_all: |
| 158 | + resolver_result = next((res for res in result if res.get('resolver') == resolver), None) |
| 159 | + if not resolver_result: |
| 160 | + raise ResolverError(f'Could not resolve {objectname} to a sky position using {resolver}. ' |
| 161 | + 'Please try another resolver or set ``resolver=None`` to use the first ' |
| 162 | + 'compatible resolver.') |
| 163 | + resolver_coord = SkyCoord(resolver_result['ra'], resolver_result['decl'], unit='deg') |
| 164 | + |
| 165 | + # If object belongs to a MAST catalog, check the separation between the coordinates from the |
| 166 | + # resolver and the catalog |
| 167 | + if is_catalog: |
| 168 | + catalog_result = next((res for res in result if res.get('resolver') == catalog), None) |
| 169 | + if catalog_result: |
| 170 | + catalog_coord = SkyCoord(catalog_result['ra'], catalog_result['decl'], unit='deg') |
| 171 | + if resolver_coord.separation(catalog_coord) > 1 * u.arcsec: |
| 172 | + # Warn user if the coordinates differ by more than 1 arcsec |
| 173 | + warnings.warn(f'Resolver {resolver} returned coordinates that differ from MAST {catalog} catalog ' |
| 174 | + 'by more than 0.1 arcsec. ', InputWarning) |
| 175 | + |
| 176 | + return resolver_coord |
| 177 | + |
| 178 | + if not result: |
| 179 | + raise ResolverError('Could not resolve {} to a sky position.'.format(objectname)) |
| 180 | + |
| 181 | + # Return results for all compatible resolvers |
142 | 182 | if resolve_all:
|
143 |
| - # Return results for all compatible resolvers |
144 |
| - coordinates = {} |
145 |
| - for res in result['resolvedCoordinate']: |
146 |
| - ra = res['ra'] |
147 |
| - dec = res['decl'] |
148 |
| - coordinates[res['resolver']] = coord.SkyCoord(ra, dec, unit="deg") |
149 |
| - return coordinates |
150 |
| - |
151 |
| - # Return coordinates for a single resolver |
152 |
| - ra = result['resolvedCoordinate'][0]['ra'] |
153 |
| - dec = result['resolvedCoordinate'][0]['decl'] |
154 |
| - coordinates = coord.SkyCoord(ra, dec, unit="deg") |
155 |
| - |
156 |
| - return coordinates |
| 183 | + return { |
| 184 | + res['resolver']: SkyCoord(res['ra'], res['decl'], unit='deg') |
| 185 | + for res in result |
| 186 | + } |
| 187 | + |
| 188 | + # Case when resolve_all is False and no resolver is specified |
| 189 | + # SANTA returns result from first compatible resolver |
| 190 | + return SkyCoord(result[0]['ra'], result[0]['decl'], unit='deg') |
157 | 191 |
|
158 | 192 |
|
159 | 193 | def parse_input_location(coordinates=None, objectname=None, resolver=None):
|
|
0 commit comments