\documentclass[11pt]{article}

\usepackage{amsmath}

% GILDAS specific definitions
\include{gildas-def}

\title{IRAM Memo 2023-1\\[3\bigskipamount]
  Review of the spatial projections support in \gildas\\
  Compatibility with FITS}%
\author{S. Bardeau$^{1}$, J. Pety$^{1,2}$\\[0.5cm]
  1. IRAM (Grenoble) \\
  2. Observatoire de Paris}%
\date{22-nov-2023 \\
  version 1.0} \makeindex{}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\begin{document}

\maketitle

\begin{rawhtml}
  Note: this is the on-line version of the Revised support for the SFL
  projection in GREG. A <A HREF="../../pdf/greg-sfl.pdf"> PDF
  version</A> is also available.
\end{rawhtml}

\begin{rawhtml}
  Related information is available in:
  <UL>
  <LI> <A HREF="../greg-html/greg.html"> GREG:</A> Grenoble Graphics
  </UL>
\end{rawhtml}

\begin{abstract}
  This memo reviews the spatial projections implemented in \gildas\
  and their compatibility with the FITS conventions defined by the
  AIPS memos and by Calabretta \& Greisen (2002). It focuses on the
  \emph{radio} projection used at the IRAM 30m telescope, explains
  why its legacy GLS description is obsolete in FITS, and shows how
  the same data can be represented with the CG02-compliant SFL
  projection through a header translation only. It also summarizes
  the related corrections introduced in \gildas\ to restore reliable
  FITS import and export for the affected projections.\\

  Keywords: projection, FITS

  Related documents: \emph{GreG documentation}
\end{abstract}

\newpage
\tableofcontents

\newpage
\section{Description}
\label{txt:description}

\subsection{IRAM context}

At the IRAM 30m telescope, the observations are traditionally
performed so that the spectra coordinates, and the resulting gridded
cubes created from on-the-fly projects, are expressed as an absolute
position on the celestial sphere plus relative offsets projected on a
2D plane using what we call the \emph{radio projection}. This
projection is correctly supported within the \gildas\ frame (including
the \gildas\ Data Format), but also when exporting cubes to FITS using
the equivalent \emph{GLobal-Sinusoidal (hereafter GLS)} projection
inherited from AIPS legacy.\\

However, recent versions of third-party software (CASA, CARTA) have
broken support of the GLS projection in FITS files. This memo analyzes
the current FITS standard regarding spatial projections, makes a
complete review of the various projections supported in \gildas, and
describes the actions performed to ensure \gildas\ users have no
problem when exporting or importing their data to/from FITS.

\subsection{FITS formalism}

