GIRAFFE Pipeline Reference Manual

giastroutils.c
1/*
2 * This file is part of the GIRAFFE Pipeline
3 * Copyright (C) 2002-2019 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24#include <math.h>
25
26#include <cxtypes.h>
27
28#include <cpl_msg.h>
29
30#include <giastroutils.h>
31
32
33
42static const cxdouble TINY = 1.e-12;
43
44static const cxdouble RV_DPI =
45 3.1415926535897932384626433832795028841971693993751; /* pi */
46
47static const cxdouble DEG_TO_RAD =
48 0.017453292519943295769236907684886127134428718885417; /* pi/180 */
49
50static const cxdouble SEC_TO_DEG = 15. / 3600.;
51
52
53
54/*
55 * @brief
56 * Compute the zenith distance of a point in the sky
57 *
58 * @param hourangle Hour angle in radians
59 * @param delta Declination in radians
60 * @param latitude Latitude of the observatory in radians
61 *
62 * @return
63 * The secant of the zenith distance, or @c 0. if na error occurred.
64 *
65 * The function computes the secans of the zenith distance of a point
66 * in the sky, given by the angle @em hourangle from the meridian and the
67 * declination @em delta. The latitude of the observing site is given by
68 * @em latitude.
69 *
70 * The domain of the hour angle, declination and the latitude of the
71 * observing site are [$-\pi$, \pi$], [$-0.5\pi, 0.5\pi$] and [$0, 2\pi$]
72 * respectively.
73 */
74
75inline static cxdouble
76_giraffe_compute_zdistance(cxdouble hourangle, cxdouble delta,
77 cxdouble latitude)
78{
79
80 cxdouble p0 = sin(latitude) * sin(delta);
81 cxdouble p1 = cos(latitude) * cos(delta);
82 cxdouble z = p0 + cos(hourangle) * p1;
83
84 if (fabs(z) < TINY) {
85 z = z < 0. ? -TINY : TINY;
86 }
87
88 return 1. / z;
89
90}
91
92
93/*
94 * @brief
95 * Compute approximated airmass value.
96 *
97 * @param secz Secant of the zenith distance.
98 *
99 * @return
100 * The function returns the approximated airmass value.
101 *
102 * The function uses the approximation given by Young and Irvine
103 * (Young A. T., Irvine W. M., 1967, Astron. J. 72, 945) to compute
104 * the airmass for a given sec(z) @em secz. This approximation
105 * takes into account atmosphere refraction and curvature, but is in
106 * principle only valid at sea level.
107 */
108
109inline static cxdouble
110_giraffe_compute_airmass_young_irvine(cxdouble secz)
111{
112
113 return secz * (1. - 0.0012 * (pow(secz, 2.) - 1.));
114
115}
116
117
118/*
119 * @brief
120 * Compute approximated airmass value.
121 *
122 * @param secz Secant of the zenith distance.
123 *
124 * @return
125 * The function returns the approximated airmass value.
126 *
127 * The function uses the approximation given by Young (Young A. T.,
128 * 1994, "Air mass and refraction", Applied Optics, 33, 1108-1110) to
129 * compute the airmass for a given sec(z) @em secz, where z is the true
130 * zenith angle.
131 */
132
133inline static cxdouble
134_giraffe_compute_airmass_young(cxdouble secz)
135{
136
137 cxdouble z = 1. / secz; /* cos(zt) cosine of the true zenith angle */
138 cxdouble x = 0.;
139 cxdouble y = 0.;
140
141 x = 1.002432 * z * z + 0.148386 * z + 0.0096467;
142 y = z * z * z + 0.149864 * z * z + 0.0102963 * z + 0.000303978;
143
144 return x / y;
145
146}
147
148
176cxdouble
177giraffe_compute_airmass(cxdouble alpha, cxdouble delta, cxdouble lst,
178 cxdouble exptime, cxdouble latitude)
179{
180
181 const cxchar* const fctid = "giraffe_compute_airmass";
182
183
184 /* Weights for Stetson's formula */
185
186 const cxdouble weights[] = {1. / 6., 2. / 3., 1. / 6.};
187
188
189 /*
190 * Accuracy limit for airmass approximation (cf. Young A. T., Irvine W. M.,
191 * 1967, Astron. J. 72, 945).
192 */
193
194 const cxdouble airmass_upper_limit = 10.;
195
196
197 cxdouble z = 0.;
198 cxdouble hourangle = 0.;
199 cxdouble airmass = 0.;
200
201
202 /*
203 * Compute hour angle of the observation in degrees.
204 */
205
206 hourangle = lst * SEC_TO_DEG - alpha;
207
208
209 /*
210 * Range adjustments. Angle between line of sight and the meridian
211 * is needed.
212 */
213
214 if (hourangle < -180.) {
215 hourangle += 360.;
216 }
217
218 if (hourangle > 180.) {
219 hourangle -= 360.;
220 }
221
222
223 /*
224 * Convert angles from degrees to radians
225 */
226
227 delta *= DEG_TO_RAD;
228 latitude *= DEG_TO_RAD;
229 hourangle *= DEG_TO_RAD;
230
231
232 /*
233 * Calculate airmass of the observation using the approximation given
234 * by Young (Young A. T., 1994, "Air mass and refraction", Applied
235 * Optics, 33, 1108-1110)for the individual airmass values. For finite
236 * exposure times these airmass values are averaged using the weights
237 * given by Stetson (Stetson P., 1987, PASP 99, 191)
238 */
239
240 z = _giraffe_compute_zdistance(hourangle, delta, latitude);
241
242 if (fabs(z) < TINY) {
243 cpl_msg_debug(fctid, "Airmass computation failed. Object is "
244 "below the horizon.");
245 return -1.;
246 }
247
248 airmass = _giraffe_compute_airmass_young(z);
249
250 if (exptime > 0.) {
251
252 const cxint nweights = CX_N_ELEMENTS(weights);
253
254 cxint i = 0;
255
256 cxdouble timestep = exptime / (nweights - 1) * SEC_TO_DEG *
257 DEG_TO_RAD;
258
259
260 airmass *= weights[0];
261
262 for (i = 1; i < nweights; i++) {
263
264 z = _giraffe_compute_zdistance(hourangle + i * timestep,
265 delta, latitude);
266
267 if (fabs(z) < TINY) {
268
269 cpl_msg_debug(fctid, "Airmass computation failed. Object "
270 "is below the horizon.");
271 return -1.;
272
273 }
274
275 airmass += weights[i] * _giraffe_compute_airmass_young(z);
276
277 }
278
279 }
280
281
282 if (airmass > airmass_upper_limit) {
283 cpl_msg_debug(fctid, "Airmass larger than %f", airmass_upper_limit);
284 }
285
286 return airmass;
287
288}
cxdouble giraffe_compute_airmass(cxdouble alpha, cxdouble delta, cxdouble lst, cxdouble exptime, cxdouble latitude)
Compute the airmass for a given pointing direction and observing site.
Definition: giastroutils.c:177

This file is part of the GIRAFFE Pipeline Reference Manual 2.17.1.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Feb 13 2025 14:13:57 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2004