@@ -217,13 +217,14 @@ def list_wildcards():
217
217
def list_votable_fields (self ):
218
218
"""List all options to add columns to SIMBAD's output.
219
219
220
- They are of three types:
220
+ They are of four types:
221
221
222
222
- "column of basic": a column of the basic table. There fields can also be explored with
223
223
`~astroquery.simbad.SimbadClass.list_columns`.
224
224
- "table": a table other than basic that has a declared direct join
225
225
- "bundle of basic columns": a pre-selected bundle of columns of basic. Ex: "parallax" will add all
226
226
columns relevant to parallax
227
+ - "filter name": an optical filter name
227
228
228
229
Examples
229
230
--------
@@ -266,8 +267,11 @@ def list_votable_fields(self):
266
267
"description" : [value ["description" ] for _ , value in bundle_entries .items ()],
267
268
"type" : ["bundle of basic columns" ] * len (bundle_entries )},
268
269
dtype = ["object" , "object" , "object" ])
269
- # vstack the three types of options
270
- return vstack ([tables , basic_columns , bundles ], metadata_conflicts = "silent" )
270
+ # get the filter names
271
+ filters = self .query_tap ("SELECT filtername AS name, description FROM filter" )
272
+ filters ["type" ] = Column (["filter name" ] * len (filters ), dtype = "object" )
273
+ # vstack the four types of options
274
+ return vstack ([tables , basic_columns , bundles , filters ], metadata_conflicts = "silent" )
271
275
272
276
def _get_bundle_columns (self , bundle_name ):
273
277
"""Get the list of columns in the preselected bundles.
@@ -324,11 +328,17 @@ def _add_table_to_output(self, table):
324
328
"query to be written and called with 'SimbadClass.query_tap'." )
325
329
326
330
columns = list (self .list_columns (table )["column_name" ])
327
- columns = [column .casefold () for column in columns if column not in {"oidref" , "oidbibref" }]
328
331
329
- # the alias is mandatory to be able to distinguish between duplicates like
330
- # mesDistance.bibcode and mesDiameter.bibcode.
331
- alias = [f'"{ table } .{ column } "' if not column .startswith (table ) else None for column in columns ]
332
+ # allfluxes is the only case-dependent table
333
+ if table == "allfluxes" :
334
+ columns = [column for column in columns if column not in {"oidref" , "oidbibref" }]
335
+ alias = [column .replace ("_" , "" ) if "_" in column else None
336
+ for column in columns ]
337
+ else :
338
+ columns = [column .casefold () for column in columns if column not in {"oidref" , "oidbibref" }]
339
+ # the alias is mandatory to be able to distinguish between duplicates like
340
+ # mesDistance.bibcode and mesDiameter.bibcode.
341
+ alias = [f"{ table } .{ column } " if not column .startswith (table ) else None for column in columns ]
332
342
333
343
# modify the attributes here
334
344
self .columns_in_output += [_Column (table , column , alias )
@@ -366,27 +376,43 @@ def add_votable_fields(self, *args):
366
376
['basic.main_id', 'basic.ra', 'basic.dec', 'basic.coo_err_maj', 'basic.coo_err_min', ...
367
377
"""
368
378
369
- # the legacy way of adding fluxes is the only case-dependant option
379
+ # the legacy way of adding fluxes
370
380
args = list (args )
381
+ fluxes_to_add = []
371
382
for arg in args :
383
+ if arg .startswith ("flux_" ):
384
+ raise ValueError ("The votable fields 'flux_***(filtername)' are removed and replaced "
385
+ "by 'flux' that will add all information for every filters. "
386
+ "See section on filters in "
387
+ "https://astroquery.readthedocs.io/en/latest/simbad/simbad_evolution.html"
388
+ " to see the new ways to interact with SIMBAD's fluxes." )
372
389
if re .match (r"^flux.*\(.+\)$" , arg ):
373
- warnings .warn ("The notation 'flux(X )' is deprecated since 0.4.8. "
390
+ warnings .warn ("The notation 'flux(U )' is deprecated since 0.4.8 in favor of 'U' . "
374
391
"See section on filters in "
375
392
"https://astroquery.readthedocs.io/en/latest/simbad/simbad_evolution.html "
376
- "to see how it can be replaced." , DeprecationWarning , stacklevel = 2 )
377
- flux_filter = re .findall (r"\((\w+)\)" , arg )[0 ]
378
- if len (flux_filter ) == 1 and flux_filter .islower ():
379
- flux_filter = flux_filter + "_"
380
- self .joins .append (_Join ("allfluxes" , _Column ("basic" , "oid" ),
381
- _Column ("allfluxes" , "oidref" )))
382
- self .columns_in_output .append (_Column ("allfluxes" , flux_filter ))
393
+ "to see the new ways to interact with SIMBAD's fluxes." , DeprecationWarning , stacklevel = 2 )
394
+ fluxes_to_add .append (re .findall (r"\((\w+)\)" , arg )[0 ])
383
395
args .remove (arg )
384
396
385
- # casefold args
386
- args = set (map (str .casefold , args ))
387
-
388
397
# output options
389
398
output_options = self .list_votable_fields ()
399
+ # fluxes are case-dependant
400
+ fluxes = output_options [output_options ["type" ] == "filter name" ]["name" ]
401
+ # add fluxes
402
+ fluxes_to_add += [flux for flux in args if flux in fluxes ]
403
+ if fluxes_to_add :
404
+ self .joins .append (_Join ("allfluxes" , _Column ("basic" , "oid" ),
405
+ _Column ("allfluxes" , "oidref" )))
406
+ for flux in fluxes_to_add :
407
+ if len (flux ) == 1 and flux .islower ():
408
+ # the name in the allfluxes view has a trailing underscore. This is not
409
+ # the case in the list of filter names, so we homogenize with an alias
410
+ self .columns_in_output .append (_Column ("allfluxes" , flux + "_" , flux ))
411
+ else :
412
+ self .columns_in_output .append (_Column ("allfluxes" , flux ))
413
+
414
+ # casefold args because we allow case difference for every other argument (legacy behavior)
415
+ args = set (map (str .casefold , args ))
390
416
output_options ["name" ] = list (map (str .casefold , list (output_options ["name" ])))
391
417
basic_columns = output_options [output_options ["type" ] == "column of basic" ]["name" ]
392
418
all_tables = output_options [output_options ["type" ] == "table" ]["name" ]
@@ -1374,7 +1400,7 @@ def _query(self, top, columns, joins, criteria, from_table="basic",
1374
1400
top = f" TOP { top } " if top != - 1 else ""
1375
1401
1376
1402
# columns
1377
- input_columns = [f'{ column .table } ."{ column .name } " AS { column .alias } ' if column .alias is not None
1403
+ input_columns = [f'{ column .table } ."{ column .name } " AS " { column .alias } " ' if column .alias is not None
1378
1404
else f'{ column .table } ."{ column .name } "' for column in columns ]
1379
1405
# remove possible duplicates
1380
1406
unique_columns = []
@@ -1391,7 +1417,7 @@ def _query(self, top, columns, joins, criteria, from_table="basic",
1391
1417
[unique_joins .append (join ) for join in joins if join not in unique_joins ]
1392
1418
join = " " + " " .join ([(f'{ join .join_type } { join .table } ON { join .column_left .table } ."'
1393
1419
f'{ join .column_left .name } " = { join .column_right .table } ."'
1394
- f'{ join .column_right .name } "' ) for join in joins ])
1420
+ f'{ join .column_right .name } "' ) for join in unique_joins ])
1395
1421
1396
1422
# criteria
1397
1423
if criteria != []:
0 commit comments