The AIPS Memos 27\footnote{\emph{Non-linear Coordinate Systems in
    AIPS} by Eric W. Greisen, May 20th, 1983, revised on January 16th,
  1993; link \texttt{http://www.aips.nrao.edu/aipsmemo.html}} and
46\footnote{\emph{Additional Non-linear Coordinates} by Eric
  W. Greisen, May 20, 1986, revised on January 16, 1993} introduced a
number of projections and the equations to convert between the 2D
projection plane coordinates and 3D spherical celestial
coordinates. The Calabretta \& Greisen 2002
paper\footnote{\emph{Representations of celestial coordinates in
    FITS}, M. R. Calabretta and E. W. Greisen, A\&A 395, 1077-1122
  (2002)} (hereafter CG02) extended the AIPS conventions and
introduced a fully generic formalism to describe many kind of
projections in the FITS file headers. Given the parameters reproduced
in the table~\ref{tab:parameters}, the CG02 general idea, as described
in their section 2, going from the projected plane to the celestial
sphere consists in 3 major steps:
\begin{description}
\item[Definition:] the 2D projected plane is defined as a regular
  coordinate system with a reference point $(x_0,y_0)$ located at
  $(0,0)$ by design. Its extents might be finite or infinite depending
  on the projection kind.
\item[Unprojection:] one converts from the $(x,y)$ projected
  coordinates to the unprojected \emph{native} spherical coordinate:
  $(x,y)$ are converted to $(\phi,\theta)$. Unprojection obviously
  depends on the projection kind and parameters. The \emph{native}
  sphere is defined such as the reference point $(x_0,y_0)$ transforms
  to the sphere fiducial point $(\phi_0,\theta_0)$. This point is
  typically either on the Equator (coordinates $(0,0)$ for \eg\
  cylindrical projections) or located on a pole (coordinates
  $(0,\pm90^\circ)$ for \eg\ zenithal projections); this is an
  intrinsic property of the projection kind.
\item[Euler rotation:] then one rotates the native coordinates
  $(\phi,\theta)$ to celestial coordinates $(\alpha,\delta)$ by an
  Euler rotation of the native sphere. The Euler angles are defined
  thanks to $(\phi_0,\theta_0)$ matching $(\alpha_0,\delta_0)$, plus a
  possible inclination angle.
\end{description}

\begin{table}[htb]
\caption{CG02 coordinate definitions (from their Table~1).}
\center
\begin{tabular}{ll}
\hline
$(x,y)$               & Projection plane coordinates \\
$(\phi,\theta)$       & Native longitude and latitude \\
$(\alpha,\delta)$     & Celestial longitude and latitude \\
$(x_0,y_0)$           & Projection plane coordinates of the fiducial point\\
$(\phi_0,\theta_0)$   & Native longitude and latitude of the fiducial point\\
$(\alpha_0,\delta_0)$ & Celestial longitude and latitude of the fiducial point (\texttt{CRVALia})\\
$(\phi_p,\theta_p)$   & Native longitude and latitude of the celestial pole (\texttt{LONPOLEa})\\
$(\alpha_p,\delta_p)$ & Celestial longitude and latitude of the native pole \\
\hline
\end{tabular}
\label{tab:parameters}
\end{table}

\begin{figure}[htbp]
  \center
  \includegraphics[width=0.9\textwidth]{greg-projections-formalism}
  \caption{\small{Visual representation of the CG02 formalism. In all
      the plots, the grey region and the star marker are at the same
      position on sky. \textbf{Top left}: the grey region symbolizes a
      $20 \times 12$ square degrees in the $(x,y)$ 2D projected
      plane. Blue lines show the abscissa and ordinate origins. For
      simplicity the region is centered on the reference point, but it
      could be anywhere allowed in the plane. \textbf{Top right}: the
      same area is unprojected to $(\phi,\theta)$ spherical
      coordinates on the 3D native sphere (the \emph{unprojection}
      kind chosen for this example is not detailed here). The equator
      and zero reference meridian are shown in green. In this example,
      the fiducial point $(\phi_0,\theta_0)$ has coordinates
      $(0,0)$. \textbf{Bottom left}: the whole sky orientation is kept
      the same as before, but the coordinate system represented is now
      the 3D celestial sphere, with arbitrary reference point and
      inclination angle for the example. The equator and zero
      reference meridian are shown in red. \textbf{Bottom right}: Same
      as previous plot but the celestial sphere is rotated and
      displayed with its origin of coordinates in front. In this
      process, the coordinates have to be Euler-rotated from
      $(\phi,\theta)$ to $(\alpha,\delta)$ to be expressed in this new
      system.}}
\label{fig:formalism}
\end{figure}

The Figure~\ref{fig:formalism} offers a visual representation of these
transformations. The opposite conversion (from absolute celestial
coordinates to projected plane offsets) is done by reverting these
operations.

\subsection{Compatibility between FITS and GILDAS}

The notable projections supported by \gildas\ are summarized in the
Table~\ref{tab:projections}.

\begin{table}[h]
  \caption{List of the projections implemented in \gildas\ and subject
    to export or import to/from FITS data format. The top group was
    defined in the AIPS memo 27, the middle group in the memo 46, and
    the bottom group in the CG02 paper.}
    \vspace{1ex}
\begin{tabular}{lllp{8cm}}
\hline
Name & FITS & \gildas & Note \\
\hline
\hline
Gnomonic             & TAN         & gnomonic      & Full compatibility \gildas/FITS\\
Slant orthographic   & SIN         & orthographic  & Basic compatibility (\gildas\ does not implement
                                                     the additional SIN projection parameters) \\
Zenithal equidistant & ARC         & azimuthal     & Full compatibility \gildas/FITS\\
North Celestial Pole & NCP         & ncp           & Deprecated in FITS, kept in \gildas\ as  this
                                                     would require additional projection parameters of
                                                     the SIN projection\\
\hline
Stereographic        & STG         & stereographic & Full compatibility \gildas/FITS since aug23 (see
                                                     section~\ref{txt:STG})\\
Hammer-Aitoff        & AIT         & aitoff        & Compatibility \gildas/FITS as long as the
                                                     reference is on the Equator \\
Global-Sinusoidal    & GLS         & radio         & Compatibility \gildas/FITS but deprecated in
                                                     FITS, translated to SFL with translation\\
\hline
Sanson-Flamsteed     & SFL         & sfl           & Full compatibility \gildas/FITS since oct23 (see section~\ref{txt:SFL})\\
\hline
\end{tabular}
\label{tab:projections}
\end{table}

\subsubsection{Direct compatibility}

A number of projections defined in the AIPS memos are fully compatible
with the new CG02 formalism, which allows an immediate compatibility
of the \gildas\ projections with the FITS files. According to the CG02
section 6.1.1, \emph{The SIN [orthographic] projection defined by
  Greisen (1983) is here generalized by the addition of projection
  parameters. However, these parameters assume default values which
  reduce to the simple orthographic projection of the AIPS
  convention. Therefore no translation is required.} And in their
section 6.1.3, \emph{The TAN [gnomonic], ARC [azimuthal] and STG
  [stereographic] projections defined by Greisen (1983, 1986) are
  directly equivalent to those defined here and no translation is
  required.}

\subsubsection{Incompatibilities}

On the other hand, CG02 section 6.1.4 stress that \emph{the AIPS
  convention cannot represent oblique celestial coordinate graticules
  such as the one shown in [their] Fig.~2. \texttt{CRVALi} for these
  projections [(AIT/Aitoff, GLS/radio, MER)] in AIPS does not
  correspond to the celestial coordinates $(\alpha_0,\delta_0)$ of the
  reference point, as understood in this formalism, unless they are
  both zero in which case no translation is required}. In other words,
these 3 projections do not fit into the CG02 general formalism (unless
the reference point is on the Equator). See next subsections for
details.

\subsubsection{The GLS/radio projection in details}
\label{txt:GLS}

The AIPS memo 46 defines the \emph{global-sinusoidal} projection (GLS)
in its section 2.3, which writes as
\begin{eqnarray}
\label{eq:GLSx}
x & = & (\alpha-\alpha_0) \cos\delta, \\
\label{eq:GLSy}
y & = & \delta-\delta_0.
\end{eqnarray}
In this case, there is no rotation of the 2D plane compared to the
celestial system (\eg\ ICRS). $(\alpha,\delta)$ are the celestial
coordinates, and $(\alpha_0,\delta_0)$ the coordinates of the
reference point. This can not be described in the CG02 formalism,
which makes this projection obsolete for writing in new FITS files.\\

Fortunately, the GLS projection at any declination and no rotation is
equivalent to a CG02 compliant Sanson-Flamsteed (SFL) projection at
zero declination (\ie\ on the Equator)\footnote{Quoting CG02: \emph{A
    translation into the new formalism exists for non-zero
    \texttt{CRVALi} but only if \texttt{CROTAi} is zero. It consists
    of setting \texttt{CRVALi} to zero and adjusting \texttt{CRPIXj}
    and \texttt{CDELTi} accordingly in the AIPS header whereupon the
    above situation is obtained. The corrections to \texttt{CRPIXj}
    are obtained by computing the pixel coordinates of
    $(\alpha,\delta) = (0,0)$ within the AIPS convention. [...] Of the
    three projections only GLS is known to have been used with
    non-zero \texttt{CRVALi}. Consequently we have renamed it as SFL
    as a warning that translation is required.} CG02 chose the name
  \emph{Sanson-Flamsteed} (SFL) for the new formalism because GLS has
  been used with non-zero declination, and these cases have no general
  equivalent in the new formalism.}. It is therefore possible to
recast a cube in GLS projection as a cube in SFL projection just by
patching the header and without any change on the data! The
demonstration and the exact translation to be performed are detailed
in the appendix section~\ref{txt:SFL0}. The Fig.~\ref{fig:gls2sfl}
gives a visual representation of these transformations.

\begin{figure}[htbp]
  \center
  \includegraphics[width=0.9\textwidth]{greg-projections-gls2sfl}
  \caption{\small{Visual representation of the GLS-to-SFL
      transformation. In all the plots, the grey region covers the
      same area on sky. \textbf{Top left}: the grey region symbolizes
      a $20 \times 12$ square degrees in the $(x,y)$ 2D AIPS-GLS
      projected plane. Blue lines show the abscissa and ordinate
      origins. There is no transformation possible to go to a native
      sphere in the CG02 formalism. \textbf{Top right}: the reference
      point is shifted to the Equator, \ie\ by a $\delta_0$ shift
      ($30^{\circ}$ in this example). The equations now match the
      FITS-SFL formalism at $\delta_0 = 0$. \textbf{Bottom left}: the
      area is SFL-unprojected to $(\phi,\theta)$ spherical coordinates
      on the 3D native sphere. The equator and zero reference meridian
      are shown in green. The fiducial point $(\phi_0,\theta_0)$ of
      the SFL projection has coordinates $(0,0)$ by
      design. \textbf{Bottom right}: the whole sky orientation is kept
      the same as before, but the coordinate system represented is now
      the 3D celestial sphere. The equator and zero reference meridian
      are shown in red. $\alpha_0$ is $50^{\circ}$ in this example.}}
\label{fig:gls2sfl}
\end{figure}

\subsubsection{The Hammer-Aitoff case}

The Hammer-Aitoff projection (hereafter AIT) is similar to the GLS
case, \ie\ it is possible to convert from the old (AIPS) to the new
(CG02) formalism by converting the projection description. But, while
the GLS projection is known to have been used with non-zero
declination reference (hence a new name for the projection), it is
less obvious for AIT. Knowing that both AIPS-AIT and FITS-AIT
formalisms are compatible at $\delta_0 = 0$, CG02 have chosen to keep
the same name for the new convention.

\section{\gildas\ implementation}

\gildas\ implements a variety of projections. They are in place since
more than 30 years and used by the community. Here we compare them to
the AIPS memos and the CG02 paper, in order to check their
compatibility with the current FITS standard.

\subsection{Gnomonic projection}

\gildas\ implementation is fully compatible with the AIPS-TAN
convention, hence also with the CG02 one.

\subsection{Orthographic projection}

The CG02 paper has augmented the definition of the SIN projection with
more parameters in order to describe more projections, remaining
compatible with the AIPS-SIN by default. \gildas\ implementation is
only compatible with the AIPS-SIN convention, and can not describe the
augmented FITS-SIN projection.

\subsection{Azimuthal projection}

\gildas\ implementation is fully compatible with the AIPS-ARC
convention, hence also with the CG02 one.

\subsection{North Celestial Pole projection}

\gildas\ implementation is fully compatible with the AIPS-NCP
convention. NCP is deprecated in the CG02 formalism and should be
converted to an augmented SIN projection\footnote{see CG02
  section~6.1.2}, but since \gildas\ is not able to describe an
augmented SIN, NCP is kept in \gildas.

\subsection{Stereographic projection}
\label{txt:STG}

Up to the release jul23, the \gildas\ implementation was:
\begin{eqnarray}
  z & = & \sin\delta\cos\delta_0 - \cos\delta\sin\delta_0\cos(\alpha-\alpha_0)\\
  \theta & = & \cos^{-1} ( (\sin\delta - z \cos\delta_0)/\sin\delta_0 )\\
  r   & = & \tan \frac{\theta}{2}\\
  x   & = & r \sin p\\
  y   & = & r \cos p
\end{eqnarray}
where $(\alpha,\delta)$ are the celestial coordinates and $(x,y)$ the
projection plane coordinates. $z$ is an intermediate quantity. $r$ is
the distance from the reference point in the projection plane, and $p$
the inclination angle (not detailed here). After a few computations
one can show that the $\theta$ angle is compatible with the AIPS
definition (AIPS memo 46 Eq.~3):
\begin{equation}
  \cos\theta = \sin\delta\sin\delta_0 + \cos\delta\cos\delta_0\cos\Delta\alpha
\end{equation}
But, on the other hand, the coordinate modulus in the AIPS convention
is (AIPS memo 46 section 2.1.2):
\begin{equation}
r_\mathrm{AIPS} = 2\frac{\sin\theta}{1+\cos\theta}
\end{equation}
which can be written as
\begin{equation}
r_\mathrm{AIPS} = 2 \tan\frac{\theta}{2}
\end{equation}
thanks to traditional trigonometric identities \footnote{ $\tan x =
  \frac{\sin x}{\cos x} = \frac{2 \sin x \cos x}{2 \cos^2 x} =
  \frac{\sin 2x}{1 + \cos 2x}$ }, \ie\ twice the $r$ modulus used in
\gildas. In other words, the spatial scaling in the \gildas\ and AIPS
conventions differ by a factor 2. Of these two definitions, the
\gildas\ convention was the unsatisfying one because angles from the
reference point are projected as twice less distance on the projection
plane ($\tan (\theta/2) \simeq \theta/2$ for small angles, \ie\ $r
\simeq \theta/2$ for the GILDAS definition, while one would prefer $r
\simeq \theta$ for correct distance measurement in the projected
plane). This has been considered as a bug in the implementation and
this was fixed with the appropriate factor in the aug23 \gildas\
release. Doing so, the stereographic projection implementation in
\gildas\ is now fully compatible with the AIPS one, and thus to the
CG02 one.

\subsection{Aitoff projection}

\gildas\ implements the AIT projection only for $\delta_0 = 0$;
non-zero reference declinations are always ignored when projecting or
unprojecting positions, even if the data format usually saves any
declination value. This implementation is compatible\footnote{The
  formulae have not been checked, but the maps compatibility with
  other software is confirmed.} with the AIPS (and thus the CG02)
convention \emph{in the $\delta_0 = 0$ case.}

Note, however, that when data were exported to FITS files, \gildas\
versions earlier than aug23 were using the possibly non-zero
declinations as the \texttt{CRVAL2} value. This is incorrect and was
leading to wrong interpretation of the maps by third-party
software. This is fixed in the aug23 release by always setting
\texttt{CRVAL2} parameter to 0 for the AIT projection.

If, at some point, the non-zero declination case is to be implemented
in \gildas, we should choose the newest formalism, \ie\ the CG02
one\footnote{Since the \gildas\ data format used to save any
  declination value while the projection was defined for $\delta_0 =
  0$, we should then introduce a new internal projection code to
  distinguish with the backward compatible case where the reference
  declination is ignored.}

\subsection{Radio projection}

The \gildas\ kernel implements the so-called \emph{radio} projection
with the same formalism as AIPS GLS (Eqs.~\ref{eq:GLSx} and
\ref{eq:GLSy}). In particular, this projection system is used natively
at the IRAM-30m telescope and is preserved to describe the position of
pointed spectra, or on-the-fly observations and the resulting
reconstructed position-position-velocity cubes. Up to \gildas\ version
jul23, the radio-projection description was exported under the
\texttt{-GLS} suffix in FITS header files (\gildas\ command
\texttt{V$\backslash$FITS output.fits FROM input.gdf}).

However, it appeared that this could cause issues when the exported
FITS are interpreted by some third-party software. Many FITS-based
software implement an implicit GLS-to-SFL conversion as suggested by
CG02. However, some seem to implement it incorrectly (the translation
is not correctly applied), while some other just fail in this case
(CASA, CARTA). Because of these various troubles, it is decided not to
export any more FITS data out of \gildas\ with the radio/GLS
description.

% E. Caux has some on-the-fly APEX data and he produced a
% position-position-velocity cube from these data using CLASS. However,
% he reports us he can not (or partially) visualize this cube in CASA or
% CARTA. Investigating a bit, we found that the problem comes from the
% "GLS" (radio) projection of these cubes. Whether this is a CASA/CARTA
% bug is unclear, but CASA also shows this warning:
% 
% \begin{verbatim}
% 2023-06-22 13:18:14 WARN FITSCoordinateUtil  Note: The GLS projection is
%                     deprecated. Use SFL instead.
% \end{verbatim}

\subsubsection{Radio-projected cubes}

The cubes using a radio-projection in \gildas\ typically look like:
\begin{verbatim}
File : 13co10.lmv                                                    REAL*4
Size        Reference Pixel           Value                  Increment
        61   44.5561196503335       0.00000000000000     -5.411193342297338E-05
       101   55.4797321532119       0.00000000000000      5.411193342297338E-05
       921   578.812988281250       2.50000000000000     -0.106259830296040
Source name         NGC7023
Axis type           RA           DEC          VELOCITY
Coordinate system   EQUATORIAL          Velocity    LSR
Right Ascension   21:01:32.24000        Declination       68:10:29.5500
Equinox            2000.0000
Projection type     RADIO               Angle     0.000000000000000
Axis 1     A0     21:01:32.24000        Axis 2     D0     68:10:29.5500
[...]
\end{verbatim}
Note the \texttt{RADIO} projection type. Starting from \gildas\
version \texttt{aug23}, this kind of header will be implicitely
exported with the SFL projection by the \texttt{V$\backslash$FITS}
command. The resulting header will be:
\begin{verbatim}
NAXIS   =                    3         /
NAXIS1  =                   61         /
NAXIS2  =                  101         /
NAXIS3  =                  921         /
CTYPE1  = 'RA---SFL    '               /
CRVAL1  =  0.3153843333333E+03         /
CDELT1  = -0.3100385406429E-02         /
CRPIX1  =  0.4455611965033E+02         /
CUNIT1  = 'deg         '               /
CTYPE2  = 'DEC--SFL    '               /
CRVAL2  =  0.0000000000000E+00         /
CDELT2  =  0.3100385406429E-02         /
CRPIX2  = -0.2193368163425E+05         /
CUNIT2  = 'deg         '               /
OBJECT  = 'NGC7023     '               /
RADESYS = 'FK5'                        / Coordinate system
RA      =  0.3153843333333E+03         / Right Ascension
DEC     =  0.6817487500002E+02         / Declination
[...]
\end{verbatim}
Note 1) the \texttt{-SFL} suffix on the spatial axes, 2) the null
\texttt{CRVAL2} value, 3) the reference pixel shifted far away, to the
Equator (\texttt{CRPIX2} is about $-22000$ pixels). Note also that the
indicative source position (\texttt{RA,DEC}) is preserved.

