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: spx.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 spx routines
43* ---------------------------
44* specx() is a scalar routine that, given one spectral variable (e.g.
45* frequency), computes all the others (e.g. wavelength, velocity, etc.) plus
46* the required derivatives of each with respect to the others. The results
47* are returned in the spxprm struct.
48*
49* The remaining routines are all vector conversions from one spectral
50* variable to another. The API of these functions only differ in whether the
51* rest frequency or wavelength need be supplied.
52*
53* Non-linear:
54* - freqwave() frequency -> vacuum wavelength
55* - wavefreq() vacuum wavelength -> frequency
56*
57* - freqawav() frequency -> air wavelength
58* - awavfreq() air wavelength -> frequency
59*
60* - freqvelo() frequency -> relativistic velocity
61* - velofreq() relativistic velocity -> frequency
62*
63* - waveawav() vacuum wavelength -> air wavelength
64* - awavwave() air wavelength -> vacuum wavelength
65*
66* - wavevelo() vacuum wavelength -> relativistic velocity
67* - velowave() relativistic velocity -> vacuum wavelength
68*
69* - awavvelo() air wavelength -> relativistic velocity
70* - veloawav() relativistic velocity -> air wavelength
71*
72* Linear:
73* - freqafrq() frequency -> angular frequency
74* - afrqfreq() angular frequency -> frequency
75*
76* - freqener() frequency -> energy
77* - enerfreq() energy -> frequency
78*
79* - freqwavn() frequency -> wave number
80* - wavnfreq() wave number -> frequency
81*
82* - freqvrad() frequency -> radio velocity
83* - vradfreq() radio velocity -> frequency
84*
85* - wavevopt() vacuum wavelength -> optical velocity
86* - voptwave() optical velocity -> vacuum wavelength
87*
88* - wavezopt() vacuum wavelength -> redshift
89* - zoptwave() redshift -> vacuum wavelength
90*
91* - velobeta() relativistic velocity -> beta (= v/c)
92* - betavelo() beta (= v/c) -> relativistic velocity
93*
94* These are the workhorse routines, to be used for fast transformations.
95* Conversions may be done "in place" by calling the routine with the output
96* vector set to the input.
97*
98* Argument checking:
99* ------------------
100* The input spectral values are only checked for values that would result
101* in floating point exceptions. In particular, negative frequencies and
102* wavelengths are allowed, as are velocities greater than the speed of
103* light. The same is true for the spectral parameters - rest frequency and
104* wavelength.
105*
106* Accuracy:
107* ---------
108* No warranty is given for the accuracy of these routines (refer to the
109* copyright notice); intending users must satisfy for themselves their
110* adequacy for the intended purpose. However, closure effectively to within
111* double precision rounding error was demonstrated by test routine tspec.c
112* which accompanies this software.
113*
114*
115* specx() - Spectral cross conversions (scalar)
116* ---------------------------------------------
117* Given one spectral variable specx() computes all the others, plus the
118* required derivatives of each with respect to the others.
119*
120* Given:
121* type const char*
122* The type of spectral variable given by spec, FREQ,
123* AFRQ, ENER, WAVN, VRAD, WAVE, VOPT, ZOPT, AWAV, VELO,
124* or BETA (case sensitive).
125*
126* spec double The spectral variable given, in SI units.
127*
128* restfrq,
129* restwav double Rest frequency [Hz] or rest wavelength in vacuo [m],
130* only one of which need be given. The other should be
131* set to zero. If both are zero, only a subset of the
132* spectral variables can be computed, the remainder are
133* set to zero. Specifically, given one of FREQ, AFRQ,
134* ENER, WAVN, WAVE, or AWAV the others can be computed
135* without knowledge of the rest frequency. Likewise,
136* VRAD, VOPT, ZOPT, VELO, and BETA.
137*
138* Given and returned:
139* specs struct spxprm*
140* Data structure containing all spectral variables and
141* their derivatives, in SI units.
142*
143* Function return value:
144* int Status return value:
145* 0: Success.
146* 1: Null spxprm pointer passed.
147* 2: Invalid spectral parameters.
148* 3: Invalid spectral variable.
149*
150* For returns > 1, a detailed error message is set in
151* spxprm::err if enabled, see wcserr_enable().
152*
153* freqafrq(), afrqfreq(), freqener(), enerfreq(), freqwavn(), wavnfreq(),
154* freqwave(), wavefreq(), freqawav(), awavfreq(), waveawav(), awavwave(),
155* velobeta(), and betavelo() implement vector conversions between wave-like
156* or velocity-like spectral types (i.e. conversions that do not need the rest
157* frequency or wavelength). They all have the same API.
158*
159*
160* freqafrq() - Convert frequency to angular frequency (vector)
161* ------------------------------------------------------------
162* freqafrq() converts frequency to angular frequency.
163*
164* Given:
165* param double Ignored.
166*
167* nspec int Vector length.
168*
169* instep,
170* outstep int Vector strides.
171*
172* inspec const double[]
173* Input spectral variables, in SI units.
174*
175* Returned:
176* outspec double[] Output spectral variables, in SI units.
177*
178* stat int[] Status return value for each vector element:
179* 0: Success.
180* 1: Invalid value of inspec.
181*
182* Function return value:
183* int Status return value:
184* 0: Success.
185* 2: Invalid spectral parameters.
186* 4: One or more of the inspec coordinates were
187* invalid, as indicated by the stat vector.
188*
189*
190* freqvelo(), velofreq(), freqvrad(), and vradfreq() implement vector
191* conversions between frequency and velocity spectral types. They all have
192* the same API.
193*
194*
195* freqvelo() - Convert frequency to relativistic velocity (vector)
196* ----------------------------------------------------------------
197* freqvelo() converts frequency to relativistic velocity.
198*
199* Given:
200* param double Rest frequency [Hz].
201*
202* nspec int Vector length.
203*
204* instep,
205* outstep int Vector strides.
206*
207* inspec const double[]
208* Input spectral variables, in SI units.
209*
210* Returned:
211* outspec double[] Output spectral variables, in SI units.
212*
213* stat int[] Status return value for each vector element:
214* 0: Success.
215* 1: Invalid value of inspec.
216*
217* Function return value:
218* int Status return value:
219* 0: Success.
220* 2: Invalid spectral parameters.
221* 4: One or more of the inspec coordinates were
222* invalid, as indicated by the stat vector.
223*
224*
225* wavevelo(), velowave(), awavvelo(), veloawav(), wavevopt(), voptwave(),
226* wavezopt(), and zoptwave() implement vector conversions between wavelength
227* and velocity spectral types. They all have the same API.
228*
229*
230* wavevelo() - Conversions between wavelength and velocity types (vector)
231* -----------------------------------------------------------------------
232* wavevelo() converts vacuum wavelength to relativistic velocity.
233*
234* Given:
235* param double Rest wavelength in vacuo [m].
236*
237* nspec int Vector length.
238*
239* instep,
240* outstep int Vector strides.
241*
242* inspec const double[]
243* Input spectral variables, in SI units.
244*
245* Returned:
246* outspec double[] Output spectral variables, in SI units.
247*
248* stat int[] Status return value for each vector element:
249* 0: Success.
250* 1: Invalid value of inspec.
251*
252* Function return value:
253* int Status return value:
254* 0: Success.
255* 2: Invalid spectral parameters.
256* 4: One or more of the inspec coordinates were
257* invalid, as indicated by the stat vector.
258*
259*
260* spxprm struct - Spectral variables and their derivatives
261* --------------------------------------------------------
262* The spxprm struct contains the value of all spectral variables and their
263* derivatives. It is used solely by specx() which constructs it from
264* information provided via its function arguments.
265*
266* This struct should be considered read-only, no members need ever be set nor
267* should ever be modified by the user.
268*
269* double restfrq
270* (Returned) Rest frequency [Hz].
271*
272* double restwav
273* (Returned) Rest wavelength [m].
274*
275* int wavetype
276* (Returned) True if wave types have been computed, and ...
277*
278* int velotype
279* (Returned) ... true if velocity types have been computed; types are
280* defined below.
281*
282* If one or other of spxprm::restfrq and spxprm::restwav is given
283* (non-zero) then all spectral variables may be computed. If both are
284* given, restfrq is used. If restfrq and restwav are both zero, only wave
285* characteristic xor velocity type spectral variables may be computed
286* depending on the variable given. These flags indicate what is
287* available.
288*
289* double freq
290* (Returned) Frequency [Hz] (wavetype).
291*
292* double afrq
293* (Returned) Angular frequency [rad/s] (wavetype).
294*
295* double ener
296* (Returned) Photon energy [J] (wavetype).
297*
298* double wavn
299* (Returned) Wave number [/m] (wavetype).
300*
301* double vrad
302* (Returned) Radio velocity [m/s] (velotype).
303*
304* double wave
305* (Returned) Vacuum wavelength [m] (wavetype).
306*
307* double vopt
308* (Returned) Optical velocity [m/s] (velotype).
309*
310* double zopt
311* (Returned) Redshift [dimensionless] (velotype).
312*
313* double awav
314* (Returned) Air wavelength [m] (wavetype).
315*
316* double velo
317* (Returned) Relativistic velocity [m/s] (velotype).
318*
319* double beta
320* (Returned) Relativistic beta [dimensionless] (velotype).
321*
322* double dfreqafrq
323* (Returned) Derivative of frequency with respect to angular frequency
324* [/rad] (constant, = 1 / 2*pi), and ...
325* double dafrqfreq
326* (Returned) ... vice versa [rad] (constant, = 2*pi, always available).
327*
328* double dfreqener
329* (Returned) Derivative of frequency with respect to photon energy
330* [/J/s] (constant, = 1/h), and ...
331* double denerfreq
332* (Returned) ... vice versa [Js] (constant, = h, Planck's constant,
333* always available).
334*
335* double dfreqwavn
336* (Returned) Derivative of frequency with respect to wave number [m/s]
337* (constant, = c, the speed of light in vacuo), and ...
338* double dwavnfreq
339* (Returned) ... vice versa [s/m] (constant, = 1/c, always available).
340*
341* double dfreqvrad
342* (Returned) Derivative of frequency with respect to radio velocity [/m],
343* and ...
344* double dvradfreq
345* (Returned) ... vice versa [m] (wavetype && velotype).
346*
347* double dfreqwave
348* (Returned) Derivative of frequency with respect to vacuum wavelength
349* [/m/s], and ...
350* double dwavefreq
351* (Returned) ... vice versa [m s] (wavetype).
352*
353* double dfreqawav
354* (Returned) Derivative of frequency with respect to air wavelength,
355* [/m/s], and ...
356* double dawavfreq
357* (Returned) ... vice versa [m s] (wavetype).
358*
359* double dfreqvelo
360* (Returned) Derivative of frequency with respect to relativistic
361* velocity [/m], and ...
362* double dvelofreq
363* (Returned) ... vice versa [m] (wavetype && velotype).
364*
365* double dwavevopt
366* (Returned) Derivative of vacuum wavelength with respect to optical
367* velocity [s], and ...
368* double dvoptwave
369* (Returned) ... vice versa [/s] (wavetype && velotype).
370*
371* double dwavezopt
372* (Returned) Derivative of vacuum wavelength with respect to redshift [m],
373* and ...
374* double dzoptwave
375* (Returned) ... vice versa [/m] (wavetype && velotype).
376*
377* double dwaveawav
378* (Returned) Derivative of vacuum wavelength with respect to air
379* wavelength [dimensionless], and ...
380* double dawavwave
381* (Returned) ... vice versa [dimensionless] (wavetype).
382*
383* double dwavevelo
384* (Returned) Derivative of vacuum wavelength with respect to relativistic
385* velocity [s], and ...
386* double dvelowave
387* (Returned) ... vice versa [/s] (wavetype && velotype).
388*
389* double dawavvelo
390* (Returned) Derivative of air wavelength with respect to relativistic
391* velocity [s], and ...
392* double dveloawav
393* (Returned) ... vice versa [/s] (wavetype && velotype).
394*
395* double dvelobeta
396* (Returned) Derivative of relativistic velocity with respect to
397* relativistic beta [m/s] (constant, = c, the speed of light in vacuo),
398* and ...
399* double dbetavelo
400* (Returned) ... vice versa [s/m] (constant, = 1/c, always available).
401*
402* struct wcserr *err
403* (Returned) If enabled, when an error status is returned this struct
404* contains detailed information about the error, see wcserr_enable().
405*
406* void *padding
407* (An unused variable inserted for alignment purposes only.)
408*
409* Global variable: const char *spx_errmsg[] - Status return messages
410* ------------------------------------------------------------------
411* Error messages to match the status value returned from each function.
412*
413*===========================================================================*/
414
415#ifndef WCSLIB_SPEC
416#define WCSLIB_SPEC
417
418#ifdef __cplusplus
419extern "C" {
420#endif
421
422#include "wcserr.h"
423
424extern const char *spx_errmsg[];
425
426enum spx_errmsg {
427 SPXERR_SUCCESS = 0, /* Success. */
428 SPXERR_NULL_POINTER = 1, /* Null spxprm pointer passed. */
429 SPXERR_BAD_SPEC_PARAMS = 2, /* Invalid spectral parameters. */
430 SPXERR_BAD_SPEC_VAR = 3, /* Invalid spectral variable. */
431 SPXERR_BAD_INSPEC_COORD = 4 /* One or more of the inspec coordinates were
432 invalid. */
433};
434
435struct spxprm {
436 double restfrq, restwav; /* Rest frequency [Hz] and wavelength [m]. */
437
438 int wavetype, velotype; /* True if wave/velocity types have been */
439 /* computed; types are defined below. */
440
441 /* Spectral variables computed by specx(). */
442 /*------------------------------------------------------------------------*/
443 double freq, /* wavetype: Frequency [Hz]. */
444 afrq, /* wavetype: Angular frequency [rad/s]. */
445 ener, /* wavetype: Photon energy [J]. */
446 wavn, /* wavetype: Wave number [/m]. */
447 vrad, /* velotype: Radio velocity [m/s]. */
448 wave, /* wavetype: Vacuum wavelength [m]. */
449 vopt, /* velotype: Optical velocity [m/s]. */
450 zopt, /* velotype: Redshift. */
451 awav, /* wavetype: Air wavelength [m]. */
452 velo, /* velotype: Relativistic velocity [m/s]. */
453 beta; /* velotype: Relativistic beta. */
454
455 /* Derivatives of spectral variables computed by specx(). */
456 /*------------------------------------------------------------------------*/
457 double dfreqafrq, dafrqfreq, /* Constant, always available. */
458 dfreqener, denerfreq, /* Constant, always available. */
459 dfreqwavn, dwavnfreq, /* Constant, always available. */
460 dfreqvrad, dvradfreq, /* wavetype && velotype. */
461 dfreqwave, dwavefreq, /* wavetype. */
462 dfreqawav, dawavfreq, /* wavetype. */
463 dfreqvelo, dvelofreq, /* wavetype && velotype. */
464 dwavevopt, dvoptwave, /* wavetype && velotype. */
465 dwavezopt, dzoptwave, /* wavetype && velotype. */
466 dwaveawav, dawavwave, /* wavetype. */
467 dwavevelo, dvelowave, /* wavetype && velotype. */
468 dawavvelo, dveloawav, /* wavetype && velotype. */
469 dvelobeta, dbetavelo; /* Constant, always available. */
470
471 /* Error handling */
472 /*------------------------------------------------------------------------*/
473 struct wcserr *err;
474
475 /* Private */
476 /*------------------------------------------------------------------------*/
477 void *padding; /* (Dummy inserted for alignment purposes.) */
478};
479
480/* Size of the spxprm struct in int units, used by the Fortran wrappers. */
481#define SPXLEN (sizeof(struct spxprm)/sizeof(int))
482
483
484int specx(const char *type, double spec, double restfrq, double restwav,
485 struct spxprm *specs);
486
487
488/* For use in declaring function prototypes, e.g. in spcprm. */
489#define SPX_ARGS double param, int nspec, int instep, int outstep, \
490 const double inspec[], double outspec[], int stat[]
491
492int freqafrq(SPX_ARGS);
493int afrqfreq(SPX_ARGS);
494
495int freqener(SPX_ARGS);
496int enerfreq(SPX_ARGS);
497
498int freqwavn(SPX_ARGS);
499int wavnfreq(SPX_ARGS);
500
501int freqwave(SPX_ARGS);
502int wavefreq(SPX_ARGS);
503
504int freqawav(SPX_ARGS);
505int awavfreq(SPX_ARGS);
506
507int waveawav(SPX_ARGS);
508int awavwave(SPX_ARGS);
509
510int velobeta(SPX_ARGS);
511int betavelo(SPX_ARGS);
512
513
514int freqvelo(SPX_ARGS);
515int velofreq(SPX_ARGS);
516
517int freqvrad(SPX_ARGS);
518int vradfreq(SPX_ARGS);
519
520
521int wavevelo(SPX_ARGS);
522int velowave(SPX_ARGS);
523
524int awavvelo(SPX_ARGS);
525int veloawav(SPX_ARGS);
526
527int wavevopt(SPX_ARGS);
528int voptwave(SPX_ARGS);
529
530int wavezopt(SPX_ARGS);
531int zoptwave(SPX_ARGS);
532
533
534#ifdef __cplusplus
535}
536#endif
537
538#endif /* WCSLIB_SPEC */
539