Skip to content

Commit db597e6

Browse files
committed
Xmatch: allow astropy tables input iwht more than 2 columns
Before this patch astropy tables as input could only have exactly two columns that would be exactly in the order RA, DEC. That is a bad design for two reasons: - What is the order of the columns is different. - After cross-matching, how do I know which object is which? Two RA/DEC columns are fine if I want to answer the question "What are the counterparts in catalog 2?" but not if I want to retrieve a joint catalog (e.g. I have my own optical data in cat1 and cross-match with 2MASS, then I want all mags in the returned catalog.
1 parent 9a2d1a2 commit db597e6

File tree

5 files changed

+61
-71
lines changed

5 files changed

+61
-71
lines changed

astroquery/xmatch/core.py

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@ def query(self, cat1, cat2, max_distance, colRA1=None,
3333
If the table is uploaded or accessed through a URL, it must be
3434
in VOTable or CSV format with the positions in J2000
3535
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!
39-
cat2 : str or file
36+
cat2 : str or file
4037
Identifier of the second table. Follows the same rules as *cat1*.
4138
max_distance : `~astropy.units.arcsec`
4239
Maximum distance in arcsec to look for counterparts.
@@ -84,57 +81,49 @@ def query_async(
8481
'RESPONSEFORMAT': 'csv',
8582
}
8683
kwargs = {}
87-
if isinstance(cat1, six.string_types):
88-
payload['cat1'] = cat1
89-
elif isinstance(cat1, Table):
90-
payload['colRA1'], payload['colDec1'] = cat1.colnames
84+
85+
self._prepare_sending_table(1, payload, kwargs, cat1, colRA1, colDec1)
86+
self._prepare_sending_table(2, payload, kwargs, cat2, colRA2, colDec2)
87+
88+
response = commons.send_request(
89+
self.URL, payload, self.TIMEOUT, **kwargs)
90+
return response
91+
92+
def _prepare_sending_table(self, i, payload, kwargs, cat, colRA, colDec):
93+
'''Check if table is a string, a `astropy.table.Table`, etc. and set
94+
query parameters accordingly.
95+
'''
96+
catstr = 'cat{0}'.format(i)
97+
if isinstance(cat, six.string_types):
98+
payload[catstr] = cat
99+
elif isinstance(cat, Table):
91100
# write the Table's content into a new, temporary CSV-file
92101
# so that it can be pointed to via the `files` option
93102
# file will be closed when garbage-collected
94103
fp = six.StringIO()
95-
cat1.write(fp, format='ascii.csv')
104+
cat.write(fp, format='ascii.csv')
96105
fp.seek(0)
97-
kwargs['files'] = {'cat1': fp}
106+
kwargs['files'] = {catstr: fp}
98107
else:
99108
# 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:
109+
kwargs['files'] = {catstr: cat}
110+
if not self.is_table_available(cat):
111+
if ((colRA is None) or (colDec is None)):
112+
raise ValueError('Specify the name of the RA/Dec columns in' +
113+
' the input table.')
104114
# if `cat1` is not a VizieR table,
105115
# 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
116+
payload['colRA{0}'.format(i)] = colRA
117+
payload['colDec{0}'.format(i)] = colDec
118+
132119

133120
def is_table_available(self, table_id):
134121
"""Return True if the passed CDS table identifier is one of the
135122
available VizieR tables, otherwise False.
136123
137124
"""
125+
if isinstance(table_id, six.string_types) and (table_id[:7] == 'vizier:'):
126+
table_id = table_id[7:]
138127
return table_id in self.get_available_tables()
139128

140129
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

0 commit comments

Comments
 (0)