wip commit: not finished

This commit is contained in:
Matthieu Baumann
2025-08-28 14:26:43 +02:00
committed by Matthieu Baumann
parent 9db098ce6a
commit 9739b87439
9 changed files with 194 additions and 39 deletions

View File

@@ -39,7 +39,7 @@ Image Opacity: <br/> <input id="slider" type="range" value=1 min=0 max=1 step=0.
//let fits = aladin.displayFITS('http://goldmine.mib.infn.it/data//B/fits/A04_VC1316_ooooog.fits', 'overlay');
let jpg = aladin.displayJPG(
// the JPG to transform to HiPS
'https://noirlab.edu/public/media/archives/images/large/noirlab1912a.jpg',
'https://owncloud.tuebingen.mpg.de/index.php/s/sdxfNgcEaaXoBp7/download/nightskycam3_2025_08_07_05_17_30_healpix1024_red.fits',
// no options
{
transparency: 1.0,

View File

@@ -28,9 +28,9 @@
}
);
hips = aladin.newImageSurvey("https://alasky.cds.unistra.fr/GALFAHI/GALFAHI-Narrow-DR2-3D", {
hips = aladin.newImageSurvey("http://alasky.cds.unistra.fr/LGLBSHI", {
successCallback: (hips) => {
hips.setFrequency({value: 7.402056971809762E-7, unit: "m"}) // GALFA
hips.setFrequency({value: 0.21101690259115785, unit: "m"}) // GALFA
}
});
// compressed https://alasky.cds.unistra.fr/test-compression-cubes/DHIGLS/

View File

@@ -110,6 +110,9 @@ pub struct HiPS3D {
move_freq: bool,
// The location of the cursor to extract the spectra
cursor: Cursor,
/// name of the layer
layer: String,
}
struct Cursor {
@@ -179,7 +182,7 @@ impl Cursor {
/// Get the window starting and ending hashed at the pixel order
fn get_window_frequency_range(&self) -> FrequencyWindow {
const NUM_VALUES: usize = 100;
const NUM_VALUES: usize = 150;
let delta_depth = self.tile_depth.trailing_zeros();
let pixel_depth = self.cell.f_depth + delta_depth as u8;
@@ -298,7 +301,7 @@ use crate::math::spectra::Freq;
use js_sys::Reflect;
impl HiPS3D {
pub fn new(config: HiPSConfig, gl: &WebGlContext) -> Result<Self, JsValue> {
pub fn new(config: HiPSConfig, gl: &WebGlContext, layer: &str) -> Result<Self, JsValue> {
let mut vao = VertexArrayObject::new(gl);
let num_indices = vec![];
@@ -367,6 +370,7 @@ impl HiPS3D {
num_indices,
move_freq,
cursor,
layer: layer.to_string(),
})
}
@@ -492,9 +496,9 @@ impl HiPS3D {
Some(cell)
} else {
//None
None
// FIXME ME READ THE MOC
Some(cell)
//Some(cell)
}
} else {
Some(cell)
@@ -601,6 +605,13 @@ impl HiPS3D {
&JsValue::from_f64(end as f64),
)
.unwrap_abort();
Reflect::set(
&spectra_js_obj,
&JsValue::from_str("layer"),
&JsValue::from_str(&self.layer),
)
.unwrap_abort();
}
let spectra = self
@@ -754,7 +765,8 @@ impl HiPS3D {
} else {
//None
// FIXME SFMOC parsing
Some(hpx_f_cell)
//Some(hpx_f_cell)
None
}
} else {
Some(hpx_f_cell)

View File

@@ -452,9 +452,9 @@ impl Layers {
let hips = match &cfg.dataproduct_type {
// HiPS cube
DataproductType::Cube => HiPS::D3(HiPS3D::new(cfg, gl)?),
DataproductType::Cube => HiPS::D3(HiPS3D::new(cfg, gl, &layer)?),
// HiPS 3D
DataproductType::SpectralCube => HiPS::D3(HiPS3D::new(cfg, gl)?),
DataproductType::SpectralCube => HiPS::D3(HiPS3D::new(cfg, gl, &layer)?),
// Typical HiPS image
_ => HiPS::D2(HiPS2D::new(cfg, gl)?),
};

View File

@@ -38,6 +38,12 @@
bottom: 7rem;
right: 0;
}
.aladin-lite-spectra-displayer .aladin-spectra-hips-selector {
position: absolute;
top: 0;
left: 0;
max-width: 10rem;
}
.aladin-imageCanvas {
position: absolute;
@@ -861,7 +867,6 @@
padding: 0.2rem 0;
font-size: inherit;
border-radius: 0.2rem;
box-shadow: 0 0 1em 0 rgba(0, 0, 0, 0.2);
cursor: pointer;
font-family: monospace;
box-sizing: content-box;

View File

@@ -3093,12 +3093,13 @@ aladin.displayFITS(
options.body = JSON.stringify(params);
}
return fetch(url, options).then((response) => response.json());
return fetch(url, options).then((response) => response.json()).catch(e => console.error(e));
};
const get = (url, params) => request(url, params, "GET");
get("https://alasky.unistra.fr/cgi/fits2HiPS", data).then(
async (response) => {
console.log(response, data)
if (response.status != "success") {
console.error("An error occured: " + response.message);
if (errorCallback) {
@@ -3138,7 +3139,7 @@ aladin.displayFITS(
// This has to be fixed in the backend but a fast fix is just to wait
// before setting a new image survey
}
);
).catch((e) => console.error(e));
};
Aladin.prototype.displayPNG = Aladin.prototype.displayJPG;

View File

@@ -509,13 +509,6 @@ export let HiPS = (function () {
// dataproduct type
self.dataproductType = properties && properties.dataproduct_type;
if (self.dataproductType === "spectral-cube") {
if (!self.view.spectraDisplayer) {
self.view.spectraDisplayer = new SpectraDisplayer(self, {width: 600, height: 300});
}
self.view.spectraDisplayer.attachHiPS3D(self)
}
// Tile size
self.tileSize =
@@ -899,6 +892,10 @@ export let HiPS = (function () {
/// Set image format
if (options.imgFormat) {
if (this.dataproductType === "spectral-cube" && this.view.spectraDisplayer && this.view.spectraDisplayer.hips === this) {
this.view.spectraDisplayer.resetScale()
}
let imgFormat = options.imgFormat.toLowerCase();
if (imgFormat === "jpg") {

View File

@@ -21,7 +21,7 @@ import { ActionButton } from "./gui/Widgets/ActionButton";
import { Input } from "./gui/Widgets/Input";
import HomeIconUrl from '../../assets/icons/maximize.svg';
import SpectraIconUrl from '../../assets/icons/freq.svg';
import { ALEvent } from "./events/ALEvent";
/******************************************************************************
* Aladin Lite project
@@ -116,7 +116,7 @@ export class SpectraDisplayer {
}
};
constructor(hips, options) {
constructor(view, options) {
let createPlotCanvas = (name) => {
const canvas = document.createElement("canvas");
canvas.classList.add(name);
@@ -130,7 +130,7 @@ export class SpectraDisplayer {
return canvas;
};
this.view = hips.view;
this.view = view;
this.data = undefined;
this.scaleX = undefined;
@@ -185,6 +185,20 @@ export class SpectraDisplayer {
},
})
this.selector = new Input({
label: "HiPS3D selector:",
name: "layer selector",
type: 'select',
classList: ['aladin-spectra-hips-selector'],
options: [],
change: (e) => {
let name = e.target.value;
let hips = self.hips3DList.get(name);
self.attachHiPS3D(hips)
},
})
let autoCenterBtn = new ActionButton({
size: 'small',
icon: {
@@ -197,11 +211,8 @@ export class SpectraDisplayer {
},
classList: ['aladin-spectra-home'],
action(e) {
let midFreq = (self.hips.emMin + self.hips.emMax)*0.5;
self.hips.setFrequency({
value: midFreq,
unit: "m"
})
self.resetScale()
self._redraw(self.ctx);
}
})
let extractionBtn = new ActionButton({
@@ -216,7 +227,7 @@ export class SpectraDisplayer {
},
classList: ['aladin-spectra-extraction'],
action(e) {
// TODO
}
})
@@ -238,11 +249,17 @@ export class SpectraDisplayer {
divNode.appendChild(autoCenterBtn.element())
divNode.appendChild(extractionBtn.element())
let divHiPSSelector = document.createElement("div")
divHiPSSelector.innerHTML = '<span>Survey:</span>';
divHiPSSelector.appendChild(this.selector.element())
divNode.appendChild(divHiPSSelector)
this.divNode = divNode;
this.view.aladin.aladinDiv.appendChild(divNode);
this.defineEventListeners()
this.hips3DList = new Map();
}
defineEventListeners() {
@@ -253,6 +270,10 @@ export class SpectraDisplayer {
let ctxCursor = this.ctxCursor;
let self = this;
let lastClickTime = 0;
const DOUBLE_CLICK_DELAY = 300; // most operating systems uses duration between 250ms and 500ms by default.
canvas.addEventListener('mousedown', (e) => {
const rect = canvas.getBoundingClientRect();
const mx = e.clientX - rect.left;
@@ -297,6 +318,22 @@ export class SpectraDisplayer {
relatedTarget: e.relatedTarget,
};
const event = new MouseEvent('mousedown', paramsEvent);
// Track timing to simulate dblclick
const now = Date.now();
if (now - lastClickTime < DOUBLE_CLICK_DELAY) {
const dblClickEvent = new MouseEvent('dblclick', {
bubbles: true,
cancelable: true,
clientX: e.clientX,
clientY: e.clientY
});
this.view.catalogCanvas.dispatchEvent(dblClickEvent);
lastClickTime = 0; // reset
} else {
lastClickTime = now;
}
this.view.catalogCanvas.dispatchEvent(event);
}
}
@@ -412,6 +449,81 @@ export class SpectraDisplayer {
this.view.catalogCanvas.dispatchEvent(wheelEvent);
});
const updateSelectorList = () => {
let options = [];
for (const hipsName of this.hips3DList.keys()) {
options.push(hipsName)
}
this.selector.update({options})
};
ALEvent.HIPS_LAYER_ADDED.listenedBy(
this.view.aladin.aladinDiv,
function (e) {
let hips = e.detail.layer;
if (hips.dataproductType === "spectral-cube") {
self.hips3DList.set(hips.name, hips);
updateSelectorList()
}
}
);
ALEvent.HIPS_LAYER_SWAP.listenedBy(
this.view.aladin.aladinDiv,
function (e) {
let firstHiPS = e.detail.firstLayer;
let secondHiPS = e.detail.secondLayer;
self.hips3DList.delete(firstHiPS.name);
if (secondHiPS.dataproductType === "spectral-cube") {
self.hips3DList.set(secondHiPS.name, secondHiPS);
}
updateSelectorList()
}
);
ALEvent.HIPS_LAYER_REMOVED.listenedBy(
this.view.aladin.aladinDiv,
function (e) {
let hips = e.detail.layer;
self.hips3DList.delete(hips.name);
if (hips === this.hips) {
// the hips pointed by the tool has been removed
self.attachHiPS3D(null);
}
if (self.hips3DList.size === 0) {
self.hide()
}
updateSelectorList()
}
);
}
hide() {
if (this.isHidden) {
return;
}
this.divNode.style.display = "none";
this.isHidden = true;
}
show() {
if (!this.isHidden) {
return;
}
this.divNode.style.display = "block";
this.isHidden = false;
}
attachHiPS3D(hips) {
@@ -423,12 +535,29 @@ export class SpectraDisplayer {
// store new references to the new hips
this.hips = hips;
this.spectraUpdateCallback = (event) => {
this.data = event.detail;
this._redraw(this.ctx);
};
if (hips) {
this.spectraUpdateCallback = (event) => {
let data = event.detail;
console.log(data)
if (data.layer === this.hips.layer) {
this.data = data;
this._redraw(this.ctx);
}
};
window.addEventListener("spectra", this.spectraUpdateCallback);
window.addEventListener("spectra", this.spectraUpdateCallback);
this.resetScale();
this.show()
this.selector.update({value: hips.name, title: hips.name})
}
}
// When changing the HiPS format, a scale reset is necessary
resetScale() {
this.minY = undefined;
this.maxY = undefined;
}
enableInteraction() {
@@ -453,6 +582,7 @@ export class SpectraDisplayer {
if (Number.isFinite(this.minY)) {
this.minY = Math.min(...valuesWithNoNans, this.minY)
console.log(this.minY)
} else {
this.minY = Math.min(...valuesWithNoNans)
}
@@ -480,7 +610,7 @@ export class SpectraDisplayer {
_redrawLabels() {
let self = this;
function spectraValue2String(freq, precision) {
let spectraValue2String = (freq, precision) => {
let units = self.unit.units;
let x = SpectraDisplayer.UNIT.convertFrequency(

View File

@@ -47,6 +47,7 @@ import { ObsCore } from "./vo/ObsCore.js";
import { HiPS } from "./HiPS.js";
import { Image } from "./Image.js";
import { Color } from "./Color.js";
import { SpectraDisplayer } from "./SpectraDisplayer.js";
export let View = (function () {
@@ -589,11 +590,20 @@ export let View = (function () {
}
View.prototype.selectLayer = function (layer) {
if (!this.imageLayers.has(layer)) {
let imageLayer = this.imageLayers.get(layer)
if (!imageLayer) {
console.warn(layer + ' does not exists. So cannot be selected');
return;
}
if (imageLayer.dataproductType === "spectral-cube") {
if (!this.spectraDisplayer) {
this.spectraDisplayer = new SpectraDisplayer(this, {width: 800, height: 300});
}
this.spectraDisplayer.attachHiPS3D(imageLayer)
}
this.selectedLayer = layer;
};
@@ -619,7 +629,6 @@ export let View = (function () {
catch (err) {
return;
}
};
if (!Utils.hasTouchScreen()) {
@@ -1769,6 +1778,7 @@ export let View = (function () {
} else {
// it exists
alreadyPresentImageLayer = this.imageLayers.get(layerName);
// Notify that this image layer has been replaced by the wasm part
if (alreadyPresentImageLayer && alreadyPresentImageLayer.added === true) {
ALEvent.HIPS_LAYER_REMOVED.dispatchedTo(this.aladinDiv, { layer: alreadyPresentImageLayer });
@@ -1783,9 +1793,9 @@ export let View = (function () {
this.imageLayers.set(layerName, imageLayer);
// select the layer if he is on top
if (idxOverlayLayer == -1) {
//if (idxOverlayLayer == -1) {
this.selectLayer(layerName);
}
//}
ALEvent.HIPS_LAYER_ADDED.dispatchedTo(this.aladinDiv, { layer: imageLayer });
}