Skip to content

Commit

Permalink
feat: Implement get_view_as_fits function
Browse files Browse the repository at this point in the history
🥅 Improve error management for hips2fits

📝 Add hips2fits example in notebook 2

📝 Move hips2fits example from notebook 2 to notebook 11

🎨 Improve error management for hips2fit and remove hips argument to take the Aladin Lite base layer survey

🐛 Change hips2fits return type to HDUList

✨ Synchronize survey traitlets to be changed on view change

🎨 Rename hips2fits function to get_view_as_fits

📝 Update changelog

docs: edit plot instructions

docs: edit method docs and exceptions messages
  • Loading branch information
Xen0Xys authored and ManonMarchand committed Jul 31, 2024
1 parent 85e6eae commit 719a7be
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 82 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
The method accepts `astropy.io.fits.HDUList`, `pathlib.Path`, or `string` representing paths (#86)
- New way to make a selection on the view with `selection` method (#100)
- Add selected sources export as `astropy.Table` list with property `selected_objects` (#100)
- Add function `get_view_as_fits` to export the view as a `astropy.io.fits.HDUList` (#86)

### Deprecated

Expand Down
2 changes: 1 addition & 1 deletion examples/02_Base_Commands.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also add a FITS image to the view of the widget, either as a path (string of pathlib.Path object) or as an\n",
"You can add a FITS image to the view of the widget, either as a path (string of pathlib.Path object) or as an\n",
"astropy HDU object."
]
},
Expand Down
138 changes: 63 additions & 75 deletions examples/11_Extracting_information_from_the_view.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,15 @@
"cell_type": "code",
"execution_count": null,
"id": "initial_id",
"metadata": {
"ExecuteTime": {
"end_time": "2024-07-24T07:31:43.806466Z",
"start_time": "2024-07-24T07:31:43.804047Z"
}
},
"metadata": {},
"outputs": [],
"source": [
"from astropy.coordinates import SkyCoord\n",
"import astropy.units as u\n",
"from astropy.wcs import WCS\n",
"from astroquery.simbad import Simbad\n",
"from astroquery.vizier import Vizier\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from ipyaladin import Aladin"
]
Expand All @@ -37,12 +34,7 @@
"cell_type": "code",
"execution_count": null,
"id": "2e62d34eb8543145",
"metadata": {
"ExecuteTime": {
"end_time": "2024-07-24T07:31:44.595633Z",
"start_time": "2024-07-24T07:31:44.580516Z"
}
},
"metadata": {},
"outputs": [],
"source": [
"aladin = Aladin(fov=5, height=600, target=\"M31\")\n",
Expand All @@ -63,12 +55,7 @@
"cell_type": "code",
"execution_count": null,
"id": "84153657cb7cd837",
"metadata": {
"ExecuteTime": {
"end_time": "2024-07-24T07:31:46.921817Z",
"start_time": "2024-07-24T07:31:46.915120Z"
}
},
"metadata": {},
"outputs": [],
"source": [
"aladin.wcs # Recover the current WCS"
Expand All @@ -86,12 +73,7 @@
"cell_type": "code",
"execution_count": null,
"id": "a63f210b-3a64-4860-8e70-42a4c66378fa",
"metadata": {
"ExecuteTime": {
"end_time": "2024-07-24T07:31:48.369339Z",
"start_time": "2024-07-24T07:31:48.361272Z"
}
},
"metadata": {},
"outputs": [],
"source": [
"aladin.height = 800\n",
Expand All @@ -113,12 +95,7 @@
"cell_type": "code",
"execution_count": null,
"id": "2ddc9637-b5c3-4412-8435-2302b6d86816",
"metadata": {
"ExecuteTime": {
"end_time": "2024-07-24T07:31:51.277841Z",
"start_time": "2024-07-24T07:31:51.271764Z"
}
},
"metadata": {},
"outputs": [],
"source": [
"aladin.wcs"
Expand All @@ -140,12 +117,7 @@
"cell_type": "code",
"execution_count": null,
"id": "9595ae02388b245a",
"metadata": {
"ExecuteTime": {
"end_time": "2024-07-24T07:31:53.400986Z",
"start_time": "2024-07-24T07:31:53.389449Z"
}
},
"metadata": {},
"outputs": [],
"source": [
"aladin.fov_xy # Recover the current field of view for the x and y axis"
Expand All @@ -164,12 +136,7 @@
"cell_type": "code",
"execution_count": null,
"id": "bb48cb19a597e262",
"metadata": {
"ExecuteTime": {
"end_time": "2024-07-24T07:31:55.769334Z",
"start_time": "2024-07-24T07:31:55.496270Z"
}
},
"metadata": {},
"outputs": [],
"source": [
"m1 = SkyCoord.from_name(\"m1\")\n",
Expand Down Expand Up @@ -207,12 +174,7 @@
"cell_type": "code",
"execution_count": null,
"id": "3efb33016d863bf7",
"metadata": {
"ExecuteTime": {
"end_time": "2024-07-24T07:31:58.508331Z",
"start_time": "2024-07-24T07:31:58.501683Z"
}
},
"metadata": {},
"outputs": [],
"source": [
"aladin.selection(\"circle\")"
Expand All @@ -230,41 +192,67 @@
"cell_type": "code",
"execution_count": null,
"id": "cda32891dd654568",
"metadata": {
"ExecuteTime": {
"end_time": "2024-07-24T07:32:07.757249Z",
"start_time": "2024-07-24T07:32:07.746282Z"
}
},
"metadata": {},
"outputs": [],
"source": [
"aladin.selected_objects"
]
},
{
"cell_type": "markdown",
"id": "c84e856d82dbde63",
"metadata": {},
"source": [
"## Getting the view as a fits file\n",
"The following method allow you to retrieve the current view as a fits file. If a `path` is given as a second argument, the fits file will be saved."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6b0d3e2131e9faa2",
"metadata": {},
"outputs": [],
"source": [
"fits = aladin.get_view_as_fits()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "020d2c7f",
"metadata": {},
"outputs": [],
"source": [
"fits[0].header"
]
},
{
"cell_type": "markdown",
"id": "36a996b424529c09",
"metadata": {},
"source": [
"Display the fits file using matplotlib:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8327802bad8e8c87",
"metadata": {},
"outputs": [],
"source": [
"wcs = WCS(fits[0].header)\n",
"\n",
"plt.subplot(projection=wcs)\n",
"plt.imshow(fits[0].data, cmap=\"binary_r\", norm=\"asinh\", vmin=0.001)"
]
}
],
"metadata": {
"nbsphinx": {
"execute": "never"
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.8"
},
"version_major": 2,
"version_minor": 0
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
Expand Down
13 changes: 7 additions & 6 deletions js/models/event_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ export default class EventHandler {
this.aladin.setFoV(fov);
});

this.aladin.on("layerChanged", (imageLayer, layerName, state) => {
if (layerName !== "base" || state !== "ADDED") return;
this.updateWCS();
this.model.set("_base_layer_last_view", imageLayer.id);
this.model.save_changes();
});

/* Div control */
this.model.on("change:_height", () => {
let height = this.model.get("_height");
Expand All @@ -151,12 +158,6 @@ export default class EventHandler {
this.model.save_changes();
});

this.aladin.on("layerChanged", (_, layerName, state) => {
if (layerName !== "base" || state !== "ADDED") return;
this.updateWCS();
this.model.save_changes();
});

this.aladin.on("resizeChanged", () => {
this.updateWCS();
this.update2AxisFoV();
Expand Down
39 changes: 39 additions & 0 deletions src/ipyaladin/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from collections.abc import Callable
import io
import pathlib
from json import JSONDecodeError
from pathlib import Path
from typing import ClassVar, Dict, Final, List, Optional, Tuple, Union
import warnings
Expand Down Expand Up @@ -205,6 +206,11 @@ class Aladin(anywidget.AnyWidget):
# overlay survey
overlay_survey = Unicode("").tag(sync=True, init_option=True)
overlay_survey_opacity = Float(0.0).tag(sync=True, init_option=True)
_base_layer_last_view = Unicode(
survey.default_value,
help="The last view of the base layer. It is used "
"to convert the view to an astropy.HDUList",
).tag(sync=True)

init_options = traitlets.List(trait=Any()).tag(sync=True)

Expand Down Expand Up @@ -376,6 +382,39 @@ def target(self, target: Union[str, SkyCoord]) -> None:
}
)

def get_view_as_fits(self) -> HDUList:
"""Get the base layer of the widget as an astropy HDUList object.
The output FITS image will have the same shape as the
current view of the widget. This uses `astroquery.hips2fits` internally.
This method currently only exports the bottom/base layer.
Returns
-------
astropy.io.fits.HDUList
The FITS object containing the image.
"""
try:
from astroquery.hips2fits import hips2fits
except ImportError as imp:
raise ValueError(
"To use the 'get_view_as_fits' method, you need to install astroquery "
"with 'pip install astroquery -U --pre'."
) from imp
try:
fits = hips2fits.query_with_wcs(
hips=self._base_layer_last_view,
wcs=self.wcs,
)
except JSONDecodeError as e:
raise ValueError(
"The FITS image could not be retrieved from the view. "
"This can happen when the widget is scrolled out of the "
"screen."
) from e
return fits

def add_catalog_from_URL(
self, votable_URL: str, votable_options: Optional[dict] = None
) -> None:
Expand Down

0 comments on commit 719a7be

Please sign in to comment.