Skip to content

Commit 1019f72

Browse files
Merge pull request #64 from Caltech-IPAC/FIREFLY-1623-tbl-api
FIREFLY-1623: Improve python API for tables
2 parents d2018de + 9383656 commit 1019f72

File tree

5 files changed

+128
-13
lines changed

5 files changed

+128
-13
lines changed

docs/reference.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ API reference
44

55
.. automodapi:: firefly_client
66
:no-inheritance-diagram:
7-
:no-heading:
8-
7+
:skip: PackageNotFoundError, Env, FFWs, RangeValues

docs/usage/displaying-images.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,15 @@ It is possible to create a 3-color composite image using a list of dictionaries
221221
fc.show_fits_3color(threeC,
222222
plot_id='wise_m101',
223223
viewer_id='3C')
224+
225+
226+
Displaying Image from a URL
227+
---------------------------
228+
229+
If you have the URL of an image, you can pass it directly instead of
230+
downloading it and then uploading it to firefly:
231+
232+
.. code-block:: py
233+
234+
image_url = 'http://irsa.ipac.caltech.edu/ibe/data/wise/allsky/4band_p1bm_frm/6a/02206a/149/02206a149-w1-int-1b.fits?center=70,20&size=200pix'
235+
fc.show_fits(url=image_url, plot_id='wise-allsky', title='WISE all-sky')

docs/usage/viewing-tables.rst

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
###############################
12
Visualizing Tables and Catalogs
2-
-------------------------------
3+
###############################
34

45
Tables can be uploaded to the Firefly server with :meth:`FireflyClient.upload_file`,
56
and displayed in a table viewer component with :meth:`FireflyClient.show_table`.
@@ -11,18 +12,60 @@ if the table contains recognizable celestial coordinates.
1112
tval = fc.upload_file('m31-2mass-2412-row.tbl')
1213
fc.show_table(file_on_server=tval, tbl_id='m31-table')
1314
15+
Modifying Table Display Parameters
16+
----------------------------------
17+
1418
If it is desired to overlay the table on an image, or to make plots from it,
1519
without showing the table in the viewer, use :meth:`FireflyClient.fetch_table`:
1620

1721
.. code-block:: py
1822
1923
fc.fetch_table(file_on_server=tval, tbl_id='invisible-table')
2024
25+
Alternatively, you can turn off the `visible` parameter in :meth:`FireflyClient.show_table`:
26+
27+
.. code-block:: py
28+
29+
fc.show_table(file_on_server=tval, tbl_id='invisible-table', visible=False)
30+
2131
If the table does not contain celestial coordinates recognized by Firefly,
22-
the image overlay will not appear. BUt if you specifically do not want
23-
the table overlaid on the image, `is_catalog=False` can be specified:
32+
the image overlay will not appear. But if you specifically do not want
33+
the table overlaid on the image, `is_catalog=False` can be specified (it is
34+
`True` by default):
2435

2536
.. code-block:: py
2637
2738
fc.show_table(file_on_server=tval, tbl_id='2mass-tbl', is_catalog=False)
2839
40+
41+
Displaying Table from a URL
42+
---------------------------
43+
44+
If you have the URL of a table, you can pass it directly instead of
45+
downloading it and then uploading it to firefly:
46+
47+
.. code-block:: py
48+
49+
table_url = "http://irsa.ipac.caltech.edu/TAP/sync?FORMAT=IPAC_TABLE&QUERY=SELECT+*+FROM+fp_psc+WHERE+CONTAINS(POINT('J2000',ra,dec),CIRCLE('J2000',70.0,20.0,0.1))=1"
50+
tbl_id_2mass_psc = '2mass-point-source-catalog'
51+
fc.show_table(url=table_url, tbl_id=tbl_id_2mass_psc)
52+
53+
Filtering/Sorting a loaded Table
54+
--------------------------------
55+
56+
After displaying a table in firefly, you can also apply filters on it.
57+
You will need to pass the `tbl_id` of that table and specify `filters` as an
58+
SQL WHERE clause-like string with column names quoted:
59+
60+
.. code-block:: py
61+
62+
fc.apply_table_filters(tbl_id=tbl_id_2mass_psc, filters='"j_m">15 and "j_m"<16 and "j_cmsig"<0.06')
63+
64+
You can sort the table by a column in ascending (`ASC`) or descending (`DESC`)
65+
order:
66+
67+
.. code-block:: py
68+
69+
fc.sort_table_column(tbl_id=tbl_id_2mass_psc, column_name='j_m', sort_direction='ASC')
70+
71+
If a column has sorting, it can be removed by specifying `sort_direction=''`.

firefly_client/fc_utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ def ensure3(val, name):
7070
'AddExtension': 'ExternalAccessCntlr/extensionAdd',
7171
'FetchTable': 'table.fetch',
7272
'ShowTable': 'table.search',
73+
'TableFilter': 'table.filter',
74+
'TableSort': 'table.sort',
7375
'ShowXYPlot': 'charts.data/chartAdd',
7476
'ShowPlot': 'charts.data/chartAdd',
7577
'ZoomImage': 'ImagePlotCntlr.ZoomImage',

firefly_client/firefly_client.py

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,8 @@ def show_fits(self, file_on_server=None, plot_id=None, viewer_id=None, **additio
732732
Display only a particular image extension from the file (zero-based index).
733733
**Title** : `str`, optional
734734
Title to display with the image.
735+
**url** : `str`, optional
736+
URL of the fits image file, if it's not a local file you can upload.
735737
736738
Returns
737739
-------
@@ -803,18 +805,20 @@ def show_fits_3color(self, three_color_params, plot_id=None, viewer_id=None):
803805
warning and r.update({'warning': warning})
804806
return r
805807

806-
def show_table(self, file_on_server=None, tbl_id=None, title=None, page_size=100, is_catalog=True,
808+
def show_table(self, file_on_server=None, url=None, tbl_id=None, title=None, page_size=100, is_catalog=True,
807809
meta=None, target_search_info=None, options=None, table_index=None,
808810
column_spec=None, filters=None, visible=True):
809811
"""
810812
Show a table.
811813
812814
Parameters
813815
----------
814-
file_on_server : `str`
816+
file_on_server : `str`, optional
815817
The name of the file on the server.
816818
If you use `upload_file()`, then it is the return value of the method. Otherwise it is a file that
817819
Firefly has direct access to.
820+
url : `str`, optional
821+
URL of the table file, if it's not a local file you can upload.
818822
tbl_id : `str`, optional
819823
A table ID. It will be created automatically if not specified.
820824
title : `str`, optional
@@ -872,28 +876,32 @@ def show_table(self, file_on_server=None, tbl_id=None, title=None, page_size=100
872876
A string specifying filters. Column names must be quoted.
873877
For example, '("coord_dec" > -0.478) and ("parent" > 0)'.
874878
visible: `bool`, optional
875-
If false, only load the table to Firefly but don't show it in the UI
879+
If false, only load the table to Firefly but don't show it in the UI.
880+
Similar to `fetch_table()`
876881
877882
Returns
878883
-------
879884
out : `dict`
880885
Status of the request, like {'success': True}.
881886
882-
.. note:: `file_on_server` and `target_search_info` are exclusively required.
887+
.. note:: `url`, `file_on_server`, and `target_search_info` are exclusively required.
888+
If more than one of these 3 parameters are passed, precedence order is:
889+
`url` > `file_on_server` > `target_search_info`
883890
"""
884891

885892
if not tbl_id:
886893
tbl_id = gen_item_id('Table')
887894
if not title:
888-
title = tbl_id if file_on_server else target_search_info.get('catalog', tbl_id)
895+
title = tbl_id if file_on_server or url else target_search_info.get('catalog', tbl_id)
889896

890897
meta_info = {'title': title, 'tbl_id': tbl_id}
891898
meta and meta_info.update(meta)
892899

893900
tbl_req = {'startIdx': 0, 'pageSize': page_size, 'tbl_id': tbl_id}
894-
if file_on_server:
901+
if file_on_server or url:
895902
tbl_type = 'table' if not is_catalog else 'catalog'
896-
tbl_req.update({'source': file_on_server, 'tblType': tbl_type,
903+
source = url if url else file_on_server
904+
tbl_req.update({'source': source, 'tblType': tbl_type,
897905
'id': 'IpacTableFromSource'})
898906
table_index and tbl_req.update({'tbl_index': table_index})
899907
elif target_search_info:
@@ -941,7 +949,6 @@ def fetch_table(self, file_on_server, tbl_id=None, title=None, page_size=1, tabl
941949
out : `dict`
942950
Status of the request, like {'success': True}.
943951
"""
944-
945952
if not tbl_id:
946953
tbl_id = gen_item_id('Table')
947954
if not title:
@@ -1908,3 +1915,55 @@ def remove_mask(self, plot_id, mask_id):
19081915

19091916
payload = {'plotId': plot_id, 'imageOverlayId': mask_id}
19101917
return self.dispatch(ACTION_DICT['DeleteOverlayMask'], payload)
1918+
1919+
# ----------------------------
1920+
# actions on table
1921+
# ----------------------------
1922+
1923+
def apply_table_filters(self, tbl_id, filters):
1924+
"""
1925+
Apply filters to a loaded table.
1926+
1927+
Parameters
1928+
----------
1929+
plot_id : `str`
1930+
ID of the table where you want to apply filters
1931+
filters : `str`
1932+
SQL WHERE clause-like string specifying filters. Column names must be quoted.
1933+
For e.g. '("ra" > 185 AND "ra" < 185.1) OR ("dec" > 15 AND "dec" < 15.1) AND "band" IN (1,2)'.
1934+
1935+
Returns
1936+
--------
1937+
out : `dict`
1938+
Status of the request, like {'success': True}
1939+
"""
1940+
tbl_req = {'tbl_id': tbl_id, 'filters': filters}
1941+
payload = {'request': tbl_req}
1942+
return self.dispatch(ACTION_DICT['TableFilter'], payload)
1943+
1944+
def sort_table_column(self, tbl_id, column_name, sort_direction=''):
1945+
"""
1946+
Sort a loaded table by a given column name.
1947+
1948+
Parameters
1949+
----------
1950+
plot_id : `str`
1951+
ID of the table where you want to apply sort
1952+
column_name : `str`
1953+
Name of the table column to sort
1954+
sort_direction : {'', 'ASC', 'DESC'}, optional
1955+
Direction of sort: '' for unsorted (or for removing the sort),
1956+
'ASC' for ascending, and 'DESC' for descending. Default is ''.
1957+
1958+
Returns
1959+
--------
1960+
out : `dict`
1961+
Status of the request, like {'success': True}
1962+
"""
1963+
sort_directions = ['', 'ASC', 'DESC']
1964+
if sort_direction not in sort_directions:
1965+
raise ValueError(f'Invalid sort_direction. Valid values are {sort_directions}')
1966+
1967+
tbl_req = {'tbl_id': tbl_id, 'sortInfo': f'{sort_direction},{column_name}'}
1968+
payload = {'request': tbl_req}
1969+
return self.dispatch(ACTION_DICT['TableSort'], payload)

0 commit comments

Comments
 (0)