\subsubsection{30m \class\ cubes}

In order to avoid changing the projection once the date were gridded,
we modified it one step earlier in the data processing. In practice,
the \texttt{XY\_MAP} command in \class\ (which grids a collection of
spectra into a cube) will now implicitly convert radio-projected
spectra positions into azimuthal projection \emph{before}
gridding. Other projections are left unchanged. The user can not
customize the projection of the output cube in \texttt{XY\_MAP}, but
he can still do this another step earlier by reprojecting
(\texttt{MODIFY PROJECTION}) all the individual spectra in the
\texttt{.30m} file.\\

Note that NOEMA cubes are not concerned as they are natively
constructed with the azimuthal projection.

\subsection{SFL projection}
\label{txt:SFL}

Since the dec07 \gildas\ release, the SFL projection was implemented
as:
\begin{eqnarray}
x & = & (\alpha-\alpha_0) \times cos(\delta-\delta_0) \\
y & = & \delta-\delta_0
\end{eqnarray}
This convention is very near to the radio/GLS one, except $x$ depends
on the cosine of $\delta-\delta_0$, not $\delta$ itself. Unfortunately,
this convention does not match the GC02 one, in particular the stage 2
described in section~\ref{txt:description} where the native sphere is
Euler-rotated to the celestial sphere. This is not as simple as the
simple $\delta$ shift in the above formula.\\

