Skip to content

What exactly does helioviewer.org assume about WCS? #494

Open

Description

@SalimHachemaoui

We are investigating a SPICE JP2 rendering issue in Helioviewer Web.

The tested SPICE JP2 is a valid 2D raster:

NAXIS  = 2
NAXIS1 = 192
NAXIS2 = 612

However, its WCS metadata is not a simple square-pixel, axis-aligned case:

CUNIT1 = deg
CUNIT2 = deg

CDELT1 = 0.0011111111111111 deg  ~= 4.0 arcsec/pixel
CDELT2 = 0.000305 deg            ~= 1.098 arcsec/pixel

It also contains a non-trivial PC matrix:

PC1_1 = -0.61227620057
PC1_2 = -0.217031764022
PC2_1 = 2.88030582543
PC2_2 = -0.61227620057

This raises a general question: what WCS assumptions does helioviewer.org make in 2D and 3D rendering?

Observed behavior

In Helioviewer Web:

  • SPICE can appear mis-scaled or vertically stretched in 2D.
  • In 3D, SPICE does not appear correctly overlaid on EUI.
  • The behavior differs from JHelioviewer, where SPICE appears to be rendered more consistently.

Main questions

  1. Does Helioviewer Web assume CDELT1 == CDELT2?
  2. Does Helioviewer Web assume that the image X axis, associated with CDELT1, is parallel to solar_x?
  3. Is CROTA2 used in 2D or 3D rendering?
  4. Is the PC matrix used in 2D or 3D rendering?
  5. Are CTYPE1/CTYPE2 projections, such as HPLN-TAN/HPLT-TAN, supported in Web rendering?
  6. Do 2D and 3D use the same WCS assumptions?
  7. Is general WCS support expected in helioviewer.org, or only simplified image positioning?

2D / 3D context

From code inspection, the 2D Web path appears to use the tiled rendering pipeline:

getClosestImage -> getTile -> PNG tiles positioned in CSS

The 3D Web path appears to use a separate pipeline:

resources/js/3d -> @helioviewer/sun -> getClosestImage/getJP2Header/downloadImage -> Three.js texture
Image

Activity

  1. dgarciabriseno commented on Jun 3, 2026

    @dgarciabriseno
    Contributor
  2. SalimHachemaoui commented on Jun 4, 2026

    @SalimHachemaoui
    ContributorAuthor

    Thanks Daniel, that confirms what we observed.
    For SPICE, the tested JP2 has CDELT1 ~= 4.0 arcsec/pixel and CDELT2 ~= 1.098 arcsec/pixel, so if JP2ImageXMLBox.php ignores CDELT2 and uses a scalar scale, that likely explains the 2D vertical stretching.
    I’ll focus on JP2ImageXMLBox.php for the 2D case and keep the 3D path separate, since it seems to handle WCS differently.

    If you think this is the right direction, I can create a dedicated branch to handle these WCS edge cases, especially CDELT1 != CDELT2 and possibly CROTA/PC later, while keeping the current behavior unchanged for standard square-pixel datasets.

  3. dgarciabriseno commented on Jun 4, 2026

    @dgarciabriseno
    Contributor
  4. SalimHachemaoui commented on Jun 4, 2026

    @SalimHachemaoui
    ContributorAuthor

    Thanks , that helps a lot.
    I’ll keep the 2D and 3D cases separate. For now I’ll focus on the 2D path and the scalar CDELT assumption.
    I’ll include JP2ImageXMLBox.php for reading CDELT1/CDELT2 and CUNIT1/CUNIT2, and I’ll also check HelioviewerCompositeImage.php so screenshots and movie frames handle CDELT2 consistently.
    The goal will be to keep the current behavior unchanged for standard square-pixel datasets such as AIA/HMI/EUI, and only enable the new logic when the image has anisotropic WCS scale, for example CDELT1 != CDELT2.
    I’ll prepare this in a dedicated branch and share the approach before going too far with the implementation.

  5. ebuchlin commented on Jun 15, 2026

    @ebuchlin

    Thank you very much for this discussion. Thinking a bit more about it with the IAS team this morning:

    • We have the option to bypass the issue by reprojecting the SPICE file to a simple WCS with CDELT2=CDELT1 and PCi_j = Id before creating the JP2. This can be a quick fix for SPICE, but it is not very satisfactory on the long term
    • The reprojection could be done server-side, but this adds some complexity and server load.
    • The web app could switch to the 3D mode when the metadata include CDELT1 ≠ CDELT2 or PCi_j ≠ Id
    • The 2D mode could be deprecated (maybe there are still issues with the 3D mode that prevent this?)

    What do you think of these options?

  6. dgarciabriseno commented on Jul 9, 2026

    @dgarciabriseno
    Contributor
    • We have the option to bypass the issue by reprojecting the SPICE file to a simple WCS with CDELT2=CDELT1 and PCi_j = Id before creating the JP2. This can be a quick fix for SPICE, but it is not very satisfactory on the long term

    This is what 2D Helioviewer expects in general, unless we add support on the server side. We have similar issues with 2D Solar Orbiter and GOES-19 because the source jp2s have a CROTA value which is also not handled in 2D mode because kakadu (program for tiling jpeg2000 files) doesn't support extracting out rotated tiles from the jp2, and we haven't yet invested the time to work around this.

    • The reprojection could be done server-side, but this adds some complexity and server load.

    If the source data needs to be reprojected at all, it must be either pre-computed in the jp2 provided to Helioviewer or computed server side to support screenshots and videos since those are generated server-side.

    • The web app could switch to the 3D mode when the metadata include CDELT1 ≠ CDELT2 or PCi_j ≠ Id

    Not ideal in the long term, but it could be done.

    • The 2D mode could be deprecated (maybe there are still issues with the 3D mode that prevent this?)

    Ultimately we do want the 3D view to be the main view, but it's not feature complete yet. It still needs support for events, screenshots, movies, and the VSO cutout.

  7. ebuchlin commented on Sep 4, 2026

    @ebuchlin

    Thanks, I understand. If this is solved by #513 , can this one be closed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions