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: spx.c,v 7.7 2021/07/12 06:36:49 mcalabre Exp $
23 *===========================================================================*/
24
25 #include <math.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "wcserr.h"
30 #include "wcsmath.h"
31 #include "spx.h"
32
33
34 // Map status return value to message.
35 const char *spx_errmsg[] = {
36 "Success",
37 "Null spxprm pointer passed",
38 "Invalid spectral parameters",
39 "Invalid spectral variable",
40 "One or more of the inspec coordinates were invalid"};
41
42 // Convenience macro for invoking wcserr_set().
43 #define SPX_ERRMSG(status) WCSERR_SET(status), spx_errmsg[status]
44
45 #define C 2.99792458e8
46 #define h 6.6260755e-34
47
48 /*============================================================================
49 * Spectral cross conversions; given one spectral coordinate it computes all
50 * the others, plus the required derivatives of each with respect to the
51 * others.
52 *===========================================================================*/
53
specx(const char * type,double spec,double restfrq,double restwav,struct spxprm * spx)54 int specx(
55 const char *type,
56 double spec,
57 double restfrq,
58 double restwav,
59 struct spxprm *spx)
60
61 {
62 static const char *function = "specx";
63
64 register int k;
65 int haverest;
66 double beta, dwaveawav, gamma, n, s, t, u;
67 struct wcserr **err;
68
69 if (spx == 0x0) return SPXERR_NULL_POINTER;
70 err = &(spx->err);
71
72 haverest = 1;
73 if (restfrq == 0.0) {
74 if (restwav == 0.0) {
75 // No line rest frequency supplied.
76 haverest = 0;
77
78 // Temporarily set a dummy value for conversions.
79 spx->restwav = 1.0;
80 } else {
81 spx->restwav = restwav;
82 }
83 spx->restfrq = C/spx->restwav;
84
85 } else {
86 spx->restfrq = restfrq;
87 spx->restwav = C/restfrq;
88 }
89
90 spx->err = 0x0;
91
92 // Convert to frequency.
93 spx->wavetype = 0;
94 spx->velotype = 0;
95 if (strcmp(type, "FREQ") == 0) {
96 if (spec == 0.0) {
97 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
98 "Invalid spectral variable: frequency == 0");
99 }
100 spx->freq = spec;
101 spx->wavetype = 1;
102
103 } else if (strcmp(type, "AFRQ") == 0) {
104 if (spec == 0.0) {
105 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
106 "Invalid spectral variable: frequency == 0");
107 }
108 spx->freq = spec/(2.0*PI);
109 spx->wavetype = 1;
110
111 } else if (strcmp(type, "ENER") == 0) {
112 if (spec == 0.0) {
113 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
114 "Invalid spectral variable: frequency == 0");
115 }
116 spx->freq = spec/h;
117 spx->wavetype = 1;
118
119 } else if (strcmp(type, "WAVN") == 0) {
120 if (spec == 0.0) {
121 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
122 "Invalid spectral variable: frequency == 0");
123 }
124 spx->freq = spec*C;
125 spx->wavetype = 1;
126
127 } else if (strcmp(type, "VRAD") == 0) {
128 spx->freq = spx->restfrq*(1.0 - spec/C);
129 spx->velotype = 1;
130
131 } else if (strcmp(type, "WAVE") == 0) {
132 if (spec == 0.0) {
133 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
134 "Invalid spectral variable: frequency == 0");
135 }
136 spx->freq = C/spec;
137 spx->wavetype = 1;
138
139 } else if (strcmp(type, "VOPT") == 0) {
140 s = 1.0 + spec/C;
141 if (s == 0.0) {
142 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
143 "Invalid spectral variable");
144 }
145 spx->freq = spx->restfrq/s;
146 spx->velotype = 1;
147
148 } else if (strcmp(type, "ZOPT") == 0) {
149 s = 1.0 + spec;
150 if (s == 0.0) {
151 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
152 "Invalid spectral variable");
153 }
154 spx->freq = spx->restfrq/s;
155 spx->velotype = 1;
156
157 } else if (strcmp(type, "AWAV") == 0) {
158 if (spec == 0.0) {
159 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
160 "Invalid spectral variable");
161 }
162 s = 1.0/spec;
163 s *= s;
164 n = 2.554e8 / (0.41e14 - s);
165 n += 294.981e8 / (1.46e14 - s);
166 n += 1.000064328;
167 spx->freq = C/(spec*n);
168 spx->wavetype = 1;
169
170 } else if (strcmp(type, "VELO") == 0) {
171 beta = spec/C;
172 if (fabs(beta) == 1.0) {
173 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
174 "Invalid spectral variable");
175 }
176 spx->freq = spx->restfrq*(1.0 - beta)/sqrt(1.0 - beta*beta);
177 spx->velotype = 1;
178
179 } else if (strcmp(type, "BETA") == 0) {
180 if (fabs(spec) == 1.0) {
181 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_VAR),
182 "Invalid spectral variable");
183 }
184 spx->freq = spx->restfrq*(1.0 - spec)/sqrt(1.0 - spec*spec);
185 spx->velotype = 1;
186
187 } else {
188 // Unrecognized type.
189 return wcserr_set(WCSERR_SET(SPXERR_BAD_SPEC_PARAMS),
190 "Unrecognized spectral type '%s'", type);
191 }
192
193
194 // Convert frequency to the other spectral types.
195 n = 1.0;
196 for (k = 0; k < 4; k++) {
197 s = n*spx->freq/C;
198 s *= s;
199 t = 0.41e14 - s;
200 u = 1.46e14 - s;
201 n = 1.000064328 + (2.554e8/t + 294.981e8/u);
202 }
203
204 dwaveawav = n - 2.0*s*(2.554e8/(t*t) + 294.981e8/(u*u));
205
206 s = spx->freq/spx->restfrq;
207
208 spx->ener = spx->freq*h;
209 spx->afrq = spx->freq*(2.0*PI);
210 spx->wavn = spx->freq/C;
211 spx->vrad = C*(1.0 - s);
212 spx->wave = C/spx->freq;
213 spx->awav = spx->wave/n;
214 spx->vopt = C*(1.0/s - 1.0);
215 spx->zopt = spx->vopt/C;
216 spx->velo = C*(1.0 - s*s)/(1.0 + s*s);
217 spx->beta = spx->velo/C;
218
219 // Compute the required derivatives.
220 gamma = 1.0/sqrt(1.0 - spx->beta*spx->beta);
221
222 spx->dfreqafrq = 1.0/(2.0*PI);
223 spx->dafrqfreq = 1.0/spx->dfreqafrq;
224
225 spx->dfreqener = 1.0/h;
226 spx->denerfreq = 1.0/spx->dfreqener;
227
228 spx->dfreqwavn = C;
229 spx->dwavnfreq = 1.0/spx->dfreqwavn;
230
231 spx->dfreqvrad = -spx->restfrq/C;
232 spx->dvradfreq = 1.0/spx->dfreqvrad;
233
234 spx->dfreqwave = -spx->freq/spx->wave;
235 spx->dwavefreq = 1.0/spx->dfreqwave;
236
237 spx->dfreqawav = spx->dfreqwave * dwaveawav;
238 spx->dawavfreq = 1.0/spx->dfreqawav;
239
240 spx->dfreqvelo = -gamma*spx->restfrq/(C + spx->velo);
241 spx->dvelofreq = 1.0/spx->dfreqvelo;
242
243 spx->dwavevopt = spx->restwav/C;
244 spx->dvoptwave = 1.0/spx->dwavevopt;
245
246 spx->dwavezopt = spx->restwav;
247 spx->dzoptwave = 1.0/spx->dwavezopt;
248
249 spx->dwaveawav = dwaveawav;
250 spx->dawavwave = 1.0/spx->dwaveawav;
251
252 spx->dwavevelo = gamma*spx->restwav/(C - spx->velo);
253 spx->dvelowave = 1.0/spx->dwavevelo;
254
255 spx->dawavvelo = spx->dwavevelo/dwaveawav;
256 spx->dveloawav = 1.0/spx->dawavvelo;
257
258 spx->dvelobeta = C;
259 spx->dbetavelo = 1.0/spx->dvelobeta;
260
261
262 // Reset values if no line rest frequency was supplied.
263 if (haverest) {
264 spx->wavetype = 1;
265 spx->velotype = 1;
266
267 } else {
268 spx->restfrq = 0.0;
269 spx->restwav = 0.0;
270
271 if (!spx->wavetype) {
272 // Don't have wave characteristic types.
273 spx->freq = 0.0;
274 spx->afrq = 0.0;
275 spx->ener = 0.0;
276 spx->wavn = 0.0;
277 spx->wave = 0.0;
278 spx->awav = 0.0;
279
280 spx->dfreqwave = 0.0;
281 spx->dwavefreq = 0.0;
282
283 spx->dfreqawav = 0.0;
284 spx->dawavfreq = 0.0;
285
286 spx->dwaveawav = 0.0;
287 spx->dawavwave = 0.0;
288
289 } else {
290 // Don't have velocity types.
291 spx->vrad = 0.0;
292 spx->vopt = 0.0;
293 spx->zopt = 0.0;
294 spx->velo = 0.0;
295 spx->beta = 0.0;
296 }
297
298 spx->dfreqvrad = 0.0;
299 spx->dvradfreq = 0.0;
300
301 spx->dfreqvelo = 0.0;
302 spx->dvelofreq = 0.0;
303
304 spx->dwavevopt = 0.0;
305 spx->dvoptwave = 0.0;
306
307 spx->dwavezopt = 0.0;
308 spx->dzoptwave = 0.0;
309
310 spx->dwavevelo = 0.0;
311 spx->dvelowave = 0.0;
312
313 spx->dawavvelo = 0.0;
314 spx->dveloawav = 0.0;
315 }
316
317 return 0;
318 }
319
320 //----------------------------------------------------------------------------
321
spxperr(const struct spxprm * spx,const char * prefix)322 int spxperr(const struct spxprm *spx, const char *prefix)
323
324 {
325 if (spx == 0x0) return SPXERR_NULL_POINTER;
326
327 if (spx->err) {
328 wcserr_prt(spx->err, prefix);
329 }
330
331 return 0;
332 }
333
334
335 /*============================================================================
336 * Conversions between frequency and vacuum wavelength.
337 *===========================================================================*/
338
freqwave(double dummy,int nfreq,int sfreq,int swave,const double freq[],double wave[],int stat[])339 int freqwave(
340 double dummy,
341 int nfreq,
342 int sfreq,
343 int swave,
344 const double freq[],
345 double wave[],
346 int stat[])
347
348 {
349 int status = 0;
350 register int ifreq, *statp;
351 register const double *freqp;
352 register double *wavep;
353
354 // Avert nuisance compiler warnings about unused parameters.
355 (void)dummy;
356
357 freqp = freq;
358 wavep = wave;
359 statp = stat;
360 for (ifreq = 0; ifreq < nfreq; ifreq++) {
361 if (*freqp != 0.0) {
362 *wavep = C/(*freqp);
363 *(statp++) = 0;
364 } else {
365 *(statp++) = 1;
366 status = SPXERR_BAD_INSPEC_COORD;
367 }
368
369 freqp += sfreq;
370 wavep += swave;
371 }
372
373 return status;
374 }
375
376 //----------------------------------------------------------------------------
377
wavefreq(double dummy,int nwave,int swave,int sfreq,const double wave[],double freq[],int stat[])378 int wavefreq(
379 double dummy,
380 int nwave,
381 int swave,
382 int sfreq,
383 const double wave[],
384 double freq[],
385 int stat[])
386
387 {
388 int status = 0;
389 register int iwave, *statp;
390 register const double *wavep;
391 register double *freqp;
392
393 // Avert nuisance compiler warnings about unused parameters.
394 (void)dummy;
395
396 wavep = wave;
397 freqp = freq;
398 statp = stat;
399 for (iwave = 0; iwave < nwave; iwave++) {
400 if (*wavep != 0.0) {
401 *freqp = C/(*wavep);
402 *(statp++) = 0;
403 } else {
404 *(statp++) = 1;
405 status = SPXERR_BAD_INSPEC_COORD;
406 }
407
408 wavep += swave;
409 freqp += sfreq;
410 }
411
412 return status;
413 }
414
415 /*============================================================================
416 * Conversions between frequency and air wavelength.
417 *===========================================================================*/
418
freqawav(double dummy,int nfreq,int sfreq,int sawav,const double freq[],double awav[],int stat[])419 int freqawav(
420 double dummy,
421 int nfreq,
422 int sfreq,
423 int sawav,
424 const double freq[],
425 double awav[],
426 int stat[])
427
428 {
429 int status;
430
431 if ((status = freqwave(dummy, nfreq, sfreq, sawav, freq, awav, stat))) {
432 return status;
433 }
434
435 return waveawav(dummy, nfreq, sawav, sawav, awav, awav, stat);
436 }
437
438 //----------------------------------------------------------------------------
439
awavfreq(double dummy,int nawav,int sawav,int sfreq,const double awav[],double freq[],int stat[])440 int awavfreq(
441 double dummy,
442 int nawav,
443 int sawav,
444 int sfreq,
445 const double awav[],
446 double freq[],
447 int stat[])
448
449 {
450 int status;
451
452 if ((status = awavwave(dummy, nawav, sawav, sfreq, awav, freq, stat))) {
453 return status;
454 }
455
456 return wavefreq(dummy, nawav, sfreq, sfreq, freq, freq, stat);
457 }
458
459 /*============================================================================
460 * Conversions between frequency and relativistic velocity.
461 *===========================================================================*/
462
freqvelo(double restfrq,int nfreq,int sfreq,int svelo,const double freq[],double velo[],int stat[])463 int freqvelo(
464 double restfrq,
465 int nfreq,
466 int sfreq,
467 int svelo,
468 const double freq[],
469 double velo[],
470 int stat[])
471
472 {
473 double r, s;
474 register int ifreq, *statp;
475 register const double *freqp;
476 register double *velop;
477
478 r = restfrq*restfrq;
479
480 freqp = freq;
481 velop = velo;
482 statp = stat;
483 for (ifreq = 0; ifreq < nfreq; ifreq++) {
484 s = *freqp * *freqp;
485 *velop = C*(r - s)/(r + s);
486 *(statp++) = 0;
487
488 freqp += sfreq;
489 velop += svelo;
490 }
491
492 return 0;
493 }
494
495 //----------------------------------------------------------------------------
496
velofreq(double restfrq,int nvelo,int svelo,int sfreq,const double velo[],double freq[],int stat[])497 int velofreq(
498 double restfrq,
499 int nvelo,
500 int svelo,
501 int sfreq,
502 const double velo[],
503 double freq[],
504 int stat[])
505
506 {
507 int status = 0;
508 double s;
509 register int ivelo, *statp;
510 register const double *velop;
511 register double *freqp;
512
513 velop = velo;
514 freqp = freq;
515 statp = stat;
516 for (ivelo = 0; ivelo < nvelo; ivelo++) {
517 s = C + *velop;
518 if (s != 0.0) {
519 *freqp = restfrq*sqrt((C - *velop)/s);
520 *(statp++) = 0;
521 } else {
522 *(statp++) = 1;
523 status = SPXERR_BAD_INSPEC_COORD;
524 }
525
526 velop += svelo;
527 freqp += sfreq;
528 }
529
530 return status;
531 }
532
533 /*============================================================================
534 * Conversions between vacuum wavelength and air wavelength.
535 *===========================================================================*/
536
waveawav(double dummy,int nwave,int swave,int sawav,const double wave[],double awav[],int stat[])537 int waveawav(
538 double dummy,
539 int nwave,
540 int swave,
541 int sawav,
542 const double wave[],
543 double awav[],
544 int stat[])
545
546 {
547 int status = 0;
548 double n, s;
549 register int iwave, k, *statp;
550 register const double *wavep;
551 register double *awavp;
552
553 // Avert nuisance compiler warnings about unused parameters.
554 (void)dummy;
555
556 wavep = wave;
557 awavp = awav;
558 statp = stat;
559 for (iwave = 0; iwave < nwave; iwave++) {
560 if (*wavep != 0.0) {
561 n = 1.0;
562 for (k = 0; k < 4; k++) {
563 s = n/(*wavep);
564 s *= s;
565 n = 2.554e8 / (0.41e14 - s);
566 n += 294.981e8 / (1.46e14 - s);
567 n += 1.000064328;
568 }
569
570 *awavp = (*wavep)/n;
571 *(statp++) = 0;
572 } else {
573 *(statp++) = 1;
574 status = SPXERR_BAD_INSPEC_COORD;
575 }
576
577 wavep += swave;
578 awavp += sawav;
579 }
580
581 return status;
582 }
583
584 //----------------------------------------------------------------------------
585
awavwave(double dummy,int nawav,int sawav,int swave,const double awav[],double wave[],int stat[])586 int awavwave(
587 double dummy,
588 int nawav,
589 int sawav,
590 int swave,
591 const double awav[],
592 double wave[],
593 int stat[])
594
595 {
596 int status = 0;
597 double n, s;
598 register int iawav, *statp;
599 register const double *awavp;
600 register double *wavep;
601
602 // Avert nuisance compiler warnings about unused parameters.
603 (void)dummy;
604
605 awavp = awav;
606 wavep = wave;
607 statp = stat;
608 for (iawav = 0; iawav < nawav; iawav++) {
609 if (*awavp != 0.0) {
610 s = 1.0/(*awavp);
611 s *= s;
612 n = 2.554e8 / (0.41e14 - s);
613 n += 294.981e8 / (1.46e14 - s);
614 n += 1.000064328;
615 *wavep = (*awavp)*n;
616 *(statp++) = 0;
617 } else {
618 *(statp++) = 1;
619 status = SPXERR_BAD_INSPEC_COORD;
620 }
621
622 awavp += sawav;
623 wavep += swave;
624 }
625
626 return status;
627 }
628
629 /*============================================================================
630 * Conversions between vacuum wavelength and relativistic velocity.
631 *===========================================================================*/
632
wavevelo(double restwav,int nwave,int swave,int svelo,const double wave[],double velo[],int stat[])633 int wavevelo(
634 double restwav,
635 int nwave,
636 int swave,
637 int svelo,
638 const double wave[],
639 double velo[],
640 int stat[])
641
642 {
643 double r, s;
644 register int iwave, *statp;
645 register const double *wavep;
646 register double *velop;
647
648 r = restwav*restwav;
649
650 wavep = wave;
651 velop = velo;
652 statp = stat;
653 for (iwave = 0; iwave < nwave; iwave++) {
654 s = *wavep * *wavep;
655 *velop = C*(s - r)/(s + r);
656 *(statp++) = 0;
657
658 wavep += swave;
659 velop += svelo;
660 }
661
662 return 0;
663 }
664
665 //----------------------------------------------------------------------------
666
velowave(double restwav,int nvelo,int svelo,int swave,const double velo[],double wave[],int stat[])667 int velowave(
668 double restwav,
669 int nvelo,
670 int svelo,
671 int swave,
672 const double velo[],
673 double wave[],
674 int stat[])
675
676 {
677 int status = 0;
678 double s;
679 register int ivelo, *statp;
680 register const double *velop;
681 register double *wavep;
682
683 velop = velo;
684 wavep = wave;
685 statp = stat;
686 for (ivelo = 0; ivelo < nvelo; ivelo++) {
687 s = C - *velop;
688 if (s != 0.0) {
689 *wavep = restwav*sqrt((C + *velop)/s);
690 *(statp++) = 0;
691 } else {
692 *(statp++) = 1;
693 status = SPXERR_BAD_INSPEC_COORD;
694 }
695
696 velop += svelo;
697 wavep += swave;
698 }
699
700 return status;
701 }
702
703 /*============================================================================
704 * Conversions between air wavelength and relativistic velocity.
705 *===========================================================================*/
706
awavvelo(double dummy,int nawav,int sawav,int svelo,const double awav[],double velo[],int stat[])707 int awavvelo(
708 double dummy,
709 int nawav,
710 int sawav,
711 int svelo,
712 const double awav[],
713 double velo[],
714 int stat[])
715
716 {
717 int status;
718
719 if ((status = awavwave(dummy, nawav, sawav, svelo, awav, velo, stat))) {
720 return status;
721 }
722
723 return wavevelo(dummy, nawav, svelo, svelo, velo, velo, stat);
724 }
725
726 //----------------------------------------------------------------------------
727
veloawav(double dummy,int nvelo,int svelo,int sawav,const double velo[],double awav[],int stat[])728 int veloawav(
729 double dummy,
730 int nvelo,
731 int svelo,
732 int sawav,
733 const double velo[],
734 double awav[],
735 int stat[])
736
737 {
738 int status;
739
740 if ((status = velowave(dummy, nvelo, svelo, sawav, velo, awav, stat))) {
741 return status;
742 }
743
744 return waveawav(dummy, nvelo, sawav, sawav, awav, awav, stat);
745 }
746
747 /*============================================================================
748 * Conversions between frequency and angular frequency.
749 *===========================================================================*/
750
freqafrq(double dummy,int nfreq,int sfreq,int safrq,const double freq[],double afrq[],int stat[])751 int freqafrq(
752 double dummy,
753 int nfreq,
754 int sfreq,
755 int safrq,
756 const double freq[],
757 double afrq[],
758 int stat[])
759
760 {
761 register int ifreq, *statp;
762 register const double *freqp;
763 register double *afrqp;
764
765 // Avert nuisance compiler warnings about unused parameters.
766 (void)dummy;
767
768 freqp = freq;
769 afrqp = afrq;
770 statp = stat;
771 for (ifreq = 0; ifreq < nfreq; ifreq++) {
772 *afrqp = (*freqp)*(2.0*PI);
773 *(statp++) = 0;
774
775 freqp += sfreq;
776 afrqp += safrq;
777 }
778
779 return 0;
780 }
781
782 //----------------------------------------------------------------------------
783
afrqfreq(double dummy,int nafrq,int safrq,int sfreq,const double afrq[],double freq[],int stat[])784 int afrqfreq(
785 double dummy,
786 int nafrq,
787 int safrq,
788 int sfreq,
789 const double afrq[],
790 double freq[],
791 int stat[])
792
793 {
794 register int iafrq, *statp;
795 register const double *afrqp;
796 register double *freqp;
797
798 // Avert nuisance compiler warnings about unused parameters.
799 (void)dummy;
800
801 afrqp = afrq;
802 freqp = freq;
803 statp = stat;
804 for (iafrq = 0; iafrq < nafrq; iafrq++) {
805 *freqp = (*afrqp)/(2.0*PI);
806 *(statp++) = 0;
807
808 afrqp += safrq;
809 freqp += sfreq;
810 }
811
812 return 0;
813 }
814
815 /*============================================================================
816 * Conversions between frequency and energy.
817 *===========================================================================*/
818
freqener(double dummy,int nfreq,int sfreq,int sener,const double freq[],double ener[],int stat[])819 int freqener(
820 double dummy,
821 int nfreq,
822 int sfreq,
823 int sener,
824 const double freq[],
825 double ener[],
826 int stat[])
827
828 {
829 register int ifreq, *statp;
830 register const double *freqp;
831 register double *enerp;
832
833 // Avert nuisance compiler warnings about unused parameters.
834 (void)dummy;
835
836 freqp = freq;
837 enerp = ener;
838 statp = stat;
839 for (ifreq = 0; ifreq < nfreq; ifreq++) {
840 *enerp = (*freqp)*h;
841 *(statp++) = 0;
842
843 freqp += sfreq;
844 enerp += sener;
845 }
846
847 return 0;
848 }
849
850 //----------------------------------------------------------------------------
851
enerfreq(double dummy,int nener,int sener,int sfreq,const double ener[],double freq[],int stat[])852 int enerfreq(
853 double dummy,
854 int nener,
855 int sener,
856 int sfreq,
857 const double ener[],
858 double freq[],
859 int stat[])
860
861 {
862 register int iener, *statp;
863 register const double *enerp;
864 register double *freqp;
865
866 // Avert nuisance compiler warnings about unused parameters.
867 (void)dummy;
868
869 enerp = ener;
870 freqp = freq;
871 statp = stat;
872 for (iener = 0; iener < nener; iener++) {
873 *freqp = (*enerp)/h;
874 *(statp++) = 0;
875
876 enerp += sener;
877 freqp += sfreq;
878 }
879
880 return 0;
881 }
882
883 /*============================================================================
884 * Conversions between frequency and wave number.
885 *===========================================================================*/
886
freqwavn(double dummy,int nfreq,int sfreq,int swavn,const double freq[],double wavn[],int stat[])887 int freqwavn(
888 double dummy,
889 int nfreq,
890 int sfreq,
891 int swavn,
892 const double freq[],
893 double wavn[],
894 int stat[])
895
896 {
897 register int ifreq, *statp;
898 register const double *freqp;
899 register double *wavnp;
900
901 // Avert nuisance compiler warnings about unused parameters.
902 (void)dummy;
903
904 freqp = freq;
905 wavnp = wavn;
906 statp = stat;
907 for (ifreq = 0; ifreq < nfreq; ifreq++) {
908 *wavnp = (*freqp)/C;
909 *(statp++) = 0;
910
911 freqp += sfreq;
912 wavnp += swavn;
913 }
914
915 return 0;
916 }
917
918 //----------------------------------------------------------------------------
919
wavnfreq(double dummy,int nwavn,int swavn,int sfreq,const double wavn[],double freq[],int stat[])920 int wavnfreq(
921 double dummy,
922 int nwavn,
923 int swavn,
924 int sfreq,
925 const double wavn[],
926 double freq[],
927 int stat[])
928
929 {
930 register int iwavn, *statp;
931 register const double *wavnp;
932 register double *freqp;
933
934 // Avert nuisance compiler warnings about unused parameters.
935 (void)dummy;
936
937 wavnp = wavn;
938 freqp = freq;
939 statp = stat;
940 for (iwavn = 0; iwavn < nwavn; iwavn++) {
941 *freqp = (*wavnp)*C;
942 *(statp++) = 0;
943
944 wavnp += swavn;
945 freqp += sfreq;
946 }
947
948 return 0;
949 }
950
951 /*============================================================================
952 * Conversions between frequency and radio velocity.
953 *===========================================================================*/
954
freqvrad(double restfrq,int nfreq,int sfreq,int svrad,const double freq[],double vrad[],int stat[])955 int freqvrad(
956 double restfrq,
957 int nfreq,
958 int sfreq,
959 int svrad,
960 const double freq[],
961 double vrad[],
962 int stat[])
963
964 {
965 double r;
966 register int ifreq, *statp;
967 register const double *freqp;
968 register double *vradp;
969
970 if (restfrq == 0.0) {
971 return SPXERR_BAD_SPEC_PARAMS;
972 }
973 r = C/restfrq;
974
975 freqp = freq;
976 vradp = vrad;
977 statp = stat;
978 for (ifreq = 0; ifreq < nfreq; ifreq++) {
979 *vradp = r*(restfrq - *freqp);
980 *(statp++) = 0;
981
982 freqp += sfreq;
983 vradp += svrad;
984 }
985
986 return 0;
987 }
988
989 //----------------------------------------------------------------------------
990
vradfreq(double restfrq,int nvrad,int svrad,int sfreq,const double vrad[],double freq[],int stat[])991 int vradfreq(
992 double restfrq,
993 int nvrad,
994 int svrad,
995 int sfreq,
996 const double vrad[],
997 double freq[],
998 int stat[])
999
1000 {
1001 double r;
1002 register int ivrad, *statp;
1003 register const double *vradp;
1004 register double *freqp;
1005
1006 r = restfrq/C;
1007
1008 vradp = vrad;
1009 freqp = freq;
1010 statp = stat;
1011 for (ivrad = 0; ivrad < nvrad; ivrad++) {
1012 *freqp = r*(C - *vradp);
1013 *(statp++) = 0;
1014 vradp += svrad;
1015 freqp += sfreq;
1016 }
1017
1018 return 0;
1019 }
1020
1021 /*============================================================================
1022 * Conversions between vacuum wavelength and optical velocity.
1023 *===========================================================================*/
1024
wavevopt(double restwav,int nwave,int swave,int svopt,const double wave[],double vopt[],int stat[])1025 int wavevopt(
1026 double restwav,
1027 int nwave,
1028 int swave,
1029 int svopt,
1030 const double wave[],
1031 double vopt[],
1032 int stat[])
1033
1034 {
1035 double r;
1036 register int iwave, *statp;
1037 register const double *wavep;
1038 register double *voptp;
1039
1040 if (restwav == 0.0) {
1041 return SPXERR_BAD_SPEC_PARAMS;
1042 }
1043 r = C/restwav;
1044
1045 wavep = wave;
1046 voptp = vopt;
1047 statp = stat;
1048 for (iwave = 0; iwave < nwave; iwave++) {
1049 *voptp = r*(*wavep) - C;
1050 *(statp++) = 0;
1051 wavep += swave;
1052 voptp += svopt;
1053 }
1054
1055 return 0;
1056 }
1057
1058 //----------------------------------------------------------------------------
1059
voptwave(double restwav,int nvopt,int svopt,int swave,const double vopt[],double wave[],int stat[])1060 int voptwave(
1061 double restwav,
1062 int nvopt,
1063 int svopt,
1064 int swave,
1065 const double vopt[],
1066 double wave[],
1067 int stat[])
1068
1069 {
1070 double r;
1071 register int ivopt, *statp;
1072 register const double *voptp;
1073 register double *wavep;
1074
1075 r = restwav/C;
1076
1077 voptp = vopt;
1078 wavep = wave;
1079 statp = stat;
1080 for (ivopt = 0; ivopt < nvopt; ivopt++) {
1081 *wavep = r*(C + *voptp);
1082 *(statp++) = 0;
1083 voptp += svopt;
1084 wavep += swave;
1085 }
1086
1087 return 0;
1088 }
1089
1090 /*============================================================================
1091 * Conversions between vacuum wavelength and redshift.
1092 *===========================================================================*/
1093
wavezopt(double restwav,int nwave,int swave,int szopt,const double wave[],double zopt[],int stat[])1094 int wavezopt(
1095 double restwav,
1096 int nwave,
1097 int swave,
1098 int szopt,
1099 const double wave[],
1100 double zopt[],
1101 int stat[])
1102
1103 {
1104 double r;
1105 register int iwave, *statp;
1106 register const double *wavep;
1107 register double *zoptp;
1108
1109 if (restwav == 0.0) {
1110 return SPXERR_BAD_SPEC_PARAMS;
1111 }
1112 r = 1.0/restwav;
1113
1114 wavep = wave;
1115 zoptp = zopt;
1116 statp = stat;
1117 for (iwave = 0; iwave < nwave; iwave++) {
1118 *zoptp = r*(*wavep) - 1.0;
1119 *(statp++) = 0;
1120 wavep += swave;
1121 zoptp += szopt;
1122 }
1123
1124 return 0;
1125 }
1126
1127 //----------------------------------------------------------------------------
1128
zoptwave(double restwav,int nzopt,int szopt,int swave,const double zopt[],double wave[],int stat[])1129 int zoptwave(
1130 double restwav,
1131 int nzopt,
1132 int szopt,
1133 int swave,
1134 const double zopt[],
1135 double wave[],
1136 int stat[])
1137
1138 {
1139 register int izopt, *statp;
1140 register const double *zoptp;
1141 register double *wavep;
1142
1143 zoptp = zopt;
1144 wavep = wave;
1145 statp = stat;
1146 for (izopt = 0; izopt < nzopt; izopt++) {
1147 *wavep = restwav*(1.0 + *zoptp);
1148 *(statp++) = 0;
1149 zoptp += szopt;
1150 wavep += swave;
1151 }
1152
1153 return 0;
1154 }
1155
1156 /*============================================================================
1157 * Conversions between relativistic velocity and beta (= v/c).
1158 *===========================================================================*/
1159
velobeta(double dummy,int nvelo,int svelo,int sbeta,const double velo[],double beta[],int stat[])1160 int velobeta(
1161 double dummy,
1162 int nvelo,
1163 int svelo,
1164 int sbeta,
1165 const double velo[],
1166 double beta[],
1167 int stat[])
1168
1169 {
1170 register int ivelo, *statp;
1171 register const double *velop;
1172 register double *betap;
1173
1174 // Avert nuisance compiler warnings about unused parameters.
1175 (void)dummy;
1176
1177 velop = velo;
1178 betap = beta;
1179 statp = stat;
1180 for (ivelo = 0; ivelo < nvelo; ivelo++) {
1181 *betap = (*velop)/C;
1182 *(statp++) = 0;
1183
1184 velop += svelo;
1185 betap += sbeta;
1186 }
1187
1188 return 0;
1189 }
1190
1191 //----------------------------------------------------------------------------
1192
betavelo(double dummy,int nbeta,int sbeta,int svelo,const double beta[],double velo[],int stat[])1193 int betavelo(
1194 double dummy,
1195 int nbeta,
1196 int sbeta,
1197 int svelo,
1198 const double beta[],
1199 double velo[],
1200 int stat[])
1201
1202 {
1203 register int ibeta, *statp;
1204 register const double *betap;
1205 register double *velop;
1206
1207 // Avert nuisance compiler warnings about unused parameters.
1208 (void)dummy;
1209
1210 betap = beta;
1211 velop = velo;
1212 statp = stat;
1213 for (ibeta = 0; ibeta < nbeta; ibeta++) {
1214 *velop = (*betap)*C;
1215 *(statp++) = 0;
1216
1217 betap += sbeta;
1218 velop += svelo;
1219 }
1220
1221 return 0;
1222 }
1223