Choice is made to discard the above implementation and go for the CG02
one, without changing the GILDAS name \emph{SFL} and the associated
internal identifier for this projection. This assumes this projection
was seldom used on the GILDAS side (import/export from/to FITS was
anyway not available). This may break the interpretation of old
\gildas\ cubes using this projection, if any, but introduces full
compatibility with FITS-SFL files. The implementation is detailed in
Appendix~\ref{app:SFL} and is done since \gildas\ release oct23.

\newpage
\appendix{}

\section{New SFL implementation in \gildas}
\label{app:SFL}

This appendix is based on the formalism of the CG02 paper, applied to
the particular case of the SFL projection. See
Table~\ref{tab:parameters} for the coordinates involved
here. According to the CG02 section~5.3, \emph{the pseudocylindricals
  are constructed with the native coordinate system origin at the
  reference point. Accordingly we set} (their eq.~89):
\begin{equation}
 (\phi_0,\theta_0) = (0,0)
\end{equation}
The native longitude of the celestial pole $\phi_p$ is defined as
(their section 2.2):
\begin{equation}
\phi_p =
\begin{cases}
0^\circ   & \text{for $\delta_0 \geq 0$} \\
180^\circ & \text{for $\delta_0 < 0$}
\end{cases}
\end{equation}
This implies $\sin\phi_p = 0$. Their eq.~8 is simplified as:
\begin{eqnarray}
\delta_{p,1} & = & \text{atan2}(0,\cos\phi_p) + \cos^{-1}(\sin\delta_0) \\
\delta_{p,2} & = & \text{atan2}(0,\cos\phi_p) - \cos^{-1}(\sin\delta_0)
\end{eqnarray}
where $\text{atan2}(y,x)$ is the inverse tangent function that returns
the correct quadrant. $\delta_{p,1}$ and $\delta_{p,2}$ are two
solutions for $\delta_p$. The choice between the two is ruled by
several conditions detailed in the CG02 paper section~2.4. The rule 4
states that the northernly solution is the default if the native
latitude of the celestial pole ($\theta_p$, \texttt{LATPOLEa} in FITS
headers) is not defined, which we implement as:
\begin{equation}
\delta_p =
\begin{cases}
\delta_{p,1} & \text{if } \delta_{p,1} > 0 \text{ and } \delta_{p,1} \leq 90^\circ \\
\delta_{p,2} & \text{otherwise.}
\end{cases}
\end{equation}
If $\delta_p = \pm 90^\circ$, their rule 2 applies to determine
$\alpha_p$, otherwise their generic equations~9 and 10 are used:
\begin{equation}
\alpha_p =
\begin{cases}
\alpha_0 + \phi_p - 180^\circ & \text{for } \delta_p = +90^\circ \\
\alpha_0 - \phi_p            & \text{for } \delta_p = -90^\circ \\
\alpha_0 - \text{atan2}(0,-\frac{\sin\delta_p\sin\delta_0}{\cos\delta_p\cos\delta_0}) & \text{otherwise.}
\end{cases}
\end{equation}

