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