Skip to content

Commit

Permalink
Merge branch 'master' into feature/values-recovery
Browse files Browse the repository at this point in the history
  • Loading branch information
Xen0Xys authored Jul 16, 2024
2 parents 53dd798 + 1a61e29 commit 1506c18
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 13 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Allow WCS and 2 axis FoV recovery from `wcs` and `fov_xy` properties (#96)
- monochromatic FITS images can be added to the view with `ipyaladin.Aladin.add_fits`.
The method accepts `astropy.io.fits.HDUList`, `pathlib.Path`, or `string` representing paths (#86)

## [0.4.0]

Expand Down Expand Up @@ -47,7 +49,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Deprecate `add_overlay_from_stcs` in favor of `add_graphic_overlay_from_stcs` (#88)
- Deprecate the `add_listener` method for a preferred use of `set_listener` method (#82)


## [0.3.0]

### Changed
Expand Down
55 changes: 47 additions & 8 deletions examples/2_Base_Commands.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"metadata": {},
"outputs": [],
"source": [
"from ipyaladin import Aladin"
"from ipyaladin import Aladin\n",
"from pathlib import Path"
]
},
{
Expand Down Expand Up @@ -73,11 +74,18 @@
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"aladin.target"
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The x-axis field of view (fov) can be set"
]
},
{
Expand All @@ -100,6 +108,13 @@
"aladin.fov"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The overlay survey is always on top of the base layer"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -112,6 +127,13 @@
"aladin.overlay_survey_opacity = 0.5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can change the coordinate frame (the choices are `ICRS`, `ICRSd` or `Galactic`)."
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -136,17 +158,17 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Some commands can be used with astropy objects"
"The target and field of view can be set with astropy objects"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from astropy.coordinates import Angle, SkyCoord"
]
],
"outputs": [],
"execution_count": null
},
{
"cell_type": "code",
Expand All @@ -165,6 +187,23 @@
"source": [
"aladin.fov = Angle(5, \"deg\")"
]
},
{
"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",
"astropy HDU object."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"aladin.add_fits(Path(\"images/m31.fits\"), name=\"M31\", opacity=0.5)"
]
}
],
"metadata": {
Expand Down Expand Up @@ -193,4 +232,4 @@
},
"nbformat": 4,
"nbformat_minor": 4
}
}
1 change: 1 addition & 0 deletions js/models/event_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ export default class EventHandler {
this.eventHandlers = {
change_fov: this.messageHandler.handleChangeFoV,
goto_ra_dec: this.messageHandler.handleGotoRaDec,
add_fits: this.messageHandler.handleAddFits,
add_catalog_from_URL: this.messageHandler.handleAddCatalogFromURL,
add_MOC_from_URL: this.messageHandler.handleAddMOCFromURL,
add_MOC_from_dict: this.messageHandler.handleAddMOCFromDict,
Expand Down
17 changes: 17 additions & 0 deletions js/models/message_handler.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { convertOptionNamesToCamelCase } from "../utils";
import A from "../aladin_lite";

let imageCount = 0;

export default class MessageHandler {
constructor(aladin) {
this.aladin = aladin;
Expand All @@ -14,6 +16,21 @@ export default class MessageHandler {
this.aladin.gotoRaDec(msg["ra"], msg["dec"]);
}

handleAddFits(msg, buffers) {
const options = convertOptionNamesToCamelCase(msg["options"] || {});
if (!options.name)
options.name = `image_${String(++imageCount).padStart(3, "0")}`;
const buffer = buffers[0];
const blob = new Blob([buffer], { type: "application/octet-stream" });
const url = URL.createObjectURL(blob);
const image = this.aladin.createImageFITS(url, options, (ra, dec) => {
this.aladin.gotoRaDec(ra, dec);
console.info(`FITS located at ra: ${ra}, dec: ${dec}`);
URL.revokeObjectURL(url);
});
this.aladin.setOverlayImageLayer(image, options.name);
}

handleAddCatalogFromURL(msg) {
const options = convertOptionNamesToCamelCase(msg["options"] || {});
this.aladin.addCatalog(A.catalogFromURL(msg["votable_URL"], options));
Expand Down
4 changes: 2 additions & 2 deletions js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ class Lock {
locked = false;

/**
* Locks the object
* Unlocks the object
*/
unlock() {
this.locked = false;
}

/**
* Unlocks the object
* Locks the object
*/
lock() {
this.locked = true;
Expand Down
32 changes: 30 additions & 2 deletions src/ipyaladin/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
It allows to display astronomical images and catalogs in an interactive way.
"""

import io
import pathlib
from pathlib import Path
import typing
from typing import ClassVar, Union, Final, Optional, Tuple
import warnings
Expand All @@ -14,6 +16,8 @@
from astropy.table.table import QTable
from astropy.table import Table
from astropy.coordinates import SkyCoord, Angle
from astropy.io import fits as astropy_fits
from astropy.io.fits import HDUList
import traitlets
from astropy.wcs import WCS

Expand Down Expand Up @@ -288,6 +292,32 @@ def add_catalog_from_URL(
}
)

def add_fits(self, fits: Union[str, Path, HDUList], **image_options: any) -> None:
"""Load a FITS file into the widget.
Parameters
----------
fits: a path as a string or `pathlib.Path`, or an `~astropy.io.fits.HDUList`
The FITS file to load into the widget.
image_options: dict
The options for the image. See the Aladin Lite image options:
https://cds-astro.github.io/aladin-lite/global.html#ImageOptions
"""
is_path = isinstance(fits, (Path, str))
if is_path:
with astropy_fits.open(fits) as fits_file:
fits_bytes = io.BytesIO()
fits_file.writeto(fits_bytes)
else:
fits_bytes = io.BytesIO()
fits.writeto(fits_bytes)

self.send(
{"event_name": "add_fits", "options": image_options},
buffers=[fits_bytes.getvalue()],
)

# MOCs

def add_moc(self, moc: any, **moc_options: any) -> None:
Expand Down Expand Up @@ -411,8 +441,6 @@ def add_table(self, table: Union[QTable, Table], **table_options: any) -> None:
And the table should appear in the output of Cell 1!
"""
import io

table_bytes = io.BytesIO()
table.write(table_bytes, format="votable")
self.send(
Expand Down

0 comments on commit 1506c18

Please sign in to comment.