\subsection{From projection plane to celestial coordinates}

$(x,y)$ projection planes coordinates can be converted to the absolute
celestial coordinates $(\alpha,\delta)$ as follows. The CG02 equations
92 and 93 for the SFL projection are written:
\begin{eqnarray}
\phi & = & \frac{x}{\cos y} \\
\theta & = & y
\end{eqnarray}
Using their eq.~2 with the parameters computed before, the coordinates
are:
\begin{eqnarray}
\alpha & = & \alpha_p + 
             \text{atan2}(-\cos\theta\sin(\phi-\phi_p),
                          \sin\theta\cos\delta_p-\cos\theta\sin\delta_p\cos(\phi-\phi_p)) \\
\delta & = & \sin^{-1}(\sin\theta\sin\delta_p+\cos\theta\cos\delta_p\cos(\phi-\phi_p))
\end{eqnarray}

\subsection{From celestial to projection plane coordinates}

The reverse operation is done with the generic Euler rotation (their
equation 5)
\begin{eqnarray}
\phi & = & \phi_p + \text{atan2}(-\cos\delta\sin(\alpha-\alpha_p),
                                 \sin\delta\cos\delta_p-\cos\delta\sin\delta_p\cos(\alpha-\alpha_p)) \\
\theta & = & \sin^{-1}(\sin\delta\sin\delta_p+\cos\delta\cos\delta_p\cos(\alpha-\alpha_p))
\end{eqnarray}
and the projection specific to SFL (their equations 90 and 91):
\begin{eqnarray}
x & = & \phi \cos \theta \\
y & = & \theta
\end{eqnarray}

