1/*============================================================================
2
3 WCSLIB 4.23 - an implementation of the FITS WCS standard.
4 Copyright (C) 1995-2014, Mark Calabretta
5
6 This file is part of WCSLIB.
7
8 WCSLIB is free software: you can redistribute it and/or modify it under the
9 terms of the GNU Lesser General Public License as published by the Free
10 Software Foundation, either version 3 of the License, or (at your option)
11 any later version.
12
13 WCSLIB is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16 more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with WCSLIB. If not, see http://www.gnu.org/licenses.
20
21 Direct correspondence concerning WCSLIB to mark@calabretta.id.au
22
23 Author: Mark Calabretta, Australia Telescope National Facility, CSIRO.
24 http://www.atnf.csiro.au/people/Mark.Calabretta
25 $Id: spc.h,v 4.23 2014/05/13 05:50:51 mcalabre Exp $
26*=============================================================================
27*
28* WCSLIB 4.23 - C routines that implement the spectral coordinate systems
29* recognized by the FITS World Coordinate System (WCS) standard. Refer to
30*
31* "Representations of world coordinates in FITS",
32* Greisen, E.W., & Calabretta, M.R. 2002, A&A, 395, 1061 (Paper I)
33*
34* "Representations of spectral coordinates in FITS",
35* Greisen, E.W., Calabretta, M.R., Valdes, F.G., & Allen, S.L.
36* 2006, A&A, 446, 747 (Paper III)
37*
38* Refer to the README file provided with WCSLIB for an overview of the
39* library.
40*
41*
42* Summary of the spc routines
43* ---------------------------
44* These routines implement the part of the FITS WCS standard that deals with
45* spectral coordinates. They define methods to be used for computing spectral
46* world coordinates from intermediate world coordinates (a linear
47* transformation of image pixel coordinates), and vice versa. They are based
48* on the spcprm struct which contains all information needed for the
49* computations. The struct contains some members that must be set by the
50* user, and others that are maintained by these routines, somewhat like a
51* C++ class but with no encapsulation.
52*
53* Routine spcini() is provided to initialize the spcprm struct with default
54* values, spcfree() reclaims any memory that may have been allocated to store
55* an error message, and spcprt() prints its contents.
56*
57* A setup routine, spcset(), computes intermediate values in the spcprm struct
58* from parameters in it that were supplied by the user. The struct always
59* needs to be set up by spcset() but it need not be called explicitly - refer
60* to the explanation of spcprm::flag.
61*
62* spcx2s() and spcs2x() implement the WCS spectral coordinate transformations.
63* In fact, they are high level driver routines for the lower level spectral
64* coordinate transformation routines described in spx.h.
65*
66* A number of routines are provided to aid in analysing or synthesising sets
67* of FITS spectral axis keywords:
68*
69* - spctype() checks a spectral CTYPEia keyword for validity and returns
70* information derived from it.
71*
72* - Spectral keyword analysis routine spcspxe() computes the values of the
73* X-type spectral variables for the S-type variables supplied.
74*
75* - Spectral keyword synthesis routine, spcxpse(), computes the S-type
76* variables for the X-types supplied.
77*
78* - Given a set of spectral keywords, a translation routine, spctrne(),
79* produces the corresponding set for the specified spectral CTYPEia.
80*
81* - spcaips() translates AIPS-convention spectral CTYPEia and VELREF
82* keyvalues.
83*
84* Spectral variable types - S, P, and X:
85* --------------------------------------
86* A few words of explanation are necessary regarding spectral variable types
87* in FITS.
88*
89* Every FITS spectral axis has three associated spectral variables:
90*
91* S-type: the spectral variable in which coordinates are to be
92* expressed. Each S-type is encoded as four characters and is
93* linearly related to one of four basic types as follows:
94*
95* F: frequency
96* 'FREQ': frequency
97* 'AFRQ': angular frequency
98* 'ENER': photon energy
99* 'WAVN': wave number
100* 'VRAD': radio velocity
101*
102* W: wavelength in vacuo
103* 'WAVE': wavelength
104* 'VOPT': optical velocity
105* 'ZOPT': redshift
106*
107* A: wavelength in air
108* 'AWAV': wavelength in air
109*
110* V: velocity
111* 'VELO': relativistic velocity
112* 'BETA': relativistic beta factor
113*
114* The S-type forms the first four characters of the CTYPEia keyvalue,
115* and CRVALia and CDELTia are expressed as S-type quantities so that
116* they provide a first-order approximation to the S-type variable at
117* the reference point.
118*
119* Note that 'AFRQ', angular frequency, is additional to the variables
120* defined in WCS Paper III.
121*
122* P-type: the basic spectral variable (F, W, A, or V) with which the
123* S-type variable is associated (see list above).
124*
125* For non-grism axes, the P-type is encoded as the eighth character of
126* CTYPEia.
127*
128* X-type: the basic spectral variable (F, W, A, or V) for which the
129* spectral axis is linear, grisms excluded (see below).
130*
131* For non-grism axes, the X-type is encoded as the sixth character of
132* CTYPEia.
133*
134* Grisms: Grism axes have normal S-, and P-types but the axis is linear,
135* not in any spectral variable, but in a special "grism parameter".
136* The X-type spectral variable is either W or A for grisms in vacuo or
137* air respectively, but is encoded as 'w' or 'a' to indicate that an
138* additional transformation is required to convert to or from the
139* grism parameter. The spectral algorithm code for grisms also has a
140* special encoding in CTYPEia, either 'GRI' (in vacuo) or 'GRA' (in air).
141*
142* In the algorithm chain, the non-linear transformation occurs between the
143* X-type and the P-type variables; the transformation between P-type and
144* S-type variables is always linear.
145*
146* When the P-type and X-type variables are the same, the spectral axis is
147* linear in the S-type variable and the second four characters of CTYPEia
148* are blank. This can never happen for grism axes.
149*
150* As an example, correlating radio spectrometers always produce spectra that
151* are regularly gridded in frequency; a redshift scale on such a spectrum is
152* non-linear. The required value of CTYPEia would be 'ZOPT-F2W', where the
153* desired S-type is 'ZOPT' (redshift), the P-type is necessarily 'W'
154* (wavelength), and the X-type is 'F' (frequency) by the nature of the
155* instrument.
156*
157* Argument checking:
158* ------------------
159* The input spectral values are only checked for values that would result in
160* floating point exceptions. In particular, negative frequencies and
161* wavelengths are allowed, as are velocities greater than the speed of
162* light. The same is true for the spectral parameters - rest frequency and
163* wavelength.
164*
165* Accuracy:
166* ---------
167* No warranty is given for the accuracy of these routines (refer to the
168* copyright notice); intending users must satisfy for themselves their
169* adequacy for the intended purpose. However, closure effectively to within
170* double precision rounding error was demonstrated by test routine tspc.c
171* which accompanies this software.
172*
173*
174* spcini() - Default constructor for the spcprm struct
175* ----------------------------------------------------
176* spcini() sets all members of a spcprm struct to default values. It should
177* be used to initialize every spcprm struct.
178*
179* Given and returned:
180* spc struct spcprm*
181* Spectral transformation parameters.
182*
183* Function return value:
184* int Status return value:
185* 0: Success.
186* 1: Null spcprm pointer passed.
187*
188*
189* spcfree() - Destructor for the spcprm struct
190* --------------------------------------------
191* spcfree() frees any memory that may have been allocated to store an error
192* message in the spcprm struct.
193*
194* Given:
195* spc struct spcprm*
196* Spectral transformation parameters.
197*
198* Function return value:
199* int Status return value:
200* 0: Success.
201* 1: Null spcprm pointer passed.
202*
203*
204* spcprt() - Print routine for the spcprm struct
205* ----------------------------------------------
206* spcprt() prints the contents of a spcprm struct using wcsprintf(). Mainly
207* intended for diagnostic purposes.
208*
209* Given:
210* spc const struct spcprm*
211* Spectral transformation parameters.
212*
213* Function return value:
214* int Status return value:
215* 0: Success.
216* 1: Null spcprm pointer passed.
217*
218*
219* spcset() - Setup routine for the spcprm struct
220* ----------------------------------------------
221* spcset() sets up a spcprm struct according to information supplied within
222* it.
223*
224* Note that this routine need not be called directly; it will be invoked by
225* spcx2s() and spcs2x() if spcprm::flag is anything other than a predefined
226* magic value.
227*
228* Given and returned:
229* spc struct spcprm*
230* Spectral transformation parameters.
231*
232* Function return value:
233* int Status return value:
234* 0: Success.
235* 1: Null spcprm pointer passed.
236* 2: Invalid spectral parameters.
237*
238* For returns > 1, a detailed error message is set in
239* spcprm::err if enabled, see wcserr_enable().
240*
241*
242* spcx2s() - Transform to spectral coordinates
243* --------------------------------------------
244* spcx2s() transforms intermediate world coordinates to spectral coordinates.
245*
246* Given and returned:
247* spc struct spcprm*
248* Spectral transformation parameters.
249*
250* Given:
251* nx int Vector length.
252*
253* sx int Vector stride.
254*
255* sspec int Vector stride.
256*
257* x const double[]
258* Intermediate world coordinates, in SI units.
259*
260* Returned:
261* spec double[] Spectral coordinates, in SI units.
262*
263* stat int[] Status return value status for each vector element:
264* 0: Success.
265* 1: Invalid value of x.
266*
267* Function return value:
268* int Status return value:
269* 0: Success.
270* 1: Null spcprm pointer passed.
271* 2: Invalid spectral parameters.
272* 3: One or more of the x coordinates were invalid,
273* as indicated by the stat vector.
274*
275* For returns > 1, a detailed error message is set in
276* spcprm::err if enabled, see wcserr_enable().
277*
278*
279* spcs2x() - Transform spectral coordinates
280* -----------------------------------------
281* spcs2x() transforms spectral world coordinates to intermediate world
282* coordinates.
283*
284* Given and returned:
285* spc struct spcprm*
286* Spectral transformation parameters.
287*
288* Given:
289* nspec int Vector length.
290*
291* sspec int Vector stride.
292*
293* sx int Vector stride.
294*
295* spec const double[]
296* Spectral coordinates, in SI units.
297*
298* Returned:
299* x double[] Intermediate world coordinates, in SI units.
300*
301* stat int[] Status return value status for each vector element:
302* 0: Success.
303* 1: Invalid value of spec.
304*
305* Function return value:
306* int Status return value:
307* 0: Success.
308* 1: Null spcprm pointer passed.
309* 2: Invalid spectral parameters.
310* 4: One or more of the spec coordinates were
311* invalid, as indicated by the stat vector.
312*
313* For returns > 1, a detailed error message is set in
314* spcprm::err if enabled, see wcserr_enable().
315*
316*
317* spctype() - Spectral CTYPEia keyword analysis
318* ---------------------------------------------
319* spctype() checks whether a CTYPEia keyvalue is a valid spectral axis type
320* and if so returns information derived from it relating to the associated S-,
321* P-, and X-type spectral variables (see explanation above).
322*
323* The return arguments are guaranteed not be modified if CTYPEia is not a
324* valid spectral type; zero-pointers may be specified for any that are not of
325* interest.
326*
327* A deprecated form of this function, spctyp(), lacks the wcserr** parameter.
328*
329* Given:
330* ctype const char[9]
331* The CTYPEia keyvalue, (eight characters with null
332* termination).
333*
334* Returned:
335* stype char[] The four-letter name of the S-type spectral variable
336* copied or translated from ctype. If a non-zero
337* pointer is given, the array must accomodate a null-
338* terminated string of length 5.
339*
340* scode char[] The three-letter spectral algorithm code copied or
341* translated from ctype. Logarithmic ('LOG') and
342* tabular ('TAB') codes are also recognized. If a
343* non-zero pointer is given, the array must accomodate a
344* null-terminated string of length 4.
345*
346* sname char[] Descriptive name of the S-type spectral variable.
347* If a non-zero pointer is given, the array must
348* accomodate a null-terminated string of length 22.
349*
350* units char[] SI units of the S-type spectral variable. If a
351* non-zero pointer is given, the array must accomodate a
352* null-terminated string of length 8.
353*
354* ptype char* Character code for the P-type spectral variable
355* derived from ctype, one of 'F', 'W', 'A', or 'V'.
356*
357* xtype char* Character code for the X-type spectral variable
358* derived from ctype, one of 'F', 'W', 'A', or 'V'.
359* Also, 'w' and 'a' are synonymous to 'W' and 'A' for
360* grisms in vacuo and air respectively. Set to 'L' or
361* 'T' for logarithmic ('LOG') and tabular ('TAB') axes.
362*
363* restreq int* Multivalued flag that indicates whether rest
364* frequency or wavelength is required to compute
365* spectral variables for this CTYPEia:
366* 0: Not required.
367* 1: Required for the conversion between S- and
368* P-types (e.g. 'ZOPT-F2W').
369* 2: Required for the conversion between P- and
370* X-types (e.g. 'BETA-W2V').
371* 3: Required for the conversion between S- and
372* P-types, and between P- and X-types, but not
373* between S- and X-types (this applies only for
374* 'VRAD-V2F', 'VOPT-V2W', and 'ZOPT-V2W').
375* Thus the rest frequency or wavelength is required for
376* spectral coordinate computations (i.e. between S- and
377* X-types) only if restreq%3 != 0.
378*
379* err struct wcserr **
380* If enabled, for function return values > 1, this
381* struct will contain a detailed error message, see
382* wcserr_enable(). May be NULL if an error message is
383* not desired. Otherwise, the user is responsible for
384* deleting the memory allocated for the wcserr struct.
385*
386* Function return value:
387* int Status return value:
388* 0: Success.
389* 2: Invalid spectral parameters (not a spectral
390* CTYPEia).
391*
392*
393* spcspxe() - Spectral keyword analysis
394* ------------------------------------
395* spcspxe() analyses the CTYPEia and CRVALia FITS spectral axis keyword values
396* and returns information about the associated X-type spectral variable.
397*
398* A deprecated form of this function, spcspx(), lacks the wcserr** parameter.
399*
400* Given:
401* ctypeS const char[9]
402* Spectral axis type, i.e. the CTYPEia keyvalue, (eight
403* characters with null termination). For non-grism
404* axes, the character code for the P-type spectral
405* variable in the algorithm code (i.e. the eighth
406* character of CTYPEia) may be set to '?' (it will not
407* be reset).
408*
409* crvalS double Value of the S-type spectral variable at the reference
410* point, i.e. the CRVALia keyvalue, SI units.
411*
412* restfrq,
413* restwav double Rest frequency [Hz] and rest wavelength in vacuo [m],
414* only one of which need be given, the other should be
415* set to zero.
416*
417* Returned:
418* ptype char* Character code for the P-type spectral variable
419* derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
420*
421* xtype char* Character code for the X-type spectral variable
422* derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
423* Also, 'w' and 'a' are synonymous to 'W' and 'A' for
424* grisms in vacuo and air respectively; crvalX and dXdS
425* (see below) will conform to these.
426*
427* restreq int* Multivalued flag that indicates whether rest frequency
428* or wavelength is required to compute spectral
429* variables for this CTYPEia, as for spctype().
430*
431* crvalX double* Value of the X-type spectral variable at the reference
432* point, SI units.
433*
434* dXdS double* The derivative, dX/dS, evaluated at the reference
435* point, SI units. Multiply the CDELTia keyvalue by
436* this to get the pixel spacing in the X-type spectral
437* coordinate.
438*
439* err struct wcserr **
440* If enabled, for function return values > 1, this
441* struct will contain a detailed error message, see
442* wcserr_enable(). May be NULL if an error message is
443* not desired. Otherwise, the user is responsible for
444* deleting the memory allocated for the wcserr struct.
445*
446* Function return value:
447* int Status return value:
448* 0: Success.
449* 2: Invalid spectral parameters.
450*
451*
452* spcxpse() - Spectral keyword synthesis
453* -------------------------------------
454* spcxpse(), for the spectral axis type specified and the value provided for
455* the X-type spectral variable at the reference point, deduces the value of
456* the FITS spectral axis keyword CRVALia and also the derivative dS/dX which
457* may be used to compute CDELTia. See above for an explanation of the S-,
458* P-, and X-type spectral variables.
459*
460* A deprecated form of this function, spcxps(), lacks the wcserr** parameter.
461*
462* Given:
463* ctypeS const char[9]
464* The required spectral axis type, i.e. the CTYPEia
465* keyvalue, (eight characters with null termination).
466* For non-grism axes, the character code for the P-type
467* spectral variable in the algorithm code (i.e. the
468* eighth character of CTYPEia) may be set to '?' (it
469* will not be reset).
470*
471* crvalX double Value of the X-type spectral variable at the reference
472* point (N.B. NOT the CRVALia keyvalue), SI units.
473*
474* restfrq,
475* restwav double Rest frequency [Hz] and rest wavelength in vacuo [m],
476* only one of which need be given, the other should be
477* set to zero.
478*
479* Returned:
480* ptype char* Character code for the P-type spectral variable
481* derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
482*
483* xtype char* Character code for the X-type spectral variable
484* derived from ctypeS, one of 'F', 'W', 'A', or 'V'.
485* Also, 'w' and 'a' are synonymous to 'W' and 'A' for
486* grisms; crvalX and cdeltX must conform to these.
487*
488* restreq int* Multivalued flag that indicates whether rest frequency
489* or wavelength is required to compute spectral
490* variables for this CTYPEia, as for spctype().
491*
492* crvalS double* Value of the S-type spectral variable at the reference
493* point (i.e. the appropriate CRVALia keyvalue), SI
494* units.
495*
496* dSdX double* The derivative, dS/dX, evaluated at the reference
497* point, SI units. Multiply this by the pixel spacing
498* in the X-type spectral coordinate to get the CDELTia
499* keyvalue.
500*
501* err struct wcserr **
502* If enabled, for function return values > 1, this
503* struct will contain a detailed error message, see
504* wcserr_enable(). May be NULL if an error message is
505* not desired. Otherwise, the user is responsible for
506* deleting the memory allocated for the wcserr struct.
507*
508* Function return value:
509* int Status return value:
510* 0: Success.
511* 2: Invalid spectral parameters.
512*
513*
514* spctrne() - Spectral keyword translation
515* ---------------------------------------
516* spctrne() translates a set of FITS spectral axis keywords into the
517* corresponding set for the specified spectral axis type. For example, a
518* 'FREQ' axis may be translated into 'ZOPT-F2W' and vice versa.
519*
520* A deprecated form of this function, spctrn(), lacks the wcserr** parameter.
521*
522* Given:
523* ctypeS1 const char[9]
524* Spectral axis type, i.e. the CTYPEia keyvalue, (eight
525* characters with null termination). For non-grism
526* axes, the character code for the P-type spectral
527* variable in the algorithm code (i.e. the eighth
528* character of CTYPEia) may be set to '?' (it will not
529* be reset).
530*
531* crvalS1 double Value of the S-type spectral variable at the reference
532* point, i.e. the CRVALia keyvalue, SI units.
533*
534* cdeltS1 double Increment of the S-type spectral variable at the
535* reference point, SI units.
536*
537* restfrq,
538* restwav double Rest frequency [Hz] and rest wavelength in vacuo [m],
539* only one of which need be given, the other should be
540* set to zero. Neither are required if the translation
541* is between wave-characteristic types, or between
542* velocity-characteristic types. E.g., required for
543* 'FREQ' -> 'ZOPT-F2W', but not required for
544* 'VELO-F2V' -> 'ZOPT-F2W'.
545*
546* Given and returned:
547* ctypeS2 char[9] Required spectral axis type (eight characters with
548* null termination). The first four characters are
549* required to be given and are never modified. The
550* remaining four, the algorithm code, are completely
551* determined by, and must be consistent with, ctypeS1
552* and the first four characters of ctypeS2. A non-zero
553* status value will be returned if they are inconsistent
554* (see below). However, if the final three characters
555* are specified as "???", or if just the eighth
556* character is specified as '?', the correct algorithm
557* code will be substituted (applies for grism axes as
558* well as non-grism).
559*
560* Returned:
561* crvalS2 double* Value of the new S-type spectral variable at the
562* reference point, i.e. the new CRVALia keyvalue, SI
563* units.
564*
565* cdeltS2 double* Increment of the new S-type spectral variable at the
566* reference point, i.e. the new CDELTia keyvalue, SI
567* units.
568*
569* err struct wcserr **
570* If enabled, for function return values > 1, this
571* struct will contain a detailed error message, see
572* wcserr_enable(). May be NULL if an error message is
573* not desired. Otherwise, the user is responsible for
574* deleting the memory allocated for the wcserr struct.
575*
576* Function return value:
577* int Status return value:
578* 0: Success.
579* 2: Invalid spectral parameters.
580*
581* A status value of 2 will be returned if restfrq or
582* restwav are not specified when required, or if ctypeS1
583* or ctypeS2 are self-inconsistent, or have different
584* spectral X-type variables.
585*
586*
587* spcaips() - Translate AIPS-convention spectral keywords
588* -------------------------------------------------------
589* spcaips() translates AIPS-convention spectral CTYPEia and VELREF keyvalues.
590*
591* Given:
592* ctypeA const char[9]
593* CTYPEia keyvalue possibly containing an
594* AIPS-convention spectral code (eight characters, need
595* not be null-terminated).
596*
597* velref int AIPS-convention VELREF code. It has the following
598* integer values:
599* 1: LSR kinematic, originally described simply as
600* "LSR" without distinction between the kinematic
601* and dynamic definitions.
602* 2: Barycentric, originally described as "HEL"
603* meaning heliocentric.
604* 3: Topocentric, originally described as "OBS"
605* meaning geocentric but widely interpreted as
606* topocentric.
607* AIPS++ extensions to VELREF are also recognized:
608* 4: LSR dynamic.
609* 5: Geocentric.
610* 6: Source rest frame.
611* 7: Galactocentric.
612*
613* For an AIPS 'VELO' axis, a radio convention velocity
614* (VRAD) is denoted by adding 256 to VELREF, otherwise
615* an optical velocity (VOPT) is indicated (this is not
616* applicable to 'FREQ' or 'FELO' axes). Setting velref
617* to 0 or 256 chooses between optical and radio velocity
618* without specifying a Doppler frame, provided that a
619* frame is encoded in ctypeA. If not, i.e. for
620* ctypeA = 'VELO', ctype will be returned as 'VELO'.
621*
622* VELREF takes precedence over CTYPEia in defining the
623* Doppler frame, e.g.
624*
625= ctypeA = 'VELO-HEL'
626= velref = 1
627*
628* returns ctype = 'VOPT' with specsys set to 'LSRK'.
629*
630* Returned:
631* ctype char[9] Translated CTYPEia keyvalue, or a copy of ctypeA if no
632* translation was performed (in which case any trailing
633* blanks in ctypeA will be replaced with nulls).
634*
635* specsys char[9] Doppler reference frame indicated by VELREF or else
636* by CTYPEia with value corresponding to the SPECSYS
637* keyvalue in the FITS WCS standard. May be returned
638* blank if neither specifies a Doppler frame, e.g.
639* ctypeA = 'FELO' and velref%256 == 0.
640*
641* Function return value:
642* int Status return value:
643* -1: No translation required (not an error).
644* 0: Success.
645* 2: Invalid value of VELREF.
646*
647*
648* spcprm struct - Spectral transformation parameters
649* --------------------------------------------------
650* The spcprm struct contains information required to transform spectral
651* coordinates. It consists of certain members that must be set by the user
652* ("given") and others that are set by the WCSLIB routines ("returned"). Some
653* of the latter are supplied for informational purposes while others are for
654* internal use only.
655*
656* int flag
657* (Given and returned) This flag must be set to zero whenever any of the
658* following spcprm structure members are set or changed:
659*
660* - spcprm::type,
661* - spcprm::code,
662* - spcprm::crval,
663* - spcprm::restfrq,
664* - spcprm::restwav,
665* - spcprm::pv[].
666*
667* This signals the initialization routine, spcset(), to recompute the
668* returned members of the spcprm struct. spcset() will reset flag to
669* indicate that this has been done.
670*
671* char type[8]
672* (Given) Four-letter spectral variable type, e.g "ZOPT" for
673* CTYPEia = 'ZOPT-F2W'. (Declared as char[8] for alignment reasons.)
674*
675* char code[4]
676* (Given) Three-letter spectral algorithm code, e.g "F2W" for
677* CTYPEia = 'ZOPT-F2W'.
678*
679* double crval
680* (Given) Reference value (CRVALia), SI units.
681*
682* double restfrq
683* (Given) The rest frequency [Hz], and ...
684*
685* double restwav
686* (Given) ... the rest wavelength in vacuo [m], only one of which need be
687* given, the other should be set to zero. Neither are required if the
688* X and S spectral variables are both wave-characteristic, or both
689* velocity-characteristic, types.
690*
691* double pv[7]
692* (Given) Grism parameters for 'GRI' and 'GRA' algorithm codes:
693* - 0: G, grating ruling density.
694* - 1: m, interference order.
695* - 2: alpha, angle of incidence [deg].
696* - 3: n_r, refractive index at the reference wavelength, lambda_r.
697* - 4: n'_r, dn/dlambda at the reference wavelength, lambda_r (/m).
698* - 5: epsilon, grating tilt angle [deg].
699* - 6: theta, detector tilt angle [deg].
700*
701* The remaining members of the spcprm struct are maintained by spcset() and
702* must not be modified elsewhere:
703*
704* double w[6]
705* (Returned) Intermediate values:
706* - 0: Rest frequency or wavelength (SI).
707* - 1: The value of the X-type spectral variable at the reference point
708* (SI units).
709* - 2: dX/dS at the reference point (SI units).
710* The remainder are grism intermediates.
711*
712* int isGrism
713* (Returned) Grism coordinates?
714* - 0: no,
715* - 1: in vacuum,
716* - 2: in air.
717*
718* int padding1
719* (An unused variable inserted for alignment purposes only.)
720*
721* struct wcserr *err
722* (Returned) If enabled, when an error status is returned this structure
723* contains detailed information about the error, see wcserr_enable().
724*
725* void *padding2
726* (An unused variable inserted for alignment purposes only.)
727* int (*spxX2P)(SPX_ARGS)
728* (Returned) The first and ...
729* int (*spxP2S)(SPX_ARGS)
730* (Returned) ... the second of the pointers to the transformation
731* functions in the two-step algorithm chain X -> P -> S in the
732* pixel-to-spectral direction where the non-linear transformation is from
733* X to P. The argument list, SPX_ARGS, is defined in spx.h.
734*
735* int (*spxS2P)(SPX_ARGS)
736* (Returned) The first and ...
737* int (*spxP2X)(SPX_ARGS)
738* (Returned) ... the second of the pointers to the transformation
739* functions in the two-step algorithm chain S -> P -> X in the
740* spectral-to-pixel direction where the non-linear transformation is from
741* P to X. The argument list, SPX_ARGS, is defined in spx.h.
742*
743*
744* Global variable: const char *spc_errmsg[] - Status return messages
745* ------------------------------------------------------------------
746* Error messages to match the status value returned from each function.
747*
748*===========================================================================*/
749
750#ifndef WCSLIB_SPC
751#define WCSLIB_SPC
752
753#include "spx.h"
754#include "wcserr.h"
755
756#ifdef __cplusplus
757extern "C" {
758#endif
759
760
761extern const char *spc_errmsg[];
762
763enum spc_errmsg_enum {
764 SPCERR_NO_CHANGE = -1, /* No change. */
765 SPCERR_SUCCESS = 0, /* Success. */
766 SPCERR_NULL_POINTER = 1, /* Null spcprm pointer passed. */
767 SPCERR_BAD_SPEC_PARAMS = 2, /* Invalid spectral parameters. */
768 SPCERR_BAD_X = 3, /* One or more of x coordinates were
769 invalid. */
770 SPCERR_BAD_SPEC = 4 /* One or more of the spec coordinates were
771 invalid. */
772};
773
774struct spcprm {
775 /* Initialization flag (see the prologue above). */
776 /*------------------------------------------------------------------------*/
777 int flag; /* Set to zero to force initialization. */
778
779 /* Parameters to be provided (see the prologue above). */
780 /*------------------------------------------------------------------------*/
781 char type[8]; /* Four-letter spectral variable type. */
782 char code[4]; /* Three-letter spectral algorithm code. */
783
784 double crval; /* Reference value (CRVALia), SI units. */
785 double restfrq; /* Rest frequency, Hz. */
786 double restwav; /* Rest wavelength, m. */
787
788 double pv[7]; /* Grism parameters: */
789 /* 0: G, grating ruling density. */
790 /* 1: m, interference order. */
791 /* 2: alpha, angle of incidence. */
792 /* 3: n_r, refractive index at lambda_r. */
793 /* 4: n'_r, dn/dlambda at lambda_r. */
794 /* 5: epsilon, grating tilt angle. */
795 /* 6: theta, detector tilt angle. */
796
797 /* Information derived from the parameters supplied. */
798 /*------------------------------------------------------------------------*/
799 double w[6]; /* Intermediate values. */
800 /* 0: Rest frequency or wavelength (SI). */
801 /* 1: CRVALX (SI units). */
802 /* 2: CDELTX/CDELTia = dX/dS (SI units). */
803 /* The remainder are grism intermediates. */
804
805 int isGrism; /* Grism coordinates? 1: vacuum, 2: air. */
806 int padding1; /* (Dummy inserted for alignment purposes.) */
807
808 /* Error handling */
809 /*------------------------------------------------------------------------*/
810 struct wcserr *err;
811
812 /* Private */
813 /*------------------------------------------------------------------------*/
814 void *padding2; /* (Dummy inserted for alignment purposes.) */
815 int (*spxX2P)(SPX_ARGS); /* Pointers to the transformation functions */
816 int (*spxP2S)(SPX_ARGS); /* in the two-step algorithm chain in the */
817 /* pixel-to-spectral direction. */
818
819 int (*spxS2P)(SPX_ARGS); /* Pointers to the transformation functions */
820 int (*spxP2X)(SPX_ARGS); /* in the two-step algorithm chain in the */
821 /* spectral-to-pixel direction. */
822};
823
824/* Size of the spcprm struct in int units, used by the Fortran wrappers. */
825#define SPCLEN (sizeof(struct spcprm)/sizeof(int))
826
827
828int spcini(struct spcprm *spc);
829
830int spcfree(struct spcprm *spc);
831
832int spcprt(const struct spcprm *spc);
833
834int spcset(struct spcprm *spc);
835
836int spcx2s(struct spcprm *spc, int nx, int sx, int sspec,
837 const double x[], double spec[], int stat[]);
838
839int spcs2x(struct spcprm *spc, int nspec, int sspec, int sx,
840 const double spec[], double x[], int stat[]);
841
842int spctype(const char ctype[9], char stype[], char scode[], char sname[],
843 char units[], char *ptype, char *xtype, int *restreq,
844 struct wcserr **err);
845
846int spcspxe(const char ctypeS[9], double crvalS, double restfrq,
847 double restwav, char *ptype, char *xtype, int *restreq,
848 double *crvalX, double *dXdS, struct wcserr **err);
849
850int spcxpse(const char ctypeS[9], double crvalX, double restfrq,
851 double restwav, char *ptype, char *xtype, int *restreq,
852 double *crvalS, double *dSdX, struct wcserr **err);
853
854int spctrne(const char ctypeS1[9], double crvalS1, double cdeltS1,
855 double restfrq, double restwav, char ctypeS2[9], double *crvalS2,
856 double *cdeltS2, struct wcserr **err);
857
858int spcaips(const char ctypeA[9], int velref, char ctype[9], char specsys[9]);
859
860
861/* Deprecated. */
862#define spcini_errmsg spc_errmsg
863#define spcprt_errmsg spc_errmsg
864#define spcset_errmsg spc_errmsg
865#define spcx2s_errmsg spc_errmsg
866#define spcs2x_errmsg spc_errmsg
867
868int spctyp(const char ctype[9], char stype[], char scode[], char sname[],
869 char units[], char *ptype, char *xtype, int *restreq);
870int spcspx(const char ctypeS[9], double crvalS, double restfrq,
871 double restwav, char *ptype, char *xtype, int *restreq,
872 double *crvalX, double *dXdS);
873int spcxps(const char ctypeS[9], double crvalX, double restfrq,
874 double restwav, char *ptype, char *xtype, int *restreq,
875 double *crvalS, double *dSdX);
876int spctrn(const char ctypeS1[9], double crvalS1, double cdeltS1,
877 double restfrq, double restwav, char ctypeS2[9], double *crvalS2,
878 double *cdeltS2);
879
880#ifdef __cplusplus
881}
882#endif
883
884#endif /* WCSLIB_SPC */
885