VISIR Pipeline Reference Manual  4.1.7
irplib_pfits.c
1 /* $Id: irplib_pfits.c,v 1.15 2013-05-13 16:05:04 jtaylor Exp $
2  *
3  * This file is part of the IRPLIB Package
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jtaylor $
23  * $Date: 2013-05-13 16:05:04 $
24  * $Revision: 1.15 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 
36 #include "irplib_utils.h"
37 #include "irplib_pfits.h"
38 
39 #include <cpl.h>
40 
41 #include <assert.h>
42 #include <string.h>
43 #include <sys/types.h>
44 #include <regex.h>
45 
46 /*-----------------------------------------------------------------------------
47  Private funcions
48  -----------------------------------------------------------------------------*/
49 
50 static cpl_error_code irplib_dfs_check_frame_tag(const cpl_frame *,
51  const cpl_propertylist *,
52  const char* (*)
53  (const char *,
54  const char *,
55  const char *));
56 
57 
58 /*----------------------------------------------------------------------------*/
63 /*----------------------------------------------------------------------------*/
64 
67 /*-----------------------------------------------------------------------------
68  Function codes
69  -----------------------------------------------------------------------------*/
70 
71 
72 /*----------------------------------------------------------------------------*/
78 /*----------------------------------------------------------------------------*/
79 const char * irplib_pfits_get_dpr_catg(const cpl_propertylist * self)
80 {
81  return irplib_pfits_get_string(self, "ESO DPR CATG");
82 }
83 
84 /*----------------------------------------------------------------------------*/
90 /*----------------------------------------------------------------------------*/
91 const char * irplib_pfits_get_dpr_tech(const cpl_propertylist * self)
92 {
93  return irplib_pfits_get_string(self, "ESO DPR TECH");
94 }
95 
96 /*----------------------------------------------------------------------------*/
102 /*----------------------------------------------------------------------------*/
103 const char * irplib_pfits_get_dpr_type(const cpl_propertylist * self)
104 {
105  return irplib_pfits_get_string(self, "ESO DPR TYPE");
106 }
107 
108 /*----------------------------------------------------------------------------*/
119 /*----------------------------------------------------------------------------*/
120 double irplib_pfits_get_double_macro(const cpl_propertylist * self,
121  const char * key,
122  const char * function,
123  const char * file,
124  unsigned line)
125 {
126  double value;
127  cpl_errorstate prestate = cpl_errorstate_get();
128 
129  value = cpl_propertylist_get_double(self, key);
130 
131  if (cpl_errorstate_is_equal(prestate)) {
132  cpl_msg_debug(function, "FITS card '%s' [double]: %g", key, value);
133  } else {
134  /* Set the error location to that of the caller */
135  (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
136  line, "Missing FITS card "
137  " [double]: '%s' ", key);
138  }
139 
140  return value;
141 }
142 
143 
144 
145 /*----------------------------------------------------------------------------*/
156 /*----------------------------------------------------------------------------*/
157 int irplib_pfits_get_int_macro(const cpl_propertylist * self,
158  const char * key, const char * function,
159  const char * file, unsigned line)
160 {
161  int value;
162  cpl_errorstate prestate = cpl_errorstate_get();
163 
164  value = cpl_propertylist_get_int(self, key);
165 
166  if (cpl_errorstate_is_equal(prestate)) {
167  cpl_msg_debug(function, "FITS card '%s' [int]: %d", key, value);
168  } else {
169  /* Set the error location to that of the caller */
170  (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
171  line, "Missing FITS card "
172  " [int]: '%s' ", key);
173  }
174 
175  return value;
176 }
177 
178 
179 /*----------------------------------------------------------------------------*/
190 /*----------------------------------------------------------------------------*/
191 const char * irplib_pfits_get_string_macro(const cpl_propertylist * self,
192  const char * key,
193  const char * function,
194  const char * file,
195  unsigned line)
196 {
197  const char * value;
198  cpl_errorstate prestate = cpl_errorstate_get();
199 
200  value = cpl_propertylist_get_string(self, key);
201 
202  if (cpl_errorstate_is_equal(prestate)) {
203  cpl_msg_debug(function, "FITS card '%s' [string]: %s", key, value);
204  } else {
205  /* Set the error location to that of the caller */
206  (void)cpl_error_set_message_macro(function, cpl_error_get_code(), file,
207  line, "Missing FITS card "
208  " [string]: '%s' ", key);
209  }
210 
211  return value;
212 }
213 
214 
215 
216 
217 /*----------------------------------------------------------------------------*/
224 /*----------------------------------------------------------------------------*/
225 cpl_error_code irplib_dfs_check_framelist_tag(const irplib_framelist * self,
226  const char* (*pfind)(const char *,
227  const char *,
228  const char *))
229 {
230 
231  int i;
232 
233  if (cpl_error_get_code()) return cpl_error_get_code();
234 
235  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
236  cpl_ensure_code(pfind != NULL, CPL_ERROR_NULL_INPUT);
237 
238  for (i = 0; i < irplib_framelist_get_size(self); i++) {
239  const cpl_frame * frame = irplib_framelist_get_const(self, i);
240  const cpl_propertylist * plist
242 
243  cpl_ensure_code(frame != NULL, cpl_error_get_code());
244  cpl_ensure_code(plist != NULL, cpl_error_get_code());
245 
246  cpl_ensure_code(!irplib_dfs_check_frame_tag(frame, plist, pfind),
247  cpl_error_get_code());
248  }
249 
250  return cpl_error_get_code();
251 
252 }
253 
254 
255 /*----------------------------------------------------------------------------*/
266 /*----------------------------------------------------------------------------*/
267 int irplib_dfs_find_words(const char * words, const char * format, ...)
268 {
269 
270  regex_t re;
271  va_list ap;
272  int error, status;
273 
274 
275  if (cpl_error_get_code()) return -1;
276 
277  cpl_ensure(words != NULL, CPL_ERROR_NULL_INPUT, -2);
278  cpl_ensure(format != NULL, CPL_ERROR_NULL_INPUT, -3);
279 
280  /* format must consist of space separated %s */
281  error = regcomp(&re, "^ *%s( +%s)* *$", REG_EXTENDED | REG_NOSUB);
282 
283  /* Should really be assert() */
284  cpl_ensure(!error, CPL_ERROR_ILLEGAL_INPUT, -4);
285 
286  status = regexec(&re, format, (size_t)0, NULL, 0);
287 
288  regfree(&re);
289 
290  if (status != 0) {
291  cpl_msg_error(cpl_func, "Regexp counter must consist of space-separated"
292  " %%s, not: %s", format);
293  cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, -5);
294  }
295 
296  va_start(ap, format);
297 
298  /* Iterate through arguments, by searching for the '%' */
299  for (; format != NULL; format = strchr(++format, '%')) {
300 
301  const char * regexp = va_arg(ap, const char *);
302 
303  if (regexp == NULL) {
304  va_end(ap);
305  cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, -6);
306  }
307 
308  error = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
309 
310  if (error) {
311  va_end(ap);
312  cpl_ensure(0, CPL_ERROR_ILLEGAL_INPUT, -7);
313  }
314 
315  status = regexec(&re, words, (size_t)0, NULL, 0);
316 
317  regfree(&re);
318 
319  if (status != 0) break; /* Not matched */
320 
321  }
322 
323  va_end(ap);
324 
325  return format == NULL ? 0 : 1;
326 
327 }
328 
329 /*----------------------------------------------------------------------------*/
337 /*----------------------------------------------------------------------------*/
338 cpl_error_code irplib_pfits_set_airmass(cpl_propertylist * self,
339  const irplib_framelist * rawframes)
340 {
341 
342  char * newcomment = NULL;
343  const int nframes = irplib_framelist_get_size(rawframes);
344  int iframe;
345  int nmass = 0;
346  double astart0 = -1.0;
347  double aend0 = -1.0;
348  double airmass = 0.0;
349  cpl_errorstate prestate = cpl_errorstate_get();
350 
351  skip_if(0);
352  skip_if(self == NULL);
353 
354  for (iframe = 0; iframe < nframes; iframe++) {
355  const cpl_propertylist * plist
356  = irplib_framelist_get_propertylist_const(rawframes, iframe);
357  double astart = DBL_MAX; /* Avoid (false) uninit warning */
358  double aend = DBL_MAX; /* Avoid (false) uninit warning */
359  double airmi;
360 
361  if (!cpl_errorstate_is_equal(prestate)) {
362  irplib_error_recover(prestate, "No propertylist found for frame %d:",
363  iframe);
364  continue;
365  }
366 
367  if (iframe == 0) {
368  astart = irplib_pfits_get_double(plist, "ESO TEL AIRM START");
369  if (cpl_errorstate_is_equal(prestate)) {
370  astart0 = astart;
371  aend = irplib_pfits_get_double(plist, "ESO TEL AIRM END");
372  }
373  } else {
374  aend = irplib_pfits_get_double(plist, "ESO TEL AIRM END");
375  if (cpl_errorstate_is_equal(prestate)) {
376  if (iframe == nframes - 1) aend0 = aend;
377  astart = irplib_pfits_get_double(plist, "ESO TEL AIRM START");
378  }
379  }
380 
381  if (cpl_errorstate_is_equal(prestate)) {
382  airmi = 0.5 * (astart + aend);
383  } else {
384  const char * filename = cpl_frame_get_filename(
385  irplib_framelist_get_const(rawframes, iframe));
386  irplib_error_recover(prestate, "Could not get FITS key from %s",
387  filename);
388 
389  airmi = irplib_pfits_get_double(plist, "AIRMASS");
390 
391  if (!cpl_errorstate_is_equal(prestate)) {
392  irplib_error_recover(prestate, "Could not get FITS key from %s",
393  filename);
394  continue;
395  }
396  }
397 
398  airmass += airmi;
399  nmass++;
400  }
401 
402  bug_if(0);
403 
404  if (nmass == 0 && astart0 > 0.0 && aend0 > 0.0) {
405  airmass = 0.5 * (astart0 + aend0);
406  nmass = 1;
407  }
408  if (nmass > 0) {
409  const char * key = "AIRMASS";
410  const char * comment = cpl_propertylist_get_comment(self, key);
411 
412  cpl_errorstate_set(prestate);
413 
414  airmass /= (double)nmass;
415 
416  bug_if(cpl_propertylist_update_double(self, key, airmass));
417 
418  if (comment == NULL) {
419  bug_if(cpl_propertylist_set_comment(self, key, "Averaged air mass "
420  "(Recalculated)"));
421  } else {
422  newcomment = cpl_sprintf("%s (Recalculated)",
423  comment);
424  bug_if(cpl_propertylist_set_comment(self, key, newcomment));
425  }
426 
427  }
428 
429  end_skip;
430 
431  cpl_free(newcomment);
432 
433  return cpl_error_get_code();
434 
435 }
436 
440 /*----------------------------------------------------------------------------*/
448 /*----------------------------------------------------------------------------*/
449 static cpl_error_code irplib_dfs_check_frame_tag(const cpl_frame * self,
450  const cpl_propertylist * plist,
451  const char* (*pfind)
452  (const char *,
453  const char *,
454  const char *))
455 {
456 
457  const char * file;
458  const char * tag;
459  const char * catg;
460  const char * type;
461  const char * tech;
462  cpl_errorstate prestate = cpl_errorstate_get();
463 
464 
465  cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
466 
467  file = cpl_frame_get_filename(self);
468 
469  cpl_ensure_code(file != NULL, cpl_error_get_code());
470 
471  tag = cpl_frame_get_tag(self);
472 
473  cpl_ensure_code(tag != NULL, cpl_error_get_code());
474 
475  catg = irplib_pfits_get_dpr_catg(plist);
476  type = irplib_pfits_get_dpr_type(plist);
477  tech = irplib_pfits_get_dpr_tech(plist);
478 
479  if (!cpl_errorstate_is_equal(prestate)) {
480  if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
481  cpl_msg_warning(cpl_func, "File %s has missing or incomplete DPR "
482  "triplet", file);
483  cpl_errorstate_dump(prestate, CPL_FALSE, NULL);
484  }
485  cpl_errorstate_set(prestate);
486  } else {
487  const char * docatg;
488 
489  cpl_ensure_code(pfind != NULL, CPL_ERROR_NULL_INPUT);
490 
491  docatg = (*pfind)(catg, type, tech);
492 
493  if (docatg == NULL) {
494  if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
495  cpl_msg_warning(cpl_func, "File %s has tag %s but unknown DPR "
496  "triplet: (CATG;TYPE;TECH)=(%s;%s;%s)", file, tag,
497  catg, type, tech);
498  } else if (strcmp(tag, docatg) != 0) {
499  if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
500  cpl_msg_warning(cpl_func, "File %s has tag %s but DPR triplet of "
501  "%s: (CATG;TYPE;TECH)=(%s;%s;%s)", file, tag,
502  docatg, catg, type, tech);
503  }
504  }
505 
506  return CPL_ERROR_NONE;
507 
508 }
509 
510 
const char * irplib_pfits_get_dpr_catg(const cpl_propertylist *self)
The data category.
Definition: irplib_pfits.c:79
const char * irplib_pfits_get_string_macro(const cpl_propertylist *self, const char *key, const char *function, const char *file, unsigned line)
Get the value of a property of type string.
Definition: irplib_pfits.c:191
const char * irplib_pfits_get_dpr_type(const cpl_propertylist *self)
The data type.
Definition: irplib_pfits.c:103
cpl_error_code irplib_pfits_set_airmass(cpl_propertylist *self, const irplib_framelist *rawframes)
Update/Set the AIRMASS property.
Definition: irplib_pfits.c:338
const char * irplib_pfits_get_dpr_tech(const cpl_propertylist *self)
The data technique.
Definition: irplib_pfits.c:91
const cpl_propertylist * irplib_framelist_get_propertylist_const(const irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
double irplib_pfits_get_double_macro(const cpl_propertylist *self, const char *key, const char *function, const char *file, unsigned line)
Get the value of a property of type double.
Definition: irplib_pfits.c:120
int irplib_pfits_get_int_macro(const cpl_propertylist *self, const char *key, const char *function, const char *file, unsigned line)
Get the value of a property of type int.
Definition: irplib_pfits.c:157
cpl_error_code irplib_dfs_check_framelist_tag(const irplib_framelist *self, const char *(*pfind)(const char *, const char *, const char *))
Check the tags in a frameset (group raw only)
Definition: irplib_pfits.c:225
const cpl_frame * irplib_framelist_get_const(const irplib_framelist *self, int pos)
Get the specified frame from the framelist.
int irplib_dfs_find_words(const char *words, const char *format,...)
Match a string with word(s) against a list of 1-word-regexps.
Definition: irplib_pfits.c:267
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.