Skip to content

Commit

Permalink
Merge pull request #64 from Caltech-IPAC/FIREFLY-1623-tbl-api
Browse files Browse the repository at this point in the history
FIREFLY-1623: Improve python API for tables
  • Loading branch information
jaladh-singhal authored Dec 12, 2024
2 parents d2018de + 9383656 commit 1019f72
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 13 deletions.
3 changes: 1 addition & 2 deletions docs/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ API reference

.. automodapi:: firefly_client
:no-inheritance-diagram:
:no-heading:

:skip: PackageNotFoundError, Env, FFWs, RangeValues
12 changes: 12 additions & 0 deletions docs/usage/displaying-images.rst
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,15 @@ It is possible to create a 3-color composite image using a list of dictionaries
fc.show_fits_3color(threeC,
plot_id='wise_m101',
viewer_id='3C')
Displaying Image from a URL
---------------------------

If you have the URL of an image, you can pass it directly instead of
downloading it and then uploading it to firefly:

.. code-block:: py
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'
fc.show_fits(url=image_url, plot_id='wise-allsky', title='WISE all-sky')
49 changes: 46 additions & 3 deletions docs/usage/viewing-tables.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
###############################
Visualizing Tables and Catalogs
-------------------------------
###############################

Tables can be uploaded to the Firefly server with :meth:`FireflyClient.upload_file`,
and displayed in a table viewer component with :meth:`FireflyClient.show_table`.
Expand All @@ -11,18 +12,60 @@ if the table contains recognizable celestial coordinates.
tval = fc.upload_file('m31-2mass-2412-row.tbl')
fc.show_table(file_on_server=tval, tbl_id='m31-table')
Modifying Table Display Parameters
----------------------------------

If it is desired to overlay the table on an image, or to make plots from it,
without showing the table in the viewer, use :meth:`FireflyClient.fetch_table`:

.. code-block:: py
fc.fetch_table(file_on_server=tval, tbl_id='invisible-table')
Alternatively, you can turn off the `visible` parameter in :meth:`FireflyClient.show_table`:

.. code-block:: py
fc.show_table(file_on_server=tval, tbl_id='invisible-table', visible=False)
If the table does not contain celestial coordinates recognized by Firefly,
the image overlay will not appear. BUt if you specifically do not want
the table overlaid on the image, `is_catalog=False` can be specified:
the image overlay will not appear. But if you specifically do not want
the table overlaid on the image, `is_catalog=False` can be specified (it is
`True` by default):

.. code-block:: py
fc.show_table(file_on_server=tval, tbl_id='2mass-tbl', is_catalog=False)
Displaying Table from a URL
---------------------------

If you have the URL of a table, you can pass it directly instead of
downloading it and then uploading it to firefly:

.. code-block:: py
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"
tbl_id_2mass_psc = '2mass-point-source-catalog'
fc.show_table(url=table_url, tbl_id=tbl_id_2mass_psc)
Filtering/Sorting a loaded Table
--------------------------------

After displaying a table in firefly, you can also apply filters on it.
You will need to pass the `tbl_id` of that table and specify `filters` as an
SQL WHERE clause-like string with column names quoted:

.. code-block:: py
fc.apply_table_filters(tbl_id=tbl_id_2mass_psc, filters='"j_m">15 and "j_m"<16 and "j_cmsig"<0.06')
You can sort the table by a column in ascending (`ASC`) or descending (`DESC`)
order:

