Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions examples/14_Import_Astropy_Table.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "6b6dc38b-1941-4323-9990-f2caf2330325",
"metadata": {},
"source": [
"# Import Astropy Table\n",
"This notebook shows how you can import an astropy table as a selection region "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "04719ca3-019c-4806-9453-0564773099d0",
"metadata": {},
"outputs": [],
"source": [
"from ipyaladin import Aladin\n",
"\n",
"from astropy.coordinates import SkyCoord\n",
"from astroquery.mast import Catalogs"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cc554318-c26d-4f9e-8f2e-9fd1ec19a005",
"metadata": {},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "15efe516-e4e1-448c-a5bc-959215682254",
"metadata": {},
"outputs": [],
"source": [
"aladin = Aladin(\n",
" survey=\"SDSS9 colored\",\n",
" show_coo_grid=True,\n",
" target=\"TRAPPIST-1\",\n",
" coo_frame=\"icrs\",\n",
" fov=0.05,\n",
" height=400,\n",
" samp=True,\n",
")\n",
"aladin"
]
},
{
"cell_type": "markdown",
"id": "5892695a-9915-4835-bd8b-a6f9a049a496",
"metadata": {},
"source": [
"### Add a custom catalog\n",
"load a custom catalog that we want to select"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a8c9b374-ede2-46a1-95c1-6e44072dde20",
"metadata": {},
"outputs": [],
"source": [
"target_name = \"TRAPPIST-1\"\n",
"catalog_data = Catalogs.query_region(\n",
" coordinates=SkyCoord.from_name(target_name),\n",
" radius=0.01, # [deg]\n",
" catalog=\"Panstarrs\",\n",
")\n",
"catalog_data.rename_columns([\"raMean\", \"decMean\"], [\"ra\", \"dec\"])\n",
"\n",
"\n",
"aladin.add_table(\n",
" catalog_data, name=\"test-table\", color=\"lime\", shape=\"circle\", source_size=10\n",
")"
]
},
{
"cell_type": "markdown",
"id": "b1d279fc-7a46-4d7e-a4ae-1ff739a6c1a5",
"metadata": {},
"source": [
"Once the catalog is loaded, you can select all of the sources that match on the provided keys. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "67fcab46-281d-4012-bd09-d35652be8045",
"metadata": {},
"outputs": [],
"source": [
"aladin.select_table(catalog_data, keys=[\"objID\"])"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 5
}
2 changes: 2 additions & 0 deletions js/models/event_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ export default class EventHandler {
change_colormap: this.messageHandler.handleChangeColormap,
get_JPG_thumbnail: this.messageHandler.handleGetJPGThumbnail,
trigger_selection: this.messageHandler.handleTriggerSelection,
trigger_selection_by_table:
this.messageHandler.handleTriggerSelectionByTable,
add_table: this.messageHandler.handleAddTable,
};

Expand Down
21 changes: 21 additions & 0 deletions js/models/message_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,27 @@ export default class MessageHandler {
this.aladin.select(selectionType);
}

handleTriggerSelectionByTable(msg) {
let sources = msg["table"];
let keys = msg["keys"];
let sourcesByCatalog = this.aladin.view.catalogs
.map((cat) => {
if (!cat.isShowing) {
return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be clearer to explicitly return [].

}
return cat.getSources().filter((source) =>
sources.some((s) =>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found the name sources confusing here since they are very different from the getSources() and the source being filtered. Perhaps rename to indicate that they are the sources to be selected. This could tie in with a succinct comment or two here that clarify how the nested functions are filtering the lists.

I'd also be tempted to store the filter() result in a local variable and return that on a separate line. This could help the readability a little and would make any interactive debugging easier.

keys.every((key) => {
return s[key] == source.data[key];
}),
),
);
})
.filter((n) => n.length);
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: this filter statement is here to remove any empty lists that may be returned from the first filter statement. If there are multiple catalogs, and the key only matches on some of them, it will return something like the following

[
    [],     // empty list
    [ ... ] // list full of sources
]

The empty list needs to be removed for the selectObjects call to function properly

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like there is already enough happening with all the nested functions in the map() line. I would just do this last filter() on a new line preceded by a comment.


this.aladin.view.selectObjects(sourcesByCatalog);
}

handleAddTable(msg, buffers) {
const options = convertOptionNamesToCamelCase(msg["options"] || {});
const buffer = buffers[0].buffer;
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ docs = ["autoapi",
"sphinx-collections",
"sphinx-copybutton",
"sphinx-gallery",
"pydata-sphinx-theme"
"pydata-sphinx-theme",
"pandas"
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: we had to add pandas here since we are converting the astropy table to pandas in order to get the json safe dictionary of user defined keys to search on. This is the best way I've found to do this, but I'm open to any suggestions

]

# automatically add the dev feature to the default env (e.g., hatch shell)
Expand Down
21 changes: 21 additions & 0 deletions src/ipyaladin/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,27 @@ def selection(self, selection_type: str = "rectangle") -> None:
raise ValueError("selection_type must be 'circle' or 'rectangle'")
self.send({"event_name": "trigger_selection", "selection_type": selection_type})

def select_table(self, table: Table, keys: List[str]) -> None:
"""Trigger selection of sources included in the user defined table.

Parameters
----------
__________
table: Table
The astropy table containing the sources the user wishes to select.
keys: List[str]
The list of keys in the astropy table to use to identifiy a source.

"""
table_dict = table.to_pandas()[keys].to_dict("records")
self.send(
{
"event_name": "trigger_selection_by_table",
"table": table_dict,
"keys": keys,
}
)

def rectangular_selection(self) -> None:
"""Trigger the rectangular selection tool.

Expand Down