One of the topics on the near-term development list for the Firefly Python API was associated with providing Python access to the highlighting and selection of rows in a Firefly table.
(For non-Firefly-geeks reading this: "highlighting" is what happens when a row in the table viewer or a corresponding data point in a plot or image overlay is clicked. "Selection" refers to the activation of the checkbox displayed at the head of a row in the table viewer; this can also be achieved by the use of the "check mark" button in a plot based on the region-selection tools. Only one row can be "highlighted" at a time, whereas multiple rows may be "selected"/checked. We are planning to rethink the UI mechanics of all of this at a later date.)
David Shupe and I discussed this at length yesterday. We propose the set of capabilities outlined below. Initially these would be provided in firefly_client. After exposing these to users, getting some feedback, and possibly rethinking, we would
It should be possible to use the Python API to receive a callback to a Python function when the highlight is changed.
It should be possible to configure the callback to return either the entire row or a specified subset of columns. It should be possible to request any table column by name, and it should also be possible to request the Firefly-assigned invariant row ID (the one that sticks to the original row even if the table is sorted or filtered).
It would be desirable, but perhaps not required at first, to also be able to request return the selection status (i.e., is the checkbox checked?) for the highlighted row.
The Python model for specifying the columns to be returned should be a Python set of column names as strings, e.g., an optional argument to the API for establishing the callback:
For the Firefly invariant row ID and for the checkbox status, however, I would suggest using a typed constant rather than a string, so that it would look something like:
David Shupe will comment on what the most Pythonic way to accomplish that would be. I do not want to depend on magic column names in Firefly for those attributes and make the user supply them as strings. (This is an area where it may be difficult to figure out how to put this into afw.display later on, as these concepts may not be present in other back ends.)
We are anticipating that the primary use case for this callback will be in cases where the table was originally loaded from Python and is still available in memory in the Python process, so the most natural and efficient way to implement a Python action driven by the Firefly selection may be to allow only some single column such as the "source ID" or "object ID" to be specified by the user to be returned, with the callback then using that to index into the tabular data it already has.
A slightly lower-priority use case for this will be where the table was initially loaded on the Portal (Firefly) side. In this case it may be more natural to transport all of the columns needed to implement whatever the callback action is. (But note that in this case it may not be obvious how to connect the callback to the correct table - how will the Python user know the tbl_id to use?)
The data structure returned should be, or at least include, a Python dict paralleling the Python set used in the configuration of the callback, e.g.:
This is the highest priority part of this ticket.
It should be possible to ask Firefly for the content of a loaded table, and after some discussion, we decided that the capability to request only the highlighted row, or the set of selected rows, should be integrated with this. We suggest that the API for requesting table content include optional arguments along the lines of:
The requested content could be returned as a list of dicts, preserving, if possible, the displayed sort order of the requested rows. If this is done, the dict returned for a row should have the same structure as for the one in the return to a highlight-callback function above.
However, since this is a bulk data interface, it may be more appropriate to consider using an existing Python data table model such as a Pandas DataFrame or an Astropy table.
Again, David Shupe will think about this a bit more and comment below.
This is the second priority part of the ticket, but should still be attempted as an August deliverable.
It should be possible, given a suitable primary key for a table - either the Firefly-assigned invariant row ID or a primary key internal to the table content - to request the matching row, and more generally it should be possible to request the set of rows matching a column predicate. (E.g., request all rows for which " filter_band = 'u' ". We should try to do this in a way that is as similar as possible to the way similar features are supported in other familiar Python APIs such as Pandas.
Note that since the internal Firefly tabular data model is a relational database table, ultimately an SQL WHERE clause could be supported for this API.
This is a substantially lower priority and can be deferred beyond August and to its own ticket. However, it should be implemented in a way compatible with the preceding API.
In addition to highlight-by-click and checkbox-selection, Firefly currently has a third way to identify data points for further action: drawing rectangles and circles, on images and/or on X-Y plots. It is possible to turn a set of points identified in this way into a (multi-row) "selection" with the "checkbox toolbar button" in the plotting UI. Firefly also makes it possible to extend the UI with buttons connected to optional actions.
It's a concern for user education that this is in fact a third selection-like mechanism in Firefly, and that's something we may want to address in future UX-improvement work.
In the mean time, it would be useful to make sure that the Firefly Python library does have good APIs for interaction with point-set identification of this nature.