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