Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge hips2fits to Master #98

Merged
merged 2 commits into from
Jul 31, 2024
Merged
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
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
"execute": "never"
}
},
"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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
"ruff check --fix"
],
"*ipynb":
"python3 -m jupyter nbconvert --clear-output --ClearMetadataPreprocessor.enabled=True --ClearMetadataPreprocessor.preserve_cell_metadata_mask='[(\"nbsphinx\")]' --inplace"
"python3 -m jupyter nbconvert --clear-output --ClearMetadataPreprocessor.enabled=True --ClearMetadataPreprocessor.preserve_nb_metadata_mask=nbsphinx --inplace"
}
}
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
Loading