\subsection{Special case of SFL with reference on the Equator}
\label{txt:SFL0}

The case where the reference point is chosen on the Equator ($\delta_0
= 0$) is interesting because of the conversion from GLS to SFL
suggested by CG02 and described in
section~\ref{txt:description}. Injected in the previous formulas and
rules, this gives:
\begin{eqnarray}
\phi_p & = & 0^\circ \\
\delta_p & = & +90^\circ \\
\alpha_p & = & \alpha_0 - 180^\circ
\end{eqnarray}
The $\phi_{\text{SFL},0}$ longitude simplifies as:
\begin{equation}
\phi_{\text{SFL},0} = \text{atan2}(-\cos\delta\sin(\alpha-\alpha_0-180^\circ),
                                 -\cos\delta\cos(\alpha-\alpha_0-180^\circ))
     = \alpha-\alpha_0
\end{equation}
because $\text{atan2}(-y,-x) = \text{atan2}(y,x) + 180^\circ$
(opposite quadrant). Similarly the $\theta_{\text{SFL},0}$ latitude is
in this case:
\begin{equation}
\theta_{\text{SFL},0} = \sin^{-1}(\sin\delta)
                    = \delta
\end{equation}
Finally:
\begin{eqnarray}
x_{\text{SFL},0} & = & (\alpha-\alpha_0) \cos \delta \\
y_{\text{SFL},0} & = & \delta
\end{eqnarray}
In this case $(x,y)$ have almost the same definition as the GLS
definition provided in Eqs.~\ref{eq:GLSx} and \ref{eq:GLSy}. If we
write a y-shifted version of the GLS equations as:
\begin{eqnarray}
x^\prime_\text{GLS} & = & x_\text{GLS} = (\alpha-\alpha_0) \cos \delta \\
y^\prime_\text{GLS} & = & y_\text{GLS} + \delta_0 = \delta
\end{eqnarray}
\ie\ $(x^\prime_\text{GLS},y^\prime_\text{GLS}) =
(x_{\text{SFL},0},y_{\text{SFL},0})$. This shows we can write the GLS
projection at any declination as a SFL projection at zero declination
with the relationship $x_\text{GLS} = x_{\text{SFL},0}$ and
$y_\text{GLS} = y_{\text{SFL},0} - \delta_0$.

