Skip to content

Commit cca8321

Browse files
committed
Merge pull request #641 from hamogu/fixxmatch
Xmatch: allow astropy tables input iwht more than 2 columns
2 parents 9a2d1a2 + 0dde48c commit cca8321

File tree

7 files changed

+76
-79
lines changed

7 files changed

+76
-79
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
0.3.1.dev
22
---------
33

4+
- Fix bug in xmatch service that required astropy tables to have exactly 2
5+
columns on input (#641)
46
- Fix NASA ADS, which had an internal syntax error (#602)
57
- Bugfix in NRAO queries: telescope config was parsed incorrectly (#629)
68
- IBE - added new module for locating data from PTF, WISE, and 2MASS from IRSA.

astroquery/xmatch/core.py

Lines changed: 36 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ class XMatchClass(BaseQuery):
1919

2020
def query(self, cat1, cat2, max_distance, colRA1=None,
2121
colDec1=None, colRA2=None, colDec2=None):
22-
"""Query the `CDS cross-match service
22+
"""
23+
Query the `CDS cross-match service
2324
<http://cdsxmatch.u-strasbg.fr/xmatch>`_ by finding matches between
2425
two (potentially big) catalogues.
2526
@@ -29,42 +30,38 @@ def query(self, cat1, cat2, max_distance, colRA1=None,
2930
Identifier of the first table. It can either be a URL, the
3031
payload of a local file being uploaded, a CDS table
3132
identifier (either *simbad* for a view of SIMBAD data / to
32-
point out a given VizieR table or a an AstroPy table.
33+
point out a given VizieR table) or a an AstroPy table.
3334
If the table is uploaded or accessed through a URL, it must be
3435
in VOTable or CSV format with the positions in J2000
3536
equatorial frame and as decimal degrees numbers.
36-
Note: If the passed argument is an AstroPy table, the column names
37-
are extracted from this object and the parameters `colRA1` and
38-
`colDec1` are ignored!
3937
cat2 : str or file
4038
Identifier of the second table. Follows the same rules as *cat1*.
4139
max_distance : `~astropy.units.arcsec`
4240
Maximum distance in arcsec to look for counterparts.
4341
Maximum allowed value is 180.
4442
colRA1 : str
4543
Name of the column holding the right ascension. Only required
46-
if `cat1` is an uploaded table or a pointer to a URL.
44+
if ``cat1`` is an uploaded table or a pointer to a URL.
4745
colDec1 : str
4846
Name of the column holding the declination. Only required if
49-
`cat1` is an uploaded table or a pointer to a URL.
47+
``cat1`` is an uploaded table or a pointer to a URL.
5048
colRA2 : str
5149
Name of the column holding the right ascension. Only required
52-
if `cat2` is an uploaded table or a pointer to a URL.
50+
if ``cat2`` is an uploaded table or a pointer to a URL.
5351
colDec2 : str
5452
Name of the column holding the declination. Only required if
55-
`cat2` is an uploaded table or a pointer to a URL.
53+
``cat2`` is an uploaded table or a pointer to a URL.
5654
5755
Returns
5856
-------
5957
table : `~astropy.table.Table`
6058
Query results table
61-
6259
"""
6360
response = self.query_async(
6461
cat1, cat2, max_distance, colRA1, colDec1, colRA2, colDec2)
6562
return ascii.read(response.text, format='csv')
6663

67-
@prepend_docstr_noreturns(query.__doc__)
64+
@prepend_docstr_noreturns("\n" + query.__doc__)
6865
def query_async(
6966
self, cat1, cat2, max_distance, colRA1=None,
7067
colDec1=None, colRA2=None, colDec2=None):
@@ -73,7 +70,6 @@ def query_async(
7370
-------
7471
response : `requests.Response`
7572
The HTTP response returned from the service.
76-
7773
"""
7874
if max_distance > 180 * arcsec:
7975
raise ValueError(
@@ -84,57 +80,49 @@ def query_async(
8480
'RESPONSEFORMAT': 'csv',
8581
}
8682
kwargs = {}
87-
if isinstance(cat1, six.string_types):
88-
payload['cat1'] = cat1
89-
elif isinstance(cat1, Table):
90-
payload['colRA1'], payload['colDec1'] = cat1.colnames
83+
84+
self._prepare_sending_table(1, payload, kwargs, cat1, colRA1, colDec1)
85+
self._prepare_sending_table(2, payload, kwargs, cat2, colRA2, colDec2)
86+
87+
response = commons.send_request(
88+
self.URL, payload, self.TIMEOUT, **kwargs)
89+
return response
90+
91+
def _prepare_sending_table(self, i, payload, kwargs, cat, colRA, colDec):
92+
'''Check if table is a string, a `astropy.table.Table`, etc. and set
93+
query parameters accordingly.
94+
'''
95+
catstr = 'cat{0}'.format(i)
96+
if isinstance(cat, six.string_types):
97+
payload[catstr] = cat
98+
elif isinstance(cat, Table):
9199
# write the Table's content into a new, temporary CSV-file
92100
# so that it can be pointed to via the `files` option
93101
# file will be closed when garbage-collected
94102
fp = six.StringIO()
95-
cat1.write(fp, format='ascii.csv')
103+
cat.write(fp, format='ascii.csv')
96104
fp.seek(0)
97-
kwargs['files'] = {'cat1': fp}
105+
kwargs['files'] = {catstr: fp}
98106
else:
99107
# assume it's a file-like object, support duck-typing
100-
kwargs['files'] = {'cat1': cat1}
101-
if not self.is_table_available(cat1) and\
102-
payload.get('colRA1') is None or\
103-
payload.get('colDec1') is None:
108+
kwargs['files'] = {catstr: cat}
109+
if not self.is_table_available(cat):
110+
if ((colRA is None) or (colDec is None)):
111+
raise ValueError('Specify the name of the RA/Dec columns in' +
112+
' the input table.')
104113
# if `cat1` is not a VizieR table,
105114
# it is assumed it's either a URL or an uploaded table
106-
payload['colRA1'] = colRA1
107-
payload['colDec1'] = colDec1
108-
if isinstance(cat2, six.string_types):
109-
payload['cat2'] = cat2
110-
elif isinstance(cat2, Table):
111-
payload['colRA2'], payload['colDec2'] = cat2.colnames
112-
# write the Table's content into a new, temporary CSV-file
113-
# so that it can be pointed to via the `files` option
114-
# file will be closed when garbage-collected
115-
fp = six.StringIO()
116-
cat1.write(fp, format='ascii.csv')
117-
fp.seek(0)
118-
kwargs['files'] = {'cat1': fp}
119-
else:
120-
# assume it's a file-like object, support duck-typing
121-
kwargs['files'] = {'cat2': cat2}
122-
if not self.is_table_available(cat2) and\
123-
payload.get('colRA2') is None or\
124-
payload.get('colDec2') is None:
125-
# if `cat2` is not a VizieR table,
126-
# it is assumed it's either a URL or an uploaded table
127-
payload['colRA2'] = colRA2
128-
payload['colDec2'] = colDec2
129-
response = commons.send_request(
130-
self.URL, payload, self.TIMEOUT, **kwargs)
131-
return response
115+
payload['colRA{0}'.format(i)] = colRA
116+
payload['colDec{0}'.format(i)] = colDec
117+
132118

133119
def is_table_available(self, table_id):
134120
"""Return True if the passed CDS table identifier is one of the
135121
available VizieR tables, otherwise False.
136122
137123
"""
124+
if isinstance(table_id, six.string_types) and (table_id[:7] == 'vizier:'):
125+
table_id = table_id[7:]
138126
return table_id in self.get_available_tables()
139127

140128
def get_available_tables(self):
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
ra,dec
2-
267.22029,-20.35869
3-
274.83971,-25.42714
4-
275.92229,-30.36572
5-
283.26621,-8.70756
6-
306.01575,33.86756
7-
322.493,12.16703
1+
ra,dec,my_id
2+
267.22029,-20.35869,1
3+
274.83971,-25.42714,2
4+
275.92229,-30.36572,3
5+
283.26621,-8.70756,4
6+
306.01575,33.86756,5
7+
322.493,12.16703,6
Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
angDist,ra,dec,2MASS,RAJ2000,DEJ2000,errHalfMaj,errHalfMin,errPosAng,Jmag,Hmag,Kmag,e_Jmag,e_Hmag,e_Kmag,Qfl,Rfl,X,MeasureJD
2-
1.352044,267.22029,-20.35869,17485281-2021323,267.220049,-20.358990,0.150,0.110,16,9.931,8.822,7.550,0.239,0.241,,EEU,226,2,2450950.8609
3-
1.578188,267.22029,-20.35869,17485288-2021328,267.220348,-20.359125,0.140,0.120,158,8.868,7.784,8.530,,,0.128,UUB,662,2,2450950.8609
4-
3.699368,267.22029,-20.35869,17485264-2021294,267.219344,-20.358171,0.130,0.120,33,9.562,8.525,9.445,,,0.119,UUB,662,2,2450950.8609
5-
3.822922,267.22029,-20.35869,17485299-2021279,267.220825,-20.357754,0.080,0.070,7,10.756,9.725,9.287,0.139,0.127,0.103,EBA,222,2,2450950.8609
6-
4.576677,267.22029,-20.35869,17485255-2021326,267.218994,-20.359064,0.140,0.130,87,10.431,9.348,7.926,0.159,0.316,,CEU,226,2,2450950.8609
7-
0.219609,274.83971,-25.42714,18192154-2525377,274.839773,-25.427162,0.060,0.060,90,9.368,8.431,7.919,0.024,0.044,0.036,AAA,211,0,2451407.5033
8-
1.633225,275.92229,-30.36572,18234133-3021582,275.922233,-30.366171,0.080,0.080,55,12.947,12.334,12.145,0.156,0.221,0.127,EEE,222,2,2451021.7212
9-
0.536998,283.26621,-8.70756,18530390-0842276,283.266284,-8.707690,0.060,0.060,45,12.182,11.534,11.380,0.057,0.071,0.063,AAA,222,0,2451301.7945
10-
1.178542,306.01575,33.86756,20240382+3352021,306.015944,+33.867275,0.060,0.060,90,13.575,12.684,12.321,0.025,0.027,0.026,AAA,222,0,2450948.9708
11-
0.853178,322.493,12.16703,21295836+1210007,322.493171,+12.166862,0.100,0.080,179,9.798,9.339,9.176,0.109,0.150,0.100,EEA,222,0,2451080.6935
12-
4.503950,322.493,12.16703,21295861+1210023,322.494242,+12.167332,0.100,0.080,1,10.057,9.720,9.483,0.077,0.136,0.088,EEE,222,0,2451080.6935
1+
angDist,ra,dec,my_id,2MASS,RAJ2000,DEJ2000,errHalfMaj,errHalfMin,errPosAng,Jmag,Hmag,Kmag,e_Jmag,e_Hmag,e_Kmag,Qfl,Rfl,X,MeasureJD
2+
1.352044,267.22029,-20.35869,1,17485281-2021323,267.220049,-20.358990,0.150,0.110,16,9.931,8.822,7.550,0.239,0.241,,EEU,226,2,2450950.8609
3+
1.578188,267.22029,-20.35869,1,17485288-2021328,267.220348,-20.359125,0.140,0.120,158,8.868,7.784,8.530,,,0.128,UUB,662,2,2450950.8609
4+
3.699368,267.22029,-20.35869,1,17485264-2021294,267.219344,-20.358171,0.130,0.120,33,9.562,8.525,9.445,,,0.119,UUB,662,2,2450950.8609
5+
3.822922,267.22029,-20.35869,1,17485299-2021279,267.220825,-20.357754,0.080,0.070,7,10.756,9.725,9.287,0.139,0.127,0.103,EBA,222,2,2450950.8609
6+
4.576677,267.22029,-20.35869,1,17485255-2021326,267.218994,-20.359064,0.140,0.130,87,10.431,9.348,7.926,0.159,0.316,,CEU,226,2,2450950.8609
7+
0.219609,274.83971,-25.42714,2,18192154-2525377,274.839773,-25.427162,0.060,0.060,90,9.368,8.431,7.919,0.024,0.044,0.036,AAA,211,0,2451407.5033
8+
1.633225,275.92229,-30.36572,3,18234133-3021582,275.922233,-30.366171,0.080,0.080,55,12.947,12.334,12.145,0.156,0.221,0.127,EEE,222,2,2451021.7212
9+
0.536998,283.26621,-8.70756,4,18530390-0842276,283.266284,-8.707690,0.060,0.060,45,12.182,11.534,11.380,0.057,0.071,0.063,AAA,222,0,2451301.7945
10+
1.178542,306.01575,33.86756,5,20240382+3352021,306.015944,+33.867275,0.060,0.060,90,13.575,12.684,12.321,0.025,0.027,0.026,AAA,222,0,2450948.9708
11+
0.853178,322.493,12.16703,6,21295836+1210007,322.493171,+12.166862,0.100,0.080,179,9.798,9.339,9.176,0.109,0.150,0.100,EEA,222,0,2451080.6935
12+
4.503950,322.493,12.16703,6,21295861+1210023,322.494242,+12.167332,0.100,0.080,1,10.057,9.720,9.483,0.077,0.136,0.088,EEE,222,0,2451080.6935

astroquery/xmatch/tests/test_xmatch.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ def test_xmatch_is_avail_table(monkeypatch):
6969

7070
assert xm.is_table_available('II/311/wise')
7171
assert xm.is_table_available('II/246/out')
72-
assert not xm.is_table_available('vizier:II/311/wise')
73-
72+
assert xm.is_table_available('vizier:II/311/wise')
73+
assert not xm.is_table_available('blablabla')
7474

7575
def test_xmatch_query_local(monkeypatch):
7676
xm = XMatch()
@@ -87,7 +87,7 @@ def test_xmatch_query_local(monkeypatch):
8787
table = ascii.read(response.text, format='csv')
8888
assert isinstance(table, Table)
8989
assert table.colnames == [
90-
'angDist', 'ra', 'dec', '2MASS', 'RAJ2000', 'DEJ2000',
90+
'angDist', 'ra', 'dec', 'my_id', '2MASS', 'RAJ2000', 'DEJ2000',
9191
'errHalfMaj', 'errHalfMin', 'errPosAng', 'Jmag', 'Hmag', 'Kmag',
9292
'e_Jmag', 'e_Hmag', 'e_Kmag', 'Qfl', 'Rfl', 'X', 'MeasureJD']
9393
assert len(table) == 11
@@ -103,15 +103,15 @@ def test_xmatch_query_cat1_table_local(monkeypatch):
103103
request_mockreturn(request_type, url, data, **kwargs))
104104
with open(data_path('posList.csv')) as pos_list:
105105
input_table = Table.read(pos_list.readlines(),
106-
names=['ra', 'dec'],
107106
format='ascii.csv',
108107
guess=False)
109108
response = xm.query_async(
110-
cat1=input_table, cat2='vizier:II/246/out', max_distance=5 * arcsec)
109+
cat1=input_table, cat2='vizier:II/246/out', max_distance=5 * arcsec,
110+
colRA1='ra', colDec1='dec')
111111
table = ascii.read(response.text, format='csv')
112112
assert isinstance(table, Table)
113113
assert table.colnames == [
114-
'angDist', 'ra', 'dec', '2MASS', 'RAJ2000', 'DEJ2000',
114+
'angDist', 'ra', 'dec', 'my_id', '2MASS', 'RAJ2000', 'DEJ2000',
115115
'errHalfMaj', 'errHalfMin', 'errPosAng', 'Jmag', 'Hmag', 'Kmag',
116116
'e_Jmag', 'e_Hmag', 'e_Kmag', 'Qfl', 'Rfl', 'X', 'MeasureJD']
117117
assert len(table) == 11

astroquery/xmatch/tests/test_xmatch_remote.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ def test_xmatch_avail_tables(xmatch):
3232
def test_xmatch_is_avail_table(xmatch):
3333
assert xmatch.is_table_available('II/311/wise')
3434
assert xmatch.is_table_available('II/246/out')
35-
assert not xmatch.is_table_available('vizier:II/311/wise')
35+
assert xmatch.is_table_available('vizier:II/311/wise')
36+
assert not xmatch.is_table_available('blablabla')
3637

3738

3839
@remote_data
@@ -43,7 +44,7 @@ def test_xmatch_query(xmatch):
4344
colRA1='ra', colDec1='dec')
4445
assert isinstance(table, Table)
4546
assert table.colnames == [
46-
'angDist', 'ra', 'dec', '2MASS', 'RAJ2000', 'DEJ2000',
47+
'angDist', 'ra', 'dec', 'my_id', '2MASS', 'RAJ2000', 'DEJ2000',
4748
'errHalfMaj', 'errHalfMin', 'errPosAng', 'Jmag', 'Hmag', 'Kmag',
4849
'e_Jmag', 'e_Hmag', 'e_Kmag', 'Qfl', 'Rfl', 'X', 'MeasureJD']
4950
assert len(table) == 11
@@ -52,13 +53,13 @@ def test_xmatch_query(xmatch):
5253
@remote_data
5354
def test_xmatch_query_astropy_table(xmatch):
5455
datapath = os.path.join(DATA_DIR, 'posList.csv')
55-
input_table = Table.read(datapath, names=['ra', 'dec'],
56-
format='ascii.csv')
56+
input_table = Table.read(datapath, format='ascii.csv')
5757
table = xmatch.query(
58-
cat1=input_table, cat2='vizier:II/246/out', max_distance=5 * arcsec)
58+
cat1=input_table, cat2='vizier:II/246/out', max_distance=5 * arcsec,
59+
colRA1='ra', colDec1='dec')
5960
assert isinstance(table, Table)
6061
assert table.colnames == [
61-
'angDist', 'ra', 'dec', '2MASS', 'RAJ2000', 'DEJ2000',
62+
'angDist', 'ra', 'dec', 'my_id', '2MASS', 'RAJ2000', 'DEJ2000',
6263
'errHalfMaj', 'errHalfMin', 'errPosAng', 'Jmag', 'Hmag', 'Kmag',
6364
'e_Jmag', 'e_Hmag', 'e_Kmag', 'Qfl', 'Rfl', 'X', 'MeasureJD']
6465
assert len(table) == 11

docs/xmatch/xmatch.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,11 @@ input file.
5757
0.853178 322.493 12.16703 21295836+1210007 ... EEA 222 0 2451080.6935
5858
4.50395 322.493 12.16703 21295861+1210023 ... EEE 222 0 2451080.6935
5959
60+
Reference/API
61+
=============
62+
63+
.. automodapi:: astroquery.xmatch
64+
:no-inheritance-diagram:
65+
6066

6167
.. _xMatch: http://cdsxmatch.u-strasbg.fr/xmatch/doc/

0 commit comments

Comments
 (0)