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