- Main Page
- Related Pages
- Data Structures
- Files

# spc.h

Go to the documentation of this file.

    00001 /*============================================================================
    00002
    00003   WCSLIB 4.17 - an implementation of the FITS WCS standard.
    00004   Copyright (C) 1995-2013, Mark Calabretta
    00005
    00006   This file is part of WCSLIB.
    00007
    00008   WCSLIB is free software: you can redistribute it and/or modify it under the
    00009   terms of the GNU Lesser General Public License as published by the Free
    00010   Software Foundation, either version 3 of the License, or (at your option)
    00011   any later version.
    00012
    00013   WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
    00014   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00015   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
    00016   more details.
    00017
    00018   You should have received a copy of the GNU Lesser General Public License
    00019   along with WCSLIB.  If not, see http://www.gnu.org/licenses.
    00020
    00021   Direct correspondence concerning WCSLIB to mark@calabretta.id.au
    00022
    00023   Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
    00024   http://www.atnf.csiro.au/people/Mark.Calabretta
    00025   $Id: spc.h,v 4.17 2013/01/29 05:29:20 cal103 Exp $
    00026 *=============================================================================
    00027 *
    00028 * WCSLIB 4.17 - C routines that implement the spectral coordinate systems
    00029 * recognized by the FITS World Coordinate System (WCS) standard.  Refer to
    00030 *
    00031 *   "Representations of world coordinates in FITS",
    00032 *   Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (Paper I)
    00033 *
    00034 *   "Representations of spectral coordinates in FITS",
    00035 *   Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L.
    00036 *   2006, A&A, 446, 747 (Paper III)
    00037 *
    00038 * Refer to the README file provided with WCSLIB for an overview of the
    00039 * library.
    00040 *
    00041 *
    00042 * Summary of the spc routines
    00043 * ---------------------------
    00044 * These routines implement the part of the FITS WCS standard that deals with
    00045 * spectral coordinates.  They define methods to be used for computing spectral
    00046 * world coordinates from intermediate world coordinates (a linear
    00047 * transformation of image pixel coordinates), and vice versa.  They are based
    00048 * on the spcprm struct which contains all information needed for the
    00049 * computations.  The struct contains some members that must be set by the
    00050 * user, and others that are maintained by these routines, somewhat like a
    00051 * C++ class but with no encapsulation.
    00052 *
    00053 * Routine spcini() is provided to initialize the spcprm struct with default
    00054 * values, spcfree() reclaims any memory that may have been allocated to store
    00055 * an error message, and spcprt() prints its contents.
    00056 *
    00057 * A setup routine, spcset(), computes intermediate values in the spcprm struct
    00058 * from parameters in it that were supplied by the user.  The struct always
    00059 * needs to be set up by spcset() but it need not be called explicitly - refer
    00060 * to the explanation of spcprm::flag.
    00061 *
    00062 * spcx2s() and spcs2x() implement the WCS spectral coordinate transformations.
    00063 * In fact, they are high level driver routines for the lower level spectral
    00064 * coordinate transformation routines described in spx.h.
    00065 *
    00066 * A number of routines are provided to aid in analysing or synthesising sets
    00067 * of FITS spectral axis keywords:
    00068 *
    00069 *   - spctype() checks a spectral CTYPEia keyword for validity and returns
    00070 *     information derived from it.
    00071 *
    00072 *   - Spectral keyword analysis routine spcspxe() computes the values of the
    00073 *     X-type spectral variables for the S-type variables supplied.
    00074 *
    00075 *   - Spectral keyword synthesis routine, spcxpse(), computes the S-type
    00076 *     variables for the X-types supplied.
    00077 *
    00078 *   - Given a set of spectral keywords, a translation routine, spctrne(),
    00079 *     produces the corresponding set for the specified spectral CTYPEia.
    00080 *
    00081 *   - spcaips() translates AIPS-convention spectral CTYPEia and VELREF
    00082 *     keyvalues.
    00083 *
    00084 * Spectral variable types - S, P, and X:
    00085 * --------------------------------------
    00086 * A few words of explanation are necessary regarding spectral variable types
    00087 * in FITS.
    00088 *
    00089 * Every FITS spectral axis has three associated spectral variables:
    00090 *
    00091 *   S-type: the spectral variable in which coordinates are to be
    00092 *     expressed.  Each S-type is encoded as four characters and is
    00093 *     linearly related to one of four basic types as follows:
    00094 *
    00095 *     F: frequency
    00096 *       'FREQ':  frequency
    00097 *       'AFRQ':  angular frequency
    00098 *       'ENER':  photon energy
    00099 *       'WAVN':  wave number
    00100 *       'VRAD':  radio velocity
    00101 *
    00102 *     W: wavelength in vacuo
    00103 *       'WAVE':  wavelength
    00104 *       'VOPT':  optical velocity
    00105 *       'ZOPT':  redshift
    00106 *
    00107 *     A: wavelength in air
    00108 *       'AWAV':  wavelength in air
    00109 *
    00110 *     V: velocity
    00111 *       'VELO':  relativistic velocity
    00112 *       'BETA':  relativistic beta factor
    00113 *
    00114 *     The S-type forms the first four characters of the CTYPEia keyvalue,
    00115 *     and CRVALia and CDELTia are expressed as S-type quantities so that
    00116 *     they provide a first-order approximation to the S-type variable at
    00117 *     the reference point.
    00118 *
    00119 *     Note that 'AFRQ', angular frequency, is additional to the variables
    00120 *     defined in WCS Paper III.
    00121 *
    00122 *   P-type: the basic spectral variable (F, W, A, or V) with which the
    00123 *     S-type variable is associated (see list above).
    00124 *
    00125 *     For non-grism axes, the P-type is encoded as the eighth character of
    00126 *     CTYPEia.
    00127 *
    00128 *   X-type: the basic spectral variable (F, W, A, or V) for which the
    00129 *     spectral axis is linear, grisms excluded (see below).
    00130 *
    00131 *     For non-grism axes, the X-type is encoded as the sixth character of
    00132 *     CTYPEia.
    00133 *
    00134 *   Grisms: Grism axes have normal S-, and P-types but the axis is linear,
    00135 *     not in any spectral variable, but in a special "grism parameter".
    00136 *     The X-type spectral variable is either W or A for grisms in vacuo or
    00137 *     air respectively, but is encoded as 'w' or 'a' to indicate that an
    00138 *     additional transformation is required to convert to or from the
    00139 *     grism parameter.  The spectral algorithm code for grisms also has a
    00140 *     special encoding in CTYPEia, either 'GRI' (in vacuo) or 'GRA' (in air).
    00141 *
    00142 * In the algorithm chain, the non-linear transformation occurs between the
    00143 * X-type and the P-type variables; the transformation between P-type and
    00144 * S-type variables is always linear.
    00145 *
    00146 * When the P-type and X-type variables are the same, the spectral axis is
    00147 * linear in the S-type variable and the second four characters of CTYPEia
    00148 * are blank.  This can never happen for grism axes.
    00149 *
    00150 * As an example, correlating radio spectrometers always produce spectra that
    00151 * are regularly gridded in frequency; a redshift scale on such a spectrum is
    00152 * non-linear.  The required value of CTYPEia would be 'ZOPT-F2W', where the
    00153 * desired S-type is 'ZOPT' (redshift), the P-type is necessarily 'W'
    00154 * (wavelength), and the X-type is 'F' (frequency) by the nature of the
    00155 * instrument.
    00156 *
    00157 * Argument checking:
    00158 * ------------------
    00159 * The input spectral values are only checked for values that would result in
    00160 * floating point exceptions.  In particular, negative frequencies and
    00161 * wavelengths are allowed, as are velocities greater than the speed of
    00162 * light.  The same is true for the spectral parameters - rest frequency and
    00163 * wavelength.
    00164 *
    00165 * Accuracy:
    00166 * ---------
    00167 * No warranty is given for the accuracy of these routines (refer to the
    00168 * copyright notice); intending users must satisfy for themselves their
    00169 * adequacy for the intended purpose.  However, closure effectively to within
    00170 * double precision rounding error was demonstrated by test routine tspc.c
    00171 * which accompanies this software.
    00172 *
    00173 *
    00174 * spcini() - Default constructor for the spcprm struct
    00175 * ----------------------------------------------------
    00176 * spcini() sets all members of a spcprm struct to default values.  It should
    00177 * be used to initialize every spcprm struct.
    00178 *
    00179 * Given and returned:
    00180 *   spc       struct spcprm*
    00181 *                       Spectral transformation parameters.
    00182 *
    00183 * Function return value:
    00184 *             int       Status return value:
    00185 *                         0: Success.
    00186 *                         1: Null spcprm pointer passed.
    00187 *
    00188 *
    00189 * spcfree() - Destructor for the spcprm struct
    00190 * --------------------------------------------
    00191 * spcfree() frees any memory that may have been allocated to store an error
    00192 * message in the spcprm struct.
    00193 *
    00194 * Given:
    00195 *   spc       struct spcprm*
    00196 *                       Spectral transformation parameters.
    00197 *
    00198 * Function return value:
    00199 *             int       Status return value:
    00200 *                         0: Success.
    00201 *                         1: Null spcprm pointer passed.
    00202 *
    00203 *
    00204 * spcprt() - Print routine for the spcprm struct
    00205 * ----------------------------------------------
    00206 * spcprt() prints the contents of a spcprm struct using wcsprintf().  Mainly
    00207 * intended for diagnostic purposes.
    00208 *
    00209 * Given:
    00210 *   spc       const struct spcprm*
    00211 *                       Spectral transformation parameters.
    00212 *
    00213 * Function return value:
    00214 *             int       Status return value:
    00215 *                         0: Success.
    00216 *                         1: Null spcprm pointer passed.
    00217 *
    00218 *
    00219 * spcset() - Setup routine for the spcprm struct
    00220 * ----------------------------------------------
    00221 * spcset() sets up a spcprm struct according to information supplied within
    00222 * it.
    00223 *
    00224 * Note that this routine need not be called directly; it will be invoked by
    00225 * spcx2s() and spcs2x() if spcprm::flag is anything other than a predefined
    00226 * magic value.
    00227 *
    00228 * Given and returned:
    00229 *   spc       struct spcprm*
    00230 *                       Spectral transformation parameters.
    00231 *
    00232 * Function return value:
    00233 *             int       Status return value:
    00234 *                         0: Success.
    00235 *                         1: Null spcprm pointer passed.
    00236 *                         2: Invalid spectral parameters.
    00237 *
    00238 *                       For returns > 1, a detailed error message is set in
    00239 *                       spcprm::err if enabled, see wcserr_enable().
    00240 *
    00241 *
    00242 * spcx2s() - Transform to spectral coordinates
    00243 * --------------------------------------------
    00244 * spcx2s() transforms intermediate world coordinates to spectral coordinates.
    00245 *
    00246 * Given and returned:
    00247 *   spc       struct spcprm*
    00248 *                       Spectral transformation parameters.
    00249 *
    00250 * Given:
    00251 *   nx        int       Vector length.
    00252 *
    00253 *   sx        int       Vector stride.
    00254 *
    00255 *   sspec     int       Vector stride.
    00256 *
    00257 *   x         const double[]
    00258 *                       Intermediate world coordinates, in SI units.
    00259 *
    00260 * Returned:
    00261 *   spec      double[]  Spectral coordinates, in SI units.
    00262 *
    00263 *   stat      int[]     Status return value status for each vector element:
    00264 *                         0: Success.
    00265 *                         1: Invalid value of x.
    00266 *
    00267 * Function return value:
    00268 *             int       Status return value:
    00269 *                         0: Success.
    00270 *                         1: Null spcprm pointer passed.
    00271 *                         2: Invalid spectral parameters.
    00272 *                         3: One or more of the x coordinates were invalid,
    00273 *                            as indicated by the stat vector.
    00274 *
    00275 *                       For returns > 1, a detailed error message is set in
    00276 *                       spcprm::err if enabled, see wcserr_enable().
    00277 *
    00278 *
    00279 * spcs2x() - Transform spectral coordinates
    00280 * -----------------------------------------
    00281 * spcs2x() transforms spectral world coordinates to intermediate world
    00282 * coordinates.
    00283 *
    00284 * Given and returned:
    00285 *   spc       struct spcprm*
    00286 *                       Spectral transformation parameters.
    00287 *
    00288 * Given:
    00289 *   nspec     int       Vector length.
    00290 *
    00291 *   sspec     int       Vector stride.
    00292 *
    00293 *   sx        int       Vector stride.
    00294 *
    00295 *   spec      const double[]
    00296 *                       Spectral coordinates, in SI units.
    00297 *
    00298 * Returned:
    00299 *   x         double[]  Intermediate world coordinates, in SI units.
    00300 *
    00301 *   stat      int[]     Status return value status for each vector element:
    00302 *                         0: Success.
    00303 *                         1: Invalid value of spec.
    00304 *
    00305 * Function return value:
    00306 *             int       Status return value:
    00307 *                         0: Success.
    00308 *                         1: Null spcprm pointer passed.
    00309 *                         2: Invalid spectral parameters.
    00310 *                         4: One or more of the spec coordinates were
    00311 *                            invalid, as indicated by the stat vector.
    00312 *
    00313 *                       For returns > 1, a detailed error message is set in
    00314 *                       spcprm::err if enabled, see wcserr_enable().
    00315 *
    00316 *
    00317 * spctype() - Spectral CTYPEia keyword analysis
    00318 * ---------------------------------------------
    00319 * spctype() checks whether a CTYPEia keyvalue is a valid spectral axis type
    00320 * and if so returns information derived from it relating to the associated S-,
    00321 * P-, and X-type spectral variables (see explanation above).
    00322 *
    00323 * The return arguments are guaranteed not be modified if CTYPEia is not a
    00324 * valid spectral type; zero-pointers may be specified for any that are not of
    00325 * interest.
    00326 *
    00327 * A deprecated form of this function, spctyp(), lacks the wcserr** parameter.
    00328 *
    00329 * Given:
    00330 *   ctype     const char[9]
    00331 *                       The CTYPEia keyvalue, (eight characters with null
    00332 *                       termination).
    00333 *
    00334 * Returned:
    00335 *   stype     char[]    The four-letter name of the S-type spectral variable
    00336 *                       copied or translated from ctype.  If a non-zero
    00337 *                       pointer is given, the array must accomodate a null-
    00338 *                       terminated string of length 5.
    00339 *
    00340 *   scode     char[]    The three-letter spectral algorithm code copied or
    00341 *                       translated from ctype.  Logarithmic ('LOG') and
    00342 *                       tabular ('TAB') codes are also recognized.  If a
    00343 *                       non-zero pointer is given, the array must accomodate a
    00344 *                       null-terminated string of length 4.
    00345 *
    00346 *   sname     char[]    Descriptive name of the S-type spectral variable.
    00347 *                       If a non-zero pointer is given, the array must
    00348 *                       accomodate a null-terminated string of length 22.
    00349 *
    00350 *   units     char[]    SI units of the S-type spectral variable.  If a
    00351 *                       non-zero pointer is given, the array must accomodate a
    00352 *                       null-terminated string of length 8.
    00353 *
    00354 *   ptype     char*     Character code for the P-type spectral variable
    00355 *                       derived from ctype, one of 'F', 'W', 'A', or 'V'.
    00356 *
    00357 *   xtype     char*     Character code for the X-type spectral variable
    00358 *                       derived from ctype, one of 'F', 'W', 'A', or 'V'.
    00359 *                       Also, 'w' and 'a' are synonymous to 'W' and 'A' for
    00360 *                       grisms in vacuo and air respectively.  Set to 'L' or
    00361 *                       'T' for logarithmic ('LOG') and tabular ('TAB') axes.
    00362 *
    00363 *   restreq   int*      Multivalued flag that indicates whether rest
    00364 *                       frequency or wavelength is required to compute
    00365 *                       spectral variables for this CTYPEia:
    00366 *                         0: Not required.
    00367 *                         1: Required for the conversion between S- and
    00368 *                            P-types (e.g. 'ZOPT-F2W').
    00369 *                         2: Required for the conversion between P- and
    00370 *                            X-types (e.g. 'BETA-W2V').
    00371 *                         3: Required for the conversion between S- and
    00372 *                            P-types, and between P- and X-types, but not
    00373 *                            between S- and X-types (this applies only for
    00374 *                            'VRAD-V2F', 'VOPT-V2W', and 'ZOPT-V2W').
    00375 *                        Thus the rest frequency or wavelength is required for
    00376 *                        spectral coordinate computations (i.e. between S- and
    00377 *                        X-types) only if restreq%3 != 0.
    00378 *
    00379 *   err       struct wcserr **
    00380 *                       If enabled, for function return values > 1, this
    00381 *                       struct will contain a detailed error message, see
    00382 *                       wcserr_enable().  May be NULL if an error message is
    00383 *                       not desired.  Otherwise, the user is responsible for
    00384 *                       deleting the memory allocated for the wcserr struct.
    00385 *
    00386 * Function return value:
    00387 *             int       Status return value:
    00388 *                         0: Success.
    00389 *                         2: Invalid spectral parameters (not a spectral
    00390 *                            CTYPEia).
    00391 *
    00392 *
    00393 * spcspxe() - Spectral keyword analysis
    00394 * ------------------------------------
    00395 * spcspxe() analyses the CTYPEia and CRVALia FITS spectral axis keyword values
    00396 * and returns information about the associated X-type spectral variable.
    00397 *
    00398 * A deprecated form of this function, spcspx(), lacks the wcserr** parameter.
    00399 *
    00400 * Given:
    00401 *   ctypeS    const char[9]
    00402 *                       Spectral axis type, i.e. the CTYPEia keyvalue, (eight
    00403 *                       characters with null termination).  For non-grism
    00404 *                       axes, the character code for the P-type spectral
    00405 *                       variable in the algorithm code (i.e. the eighth
    00406 *                       character of CTYPEia) may be set to '?' (it will not
    00407 *                       be reset).
    00408 *
    00409 *   crvalS    double    Value of the S-type spectral variable at the reference
    00410 *                       point, i.e. the CRVALia keyvalue, SI units.
    00411 *
    00412 *   restfrq,
    00413 *   restwav   double    Rest frequency [Hz] and rest wavelength in vacuo [m],
    00414 *                       only one of which need be given, the other should be
    00415 *                       set to zero.
    00416 *
    00417 * Returned:
    00418 *   ptype     char*     Character code for the P-type spectral variable
    00419 *                       derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
    00420 *
    00421 *   xtype     char*     Character code for the X-type spectral variable
    00422 *                       derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
    00423 *                       Also, 'w' and 'a' are synonymous to 'W' and 'A' for
    00424 *                       grisms in vacuo and air respectively; crvalX and dXdS
    00425 *                       (see below) will conform to these.
    00426 *
    00427 *   restreq   int*      Multivalued flag that indicates whether rest frequency
    00428 *                       or wavelength is required to compute spectral
    00429 *                       variables for this CTYPEia, as for spctype().
    00430 *
    00431 *   crvalX    double*   Value of the X-type spectral variable at the reference
    00432 *                       point, SI units.
    00433 *
    00434 *   dXdS      double*   The derivative, dX/dS, evaluated at the reference
    00435 *                       point, SI units.  Multiply the CDELTia keyvalue by
    00436 *                       this to get the pixel spacing in the X-type spectral
    00437 *                       coordinate.
    00438 *
    00439 *   err       struct wcserr **
    00440 *                       If enabled, for function return values > 1, this
    00441 *                       struct will contain a detailed error message, see
    00442 *                       wcserr_enable().  May be NULL if an error message is
    00443 *                       not desired.  Otherwise, the user is responsible for
    00444 *                       deleting the memory allocated for the wcserr struct.
    00445 *
    00446 * Function return value:
    00447 *             int       Status return value:
    00448 *                         0: Success.
    00449 *                         2: Invalid spectral parameters.
    00450 *
    00451 *
    00452 * spcxpse() - Spectral keyword synthesis
    00453 * -------------------------------------
    00454 * spcxpse(), for the spectral axis type specified and the value provided for
    00455 * the X-type spectral variable at the reference point, deduces the value of
    00456 * the FITS spectral axis keyword CRVALia and also the derivative dS/dX which
    00457 * may be used to compute CDELTia.  See above for an explanation of the S-,
    00458 * P-, and X-type spectral variables.
    00459 *
    00460 * A deprecated form of this function, spcxps(), lacks the wcserr** parameter.
    00461 *
    00462 * Given:
    00463 *   ctypeS    const char[9]
    00464 *                       The required spectral axis type, i.e. the CTYPEia
    00465 *                       keyvalue, (eight characters with null termination).
    00466 *                       For non-grism axes, the character code for the P-type
    00467 *                       spectral variable in the algorithm code (i.e. the
    00468 *                       eighth character of CTYPEia) may be set to '?' (it
    00469 *                       will not be reset).
    00470 *
    00471 *   crvalX    double    Value of the X-type spectral variable at the reference
    00472 *                       point (N.B. NOT the CRVALia keyvalue), SI units.
    00473 *
    00474 *   restfrq,
    00475 *   restwav   double    Rest frequency [Hz] and rest wavelength in vacuo [m],
    00476 *                       only one of which need be given, the other should be
    00477 *                       set to zero.
    00478 *
    00479 * Returned:
    00480 *   ptype     char*     Character code for the P-type spectral variable
    00481 *                       derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
    00482 *
    00483 *   xtype     char*     Character code for the X-type spectral variable
    00484 *                       derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
    00485 *                       Also, 'w' and 'a' are synonymous to 'W' and 'A' for
    00486 *                       grisms; crvalX and cdeltX must conform to these.
    00487 *
    00488 *   restreq   int*      Multivalued flag that indicates whether rest frequency
    00489 *                       or wavelength is required to compute spectral
    00490 *                       variables for this CTYPEia, as for spctype().
    00491 *
    00492 *   crvalS    double*   Value of the S-type spectral variable at the reference
    00493 *                       point (i.e. the appropriate CRVALia keyvalue), SI
    00494 *                       units.
    00495 *
    00496 *   dSdX      double*   The derivative, dS/dX, evaluated at the reference
    00497 *                       point, SI units.  Multiply this by the pixel spacing
    00498 *                       in the X-type spectral coordinate to get the CDELTia
    00499 *                       keyvalue.
    00500 *
    00501 *   err       struct wcserr **
    00502 *                       If enabled, for function return values > 1, this
    00503 *                       struct will contain a detailed error message, see
    00504 *                       wcserr_enable().  May be NULL if an error message is
    00505 *                       not desired.  Otherwise, the user is responsible for
    00506 *                       deleting the memory allocated for the wcserr struct.
    00507 *
    00508 * Function return value:
    00509 *             int       Status return value:
    00510 *                         0: Success.
    00511 *                         2: Invalid spectral parameters.
    00512 *
    00513 *
    00514 * spctrne() - Spectral keyword translation
    00515 * ---------------------------------------
    00516 * spctrne() translates a set of FITS spectral axis keywords into the
    00517 * corresponding set for the specified spectral axis type.  For example, a
    00518 * 'FREQ' axis may be translated into 'ZOPT-F2W' and vice versa.
    00519 *
    00520 * A deprecated form of this function, spctrn(), lacks the wcserr** parameter.
    00521 *
    00522 * Given:
    00523 *   ctypeS1   const char[9]
    00524 *                       Spectral axis type, i.e. the CTYPEia keyvalue, (eight
    00525 *                       characters with null termination).  For non-grism
    00526 *                       axes, the character code for the P-type spectral
    00527 *                       variable in the algorithm code (i.e. the eighth
    00528 *                       character of CTYPEia) may be set to '?' (it will not
    00529 *                       be reset).
    00530 *
    00531 *   crvalS1   double    Value of the S-type spectral variable at the reference
    00532 *                       point, i.e. the CRVALia keyvalue, SI units.
    00533 *
    00534 *   cdeltS1   double    Increment of the S-type spectral variable at the
    00535 *                       reference point, SI units.
    00536 *
    00537 *   restfrq,
    00538 *   restwav   double    Rest frequency [Hz] and rest wavelength in vacuo [m],
    00539 *                       only one of which need be given, the other should be
    00540 *                       set to zero.  Neither are required if the translation
    00541 *                       is between wave-characteristic types, or between
    00542 *                       velocity-characteristic types.  E.g., required for
    00543 *                       'FREQ'     -> 'ZOPT-F2W', but not required for
    00544 *                       'VELO-F2V' -> 'ZOPT-F2W'.
    00545 *
    00546 * Given and returned:
    00547 *   ctypeS2   char[9]   Required spectral axis type (eight characters with
    00548 *                       null termination).  The first four characters are
    00549 *                       required to be given and are never modified.  The
    00550 *                       remaining four, the algorithm code, are completely
    00551 *                       determined by, and must be consistent with, ctypeS1
    00552 *                       and the first four characters of ctypeS2.  A non-zero
    00553 *                       status value will be returned if they are inconsistent
    00554 *                       (see below).  However, if the final three characters
    00555 *                       are specified as "???", or if just the eighth
    00556 *                       character is specified as '?', the correct algorithm
    00557 *                       code will be substituted (applies for grism axes as
    00558 *                       well as non-grism).
    00559 *
    00560 * Returned:
    00561 *   crvalS2   double*   Value of the new S-type spectral variable at the
    00562 *                       reference point, i.e. the new CRVALia keyvalue, SI
    00563 *                       units.
    00564 *
    00565 *   cdeltS2   double*   Increment of the new S-type spectral variable at the
    00566 *                       reference point, i.e. the new CDELTia keyvalue, SI
    00567 *                       units.
    00568 *
    00569 *   err       struct wcserr **
    00570 *                       If enabled, for function return values > 1, this
    00571 *                       struct will contain a detailed error message, see
    00572 *                       wcserr_enable().  May be NULL if an error message is
    00573 *                       not desired.  Otherwise, the user is responsible for
    00574 *                       deleting the memory allocated for the wcserr struct.
    00575 *
    00576 * Function return value:
    00577 *             int       Status return value:
    00578 *                         0: Success.
    00579 *                         2: Invalid spectral parameters.
    00580 *
    00581 *                       A status value of 2 will be returned if restfrq or
    00582 *                       restwav are not specified when required, or if ctypeS1
    00583 *                       or ctypeS2 are self-inconsistent, or have different
    00584 *                       spectral X-type variables.
    00585 *
    00586 *
    00587 * spcaips() - Translate AIPS-convention spectral keywords
    00588 * -------------------------------------------------------
    00589 * spcaips() translates AIPS-convention spectral CTYPEia and VELREF keyvalues.
    00590 *
    00591 * Given:
    00592 *   ctypeA    const char[9]
    00593 *                       CTYPEia keyvalue possibly containing an
    00594 *                       AIPS-convention spectral code (eight characters, need
    00595 *                       not be null-terminated).
    00596 *
    00597 *   velref    int       AIPS-convention VELREF code.  It has the following
    00598 *                       integer values:
    00599 *                         1: LSR kinematic, originally described simply as
    00600 *                            "LSR" without distinction between the kinematic
    00601 *                            and dynamic definitions.
    00602 *                         2: Barycentric, originally described as "HEL"
    00603 *                            meaning heliocentric.
    00604 *                         3: Topocentric, originally described as "OBS"
    00605 *                            meaning geocentric but widely interpreted as
    00606 *                            topocentric.
    00607 *                       AIPS++ extensions to VELREF are also recognized:
    00608 *                         4: LSR dynamic.
    00609 *                         5: Geocentric.
    00610 *                         6: Source rest frame.
    00611 *                         7: Galactocentric.
    00612 *
    00613 *                       For an AIPS 'VELO' axis, a radio convention velocity
    00614 *                       (VRAD) is denoted by adding 256 to VELREF, otherwise
    00615 *                       an optical velocity (VOPT) is indicated (this is not
    00616 *                       applicable to 'FREQ' or 'FELO' axes).  Setting velref
    00617 *                       to 0 or 256 chooses between optical and radio velocity
    00618 *                       without specifying a Doppler frame, provided that a
    00619 *                       frame is encoded in ctypeA.  If not, i.e. for
    00620 *                       ctypeA = 'VELO', ctype will be returned as 'VELO'.
    00621 *
    00622 *                       VELREF takes precedence over CTYPEia in defining the
    00623 *                       Doppler frame, e.g.
    00624 *
    00625 =                         ctypeA = 'VELO-HEL'
    00626 =                         velref = 1
    00627 *
    00628 *                       returns ctype = 'VOPT' with specsys set to 'LSRK'.
    00629 *
    00630 * Returned:
    00631 *   ctype     char[9]   Translated CTYPEia keyvalue, or a copy of ctypeA if no
    00632 *                       translation was performed (in which case any trailing
    00633 *                       blanks in ctypeA will be replaced with nulls).
    00634 *
    00635 *   specsys   char[9]   Doppler reference frame indicated by VELREF or else
    00636 *                       by CTYPEia with value corresponding to the SPECSYS
    00637 *                       keyvalue in the FITS WCS standard.  May be returned
    00638 *                       blank if neither specifies a Doppler frame, e.g.
    00639 *                       ctypeA = 'FELO' and velref%256 == 0.
    00640 *
    00641 * Function return value:
    00642 *             int       Status return value:
    00643 *                        -1: No translation required (not an error).
    00644 *                         0: Success.
    00645 *                         2: Invalid value of VELREF.
    00646 *
    00647 *
    00648 * spcprm struct - Spectral transformation parameters
    00649 * --------------------------------------------------
    00650 * The spcprm struct contains information required to transform spectral
    00651 * coordinates.  It consists of certain members that must be set by the user
    00652 * ("given") and others that are set by the WCSLIB routines ("returned").  Some
    00653 * of the latter are supplied for informational purposes while others are for
    00654 * internal use only.
    00655 *
    00656 *   int flag
    00657 *     (Given and returned) This flag must be set to zero whenever any of the
    00658 *     following spcprm structure members are set or changed:
    00659 *
    00660 *       - spcprm::type,
    00661 *       - spcprm::code,
    00662 *       - spcprm::crval,
    00663 *       - spcprm::restfrq,
    00664 *       - spcprm::restwav,
    00665 *       - spcprm::pv[].
    00666 *
    00667 *     This signals the initialization routine, spcset(), to recompute the
    00668 *     returned members of the spcprm struct.  spcset() will reset flag to
    00669 *     indicate that this has been done.
    00670 *
    00671 *   char type[8]
    00672 *     (Given) Four-letter spectral variable type, e.g "ZOPT" for
    00673 *     CTYPEia = 'ZOPT-F2W'.  (Declared as char[8] for alignment reasons.)
    00674 *
    00675 *   char code[4]
    00676 *     (Given) Three-letter spectral algorithm code, e.g "F2W" for
    00677 *     CTYPEia = 'ZOPT-F2W'.
    00678 *
    00679 *   double crval
    00680 *     (Given) Reference value (CRVALia), SI units.
    00681 *
    00682 *   double restfrq
    00683 *     (Given) The rest frequency [Hz], and ...
    00684 *
    00685 *   double restwav
    00686 *     (Given) ... the rest wavelength in vacuo [m], only one of which need be
    00687 *     given, the other should be set to zero.  Neither are required if the
    00688 *     X and S spectral variables are both wave-characteristic, or both
    00689 *     velocity-characteristic, types.
    00690 *
    00691 *   double pv[7]
    00692 *     (Given) Grism parameters for 'GRI' and 'GRA' algorithm codes:
    00693 *       - 0: G, grating ruling density.
    00694 *       - 1: m, interference order.
    00695 *       - 2: alpha, angle of incidence [deg].
    00696 *       - 3: n_r, refractive index at the reference wavelength, lambda_r.
    00697 *       - 4: n'_r, dn/dlambda at the reference wavelength, lambda_r (/m).
    00698 *       - 5: epsilon, grating tilt angle [deg].
    00699 *       - 6: theta, detector tilt angle [deg].
    00700 *
    00701 * The remaining members of the spcprm struct are maintained by spcset() and
    00702 * must not be modified elsewhere:
    00703 *
    00704 *   double w[6]
    00705 *     (Returned) Intermediate values:
    00706 *       - 0: Rest frequency or wavelength (SI).
    00707 *       - 1: The value of the X-type spectral variable at the reference point
    00708 *           (SI units).
    00709 *       - 2: dX/dS at the reference point (SI units).
    00710 *      The remainder are grism intermediates.
    00711 *
    00712 *   int isGrism
    00713 *     (Returned) Grism coordinates?
    00714 *       - 0: no,
    00715 *       - 1: in vacuum,
    00716 *       - 2: in air.
    00717 *
    00718 *   int padding1
    00719 *     (An unused variable inserted for alignment purposes only.)
    00720 *
    00721 *   struct wcserr *err
    00722 *     (Returned) If enabled, when an error status is returned this structure
    00723 *     contains detailed information about the error, see wcserr_enable().
    00724 *
    00725 *   void *padding2
    00726 *     (An unused variable inserted for alignment purposes only.)
    00727 *   int (*spxX2P)(SPX_ARGS)
    00728 *     (Returned) The first and ...
    00729 *   int (*spxP2S)(SPX_ARGS)
    00730 *     (Returned) ... the second of the pointers to the transformation
    00731 *     functions in the two-step algorithm chain X -> P -> S in the
    00732 *     pixel-to-spectral direction where the non-linear transformation is from
    00733 *     X to P.  The argument list, SPX_ARGS, is defined in spx.h.
    00734 *
    00735 *   int (*spxS2P)(SPX_ARGS)
    00736 *     (Returned) The first and ...
    00737 *   int (*spxP2X)(SPX_ARGS)
    00738 *     (Returned) ... the second of the pointers to the transformation
    00739 *     functions in the two-step algorithm chain S -> P -> X in the
    00740 *     spectral-to-pixel direction where the non-linear transformation is from
    00741 *     P to X.  The argument list, SPX_ARGS, is defined in spx.h.
    00742 *
    00743 *
    00744 * Global variable: const char *spc_errmsg[] - Status return messages
    00745 * ------------------------------------------------------------------
    00746 * Error messages to match the status value returned from each function.
    00747 *
    00748 *===========================================================================*/
    00749
    00750 #ifndef WCSLIB_SPC
    00751 #define WCSLIB_SPC
    00752
    00753 #include "spx.h"
    00754 #include "wcserr.h"
    00755
    00756 #ifdef __cplusplus
    00757 extern "C" {
    00758 #endif
    00759
    00760
    00761 extern const char *spc_errmsg[];
    00762
    00763 enum spc_errmsg_enum {
    00764   SPCERR_NO_CHANGE       = -1,  /* No change. */
    00765   SPCERR_SUCCESS         =  0,  /* Success. */
    00766   SPCERR_NULL_POINTER    =  1,  /* Null spcprm pointer passed. */
    00767   SPCERR_BAD_SPEC_PARAMS =  2,  /* Invalid spectral parameters. */
    00768   SPCERR_BAD_X           =  3,  /* One or more of x coordinates were
    00769                                    invalid. */
    00770   SPCERR_BAD_SPEC        =  4   /* One or more of the spec coordinates were
    00771                                    invalid. */
    00772 };
    00773
    00774 struct spcprm {
    00775   /* Initialization flag (see the prologue above).                          */
    00776   /*------------------------------------------------------------------------*/
    00777   int    flag;                  /* Set to zero to force initialization.     */
    00778
    00779   /* Parameters to be provided (see the prologue above).                    */
    00780   /*------------------------------------------------------------------------*/
    00781   char   type[8];               /* Four-letter spectral variable type.      */
    00782   char   code[4];               /* Three-letter spectral algorithm code.    */
    00783
    00784   double crval;                 /* Reference value (CRVALia), SI units.     */
    00785   double restfrq;               /* Rest frequency, Hz.                      */
    00786   double restwav;               /* Rest wavelength, m.                      */
    00787
    00788   double pv[7];                 /* Grism parameters:                        */
    00789                                 /*   0: G, grating ruling density.          */
    00790                                 /*   1: m, interference order.              */
    00791                                 /*   2: alpha, angle of incidence.          */
    00792                                 /*   3: n_r, refractive index at lambda_r.  */
    00793                                 /*   4: n'_r, dn/dlambda at lambda_r.       */
    00794                                 /*   5: epsilon, grating tilt angle.        */
    00795                                 /*   6: theta, detector tilt angle.         */
    00796
    00797   /* Information derived from the parameters supplied.                      */
    00798   /*------------------------------------------------------------------------*/
    00799   double w[6];                  /* Intermediate values.                     */
    00800                                 /*   0: Rest frequency or wavelength (SI).  */
    00801                                 /*   1: CRVALX (SI units).                  */
    00802                                 /*   2: CDELTX/CDELTia = dX/dS (SI units).  */
    00803                                 /* The remainder are grism intermediates.   */
    00804
    00805   int    isGrism;               /* Grism coordinates?  1: vacuum, 2: air.   */
    00806   int    padding1;              /* (Dummy inserted for alignment purposes.) */
    00807
    00808   /* Error handling                                                         */
    00809   /*------------------------------------------------------------------------*/
    00810   struct wcserr *err;
    00811
    00812   /* Private                                                                */
    00813   /*------------------------------------------------------------------------*/
    00814   void   *padding2;             /* (Dummy inserted for alignment purposes.) */
    00815   int (*spxX2P)(SPX_ARGS);      /* Pointers to the transformation functions */
    00816   int (*spxP2S)(SPX_ARGS);      /* in the two-step algorithm chain in the   */
    00817                                 /* pixel-to-spectral direction.             */
    00818
    00819   int (*spxS2P)(SPX_ARGS);      /* Pointers to the transformation functions */
    00820   int (*spxP2X)(SPX_ARGS);      /* in the two-step algorithm chain in the   */
    00821                                 /* spectral-to-pixel direction.             */
    00822 };
    00823
    00824 /* Size of the spcprm struct in int units, used by the Fortran wrappers. */
    00825 #define SPCLEN (sizeof(struct spcprm)/sizeof(int))
    00826
    00827
    00828 int spcini(struct spcprm *spc);
    00829
    00830 int spcfree(struct spcprm *spc);
    00831
    00832 int spcprt(const struct spcprm *spc);
    00833
    00834 int spcset(struct spcprm *spc);
    00835
    00836 int spcx2s(struct spcprm *spc, int nx, int sx, int sspec,
    00837            const double x[], double spec[], int stat[]);
    00838
    00839 int spcs2x(struct spcprm *spc, int nspec, int sspec, int sx,
    00840            const double spec[], double x[], int stat[]);
    00841
    00842 int spctype(const char ctype[9], char stype[], char scode[], char sname[],
    00843             char units[], char *ptype, char *xtype, int *restreq,
    00844             struct wcserr **err);
    00845
    00846 int spcspxe(const char ctypeS[9], double crvalS, double restfrq,
    00847             double restwav, char *ptype, char *xtype, int *restreq,
    00848             double *crvalX, double *dXdS, struct wcserr **err);
    00849
    00850 int spcxpse(const char ctypeS[9], double crvalX, double restfrq,
    00851             double restwav, char *ptype, char *xtype, int *restreq,
    00852             double *crvalS, double *dSdX, struct wcserr **err);
    00853
    00854 int spctrne(const char ctypeS1[9], double crvalS1, double cdeltS1,
    00855             double restfrq, double restwav, char ctypeS2[9], double *crvalS2,
    00856             double *cdeltS2, struct wcserr **err);
    00857
    00858 int spcaips(const char ctypeA[9], int velref, char ctype[9], char specsys[9]);
    00859
    00860
    00861 /* Deprecated. */
    00862 #define spcini_errmsg spc_errmsg
    00863 #define spcprt_errmsg spc_errmsg
    00864 #define spcset_errmsg spc_errmsg
    00865 #define spcx2s_errmsg spc_errmsg
    00866 #define spcs2x_errmsg spc_errmsg
    00867
    00868 int spctyp(const char ctype[9], char stype[], char scode[], char sname[],
    00869            char units[], char *ptype, char *xtype, int *restreq);
    00870 int spcspx(const char ctypeS[9], double crvalS, double restfrq,
    00871            double restwav, char *ptype, char *xtype, int *restreq,
    00872            double *crvalX, double *dXdS);
    00873 int spcxps(const char ctypeS[9], double crvalX, double restfrq,
    00874            double restwav, char *ptype, char *xtype, int *restreq,
    00875            double *crvalS, double *dSdX);
    00876 int spctrn(const char ctypeS1[9], double crvalS1, double cdeltS1,
    00877            double restfrq, double restwav, char ctypeS2[9], double *crvalS2,
    00878            double *cdeltS2);
    00879
    00880 #ifdef __cplusplus
    00881 }
    00882 #endif
    00883
    00884 #endif /* WCSLIB_SPC */