WCSLIB 4.20
spc.h
Go to the documentation of this file.
1 /*============================================================================
2 
3  WCSLIB 4.20 - an implementation of the FITS WCS standard.
4  Copyright (C) 1995-2013, 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_8h_source.html,v 1.1 2014/02/12 21:11:36 irby Exp $
26 *=============================================================================
27 *
28 * WCSLIB 4.20 - 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
757 extern "C" {
758 #endif
759 
760 
761 extern const char *spc_errmsg[];
762 
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 
774 struct 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 
828 int spcini(struct spcprm *spc);
829 
830 int spcfree(struct spcprm *spc);
831 
832 int spcprt(const struct spcprm *spc);
833 
834 int spcset(struct spcprm *spc);
835 
836 int spcx2s(struct spcprm *spc, int nx, int sx, int sspec,
837  const double x[], double spec[], int stat[]);
838 
839 int spcs2x(struct spcprm *spc, int nspec, int sspec, int sx,
840  const double spec[], double x[], int stat[]);
841 
842 int 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 
846 int 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 
850 int 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 
854 int 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 
858 int 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 
868 int spctyp(const char ctype[9], char stype[], char scode[], char sname[],
869  char units[], char *ptype, char *xtype, int *restreq);
870 int spcspx(const char ctypeS[9], double crvalS, double restfrq,
871  double restwav, char *ptype, char *xtype, int *restreq,
872  double *crvalX, double *dXdS);
873 int spcxps(const char ctypeS[9], double crvalX, double restfrq,
874  double restwav, char *ptype, char *xtype, int *restreq,
875  double *crvalS, double *dSdX);
876 int 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 */