\section{Consistency checks}

Here we compare the behaviour of \gildas\ and other astronomical
software regarding GLS and SFL projections. Comparisons are done using
the \greg\ \texttt{CONVERT} command, \texttt{astropy.wcs} Python
module version 5.2.2, and the FITS graphical viewer \texttt{ds9}
version 8.2.1. The test data is created as a large scale map, with all
values blanked except 3 single pixels for easy identification:
$(3600,-1800), (3600,+1800)$ and $(-200,0)$ arcseconds relative
offsets on the projection plane, and checking what the various
software return as corresponding absolute celestial position on
sky. Note that the ambiguity is about 1 pixel (5 arcsec in the test
data) which is good enough to detect problems on such large maps.

\subsection{Support for TAN / gnomonic projection}

This projection is used to confirm the 3 software behave the same on a
friendly/non-ambiguous projection, and serves to give correct absolute
coordinates to be compared with the other consistently-reprojected
data.

\subsection{Support for GLS / radio projection}

\begin{itemize}

\item \texttt{astropy.wcs} and \texttt{G$\backslash$CONVERT} are
  consistent and compatible with the gnomonic absolute
  coordinates. Note that \texttt{astropy.wcs} claims the projection is
  SFL, so this means it implicitly translated the reference pixel as
  requested by CG02.
\item \texttt{ds9} disagree and gives improper coordinates. It seems
  it acts as if the projection was SFL without translating the
  reference (which is obviously wrong).
\end{itemize}

\subsection{Support for SFL (properly shifted) projection}

As explained in the section~\ref{txt:SFL0}, the header is consistently
modified to use a SFL projection with the reference pixel shifted on
the Equator, and data does not need to be reprojected. All the 3
software are consistent.

\subsection{Support for SFL (no shift) projection}

In this case, only the projection kind is forced to SFL instead of
GLS/radio, but not the reference. Data is not modified. We do not
expect the absolute positions of the pixels to be correct, but we can
compare if the 3 software consistently return the same positions for
their generic SFL implementation at $\delta_0 \ne 0$.

\begin{itemize}
\item \texttt{ds9} and \texttt{astropy.wcs} are consistent: they have
  the same interpretation of the header,
\item \texttt{G$\backslash$CONVERT} in \gildas\ version jul23
  disagree,
\item after reimplementation of the SFL projection,
  \texttt{G$\backslash$CONVERT} in \gildas\ version oct23 is
  consistent with the 2 other ones.
\end{itemize}

\end{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
