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 
42 static const cxdouble TINY = 1.e-12;
43 
44 static const cxdouble RV_DPI =
45  3.1415926535897932384626433832795028841971693993751; /* pi */
46 
47 static const cxdouble DEG_TO_RAD =
48  0.017453292519943295769236907684886127134428718885417; /* pi/180 */
49 
50 static 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 
75 inline 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 
109 inline 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 
133 inline 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 
176 cxdouble
177 giraffe_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.16.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Dec 15 2022 21:18:51 by doxygen 1.9.1 written by Dimitri van Heesch, © 1997-2004