.. code-block:: py
fc.sort_table_column(tbl_id=tbl_id_2mass_psc, column_name='j_m', sort_direction='ASC')
If a column has sorting, it can be removed by specifying `sort_direction=''`.
2 changes: 2 additions & 0 deletions firefly_client/fc_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ def ensure3(val, name):
'AddExtension': 'ExternalAccessCntlr/extensionAdd',
'FetchTable': 'table.fetch',
'ShowTable': 'table.search',
'TableFilter': 'table.filter',
'TableSort': 'table.sort',
'ShowXYPlot': 'charts.data/chartAdd',
'ShowPlot': 'charts.data/chartAdd',
'ZoomImage': 'ImagePlotCntlr.ZoomImage',
Expand Down
75 changes: 67 additions & 8 deletions firefly_client/firefly_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,8 @@ def show_fits(self, file_on_server=None, plot_id=None, viewer_id=None, **additio
Display only a particular image extension from the file (zero-based index).
**Title** : `str`, optional
Title to display with the image.
**url** : `str`, optional
URL of the fits image file, if it's not a local file you can upload.
Returns
-------
Expand Down Expand Up @@ -803,18 +805,20 @@ def show_fits_3color(self, three_color_params, plot_id=None, viewer_id=None):
warning and r.update({'warning': warning})
return r

def show_table(self, file_on_server=None, tbl_id=None, title=None, page_size=100, is_catalog=True,
def show_table(self, file_on_server=None, url=None, tbl_id=None, title=None, page_size=100, is_catalog=True,
meta=None, target_search_info=None, options=None, table_index=None,
column_spec=None, filters=None, visible=True):
"""
Show a table.
Parameters
----------
file_on_server : `str`
file_on_server : `str`, optional
The name of the file on the server.
If you use `upload_file()`, then it is the return value of the method. Otherwise it is a file that
Firefly has direct access to.
url : `str`, optional
URL of the table file, if it's not a local file you can upload.
tbl_id : `str`, optional
A table ID. It will be created automatically if not specified.
title : `str`, optional
Expand Down Expand Up @@ -872,28 +876,32 @@ def show_table(self, file_on_server=None, tbl_id=None, title=None, page_size=100
A string specifying filters. Column names must be quoted.
For example, '("coord_dec" > -0.478) and ("parent" > 0)'.
visible: `bool`, optional
If false, only load the table to Firefly but don't show it in the UI
If false, only load the table to Firefly but don't show it in the UI.
Similar to `fetch_table()`
Returns
-------
out : `dict`
Status of the request, like {'success': True}.
.. note:: `file_on_server` and `target_search_info` are exclusively required.
.. note:: `url`, `file_on_server`, and `target_search_info` are exclusively required.
If more than one of these 3 parameters are passed, precedence order is:
`url` > `file_on_server` > `target_search_info`
"""

if not tbl_id:
tbl_id = gen_item_id('Table')
if not title:
title = tbl_id if file_on_server else target_search_info.get('catalog', tbl_id)
title = tbl_id if file_on_server or url else target_search_info.get('catalog', tbl_id)

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

tbl_req = {'startIdx': 0, 'pageSize': page_size, 'tbl_id': tbl_id}
if file_on_server:
if file_on_server or url:
tbl_type = 'table' if not is_catalog else 'catalog'
tbl_req.update({'source': file_on_server, 'tblType': tbl_type,
source = url if url else file_on_server
tbl_req.update({'source': source, 'tblType': tbl_type,
'id': 'IpacTableFromSource'})
table_index and tbl_req.update({'tbl_index': table_index})
elif target_search_info:
Expand Down Expand Up @@ -941,7 +949,6 @@ def fetch_table(self, file_on_server, tbl_id=None, title=None, page_size=1, tabl
out : `dict`
Status of the request, like {'success': True}.
"""

if not tbl_id:
tbl_id = gen_item_id('Table')
if not title:
Expand Down Expand Up @@ -1908,3 +1915,55 @@ def remove_mask(self, plot_id, mask_id):

payload = {'plotId': plot_id, 'imageOverlayId': mask_id}
return self.dispatch(ACTION_DICT['DeleteOverlayMask'], payload)

# ----------------------------
# actions on table
# ----------------------------

def apply_table_filters(self, tbl_id, filters):
"""
Apply filters to a loaded table.
Parameters
----------
plot_id : `str`
ID of the table where you want to apply filters
filters : `str`
SQL WHERE clause-like string specifying filters. Column names must be quoted.
For e.g. '("ra" > 185 AND "ra" < 185.1) OR ("dec" > 15 AND "dec" < 15.1) AND "band" IN (1,2)'.
Returns
--------
out : `dict`
Status of the request, like {'success': True}
"""
tbl_req = {'tbl_id': tbl_id, 'filters': filters}
payload = {'request': tbl_req}
return self.dispatch(ACTION_DICT['TableFilter'], payload)

def sort_table_column(self, tbl_id, column_name, sort_direction=''):
"""
Sort a loaded table by a given column name.
Parameters
----------
plot_id : `str`
ID of the table where you want to apply sort
column_name : `str`
Name of the table column to sort
sort_direction : {'', 'ASC', 'DESC'}, optional
Direction of sort: '' for unsorted (or for removing the sort),
'ASC' for ascending, and 'DESC' for descending. Default is ''.
Returns
--------
out : `dict`
Status of the request, like {'success': True}
"""
sort_directions = ['', 'ASC', 'DESC']
if sort_direction not in sort_directions:
raise ValueError(f'Invalid sort_direction. Valid values are {sort_directions}')

tbl_req = {'tbl_id': tbl_id, 'sortInfo': f'{sort_direction},{column_name}'}
payload = {'request': tbl_req}
return self.dispatch(ACTION_DICT['TableSort'], payload)

0 comments on commit 1019f72

Please sign in to comment.