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