FORS Pipeline Reference Manual  5.0.9
fors_data.c
1 /* $Id: fors_data.c,v 1.44 2013-08-07 13:26:50 cgarcia Exp $
2  *
3  * This file is part of the FORS Library
4  * Copyright (C) 2002-2010 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 02110-1301 USA
19  */
20 
21 /*
22  * $Author: cgarcia $
23  * $Date: 2013-08-07 13:26:50 $
24  * $Revision: 1.44 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 #include <fors_data.h>
33 
34 #include <cpl_wcs.h>
35 #include <fors_star.h>
36 #include <fors_instrument.h>
37 #include <fors_std_star.h>
38 #include <fors_utils.h>
39 
40 #include <math.h>
41 #include <stdbool.h>
42 #include <string.h>
43 
44 
45 const char *const FORS_DATA_PHOT_FILTER = "FILTER";
46 const char *const FORS_DATA_PHOT_EXTCOEFF = "EXT";
47 const char *const FORS_DATA_PHOT_DEXTCOEFF = "DEXT";
48 const char *const FORS_DATA_PHOT_ZEROPOINT = "ZPOINT";
49 const char *const FORS_DATA_PHOT_DZEROPOINT = "DZPOINT";
50 const char *const FORS_DATA_PHOT_COLORTERM = "COL";
51 const char *const FORS_DATA_PHOT_DCOLORTERM = "DCOL";
52 
53 
54 #undef cleanup
55 #define cleanup \
56 do { \
57  cpl_wcs_delete(wcs); \
58  cpl_matrix_delete(from); \
59  cpl_matrix_delete(to); \
60  cpl_array_delete(status); \
61 } while(0)
62 
67 void
68 fors_std_star_list_apply_wcs( fors_std_star_list *stars,
69  const cpl_propertylist *header)
70 {
71  cpl_wcs *wcs = NULL;
72 
73  cpl_matrix *from = NULL;
74  cpl_matrix *to = NULL;
75  cpl_array *status = NULL;
76 
77  cassure_automsg( stars != NULL,
78  CPL_ERROR_NULL_INPUT,
79  return);
80  cassure_automsg( header != NULL,
81  CPL_ERROR_NULL_INPUT,
82  return);
83 
84  if (fors_std_star_list_size(stars) == 0) {
85  cleanup;
86  return;
87  }
88 
89  wcs = cpl_wcs_new_from_propertylist(header);
90  assure( !cpl_error_get_code(), return,
91  "Failed to get WCS from header");
92 
93  {
94  fors_std_star *star;
95  int i;
96 
97  from = cpl_matrix_new(fors_std_star_list_size(stars), 2);
98 
99  for (star = fors_std_star_list_first(stars), i = 0;
100  star != NULL;
101  star = fors_std_star_list_next(stars), i++) {
102 
103  cpl_matrix_set(from, i, 0, star->ra);
104  cpl_matrix_set(from, i, 1, star->dec);
105  }
106 
107  cpl_wcs_convert(wcs, from,
108  &to, &status,
109  CPL_WCS_WORLD2PHYS);
110 
111  /* The WCSLIB call sometimes fails with the error message
112  "WCSLIB One or more input coordinates invalid",
113  while all status flags are 0.
114  */
115  if (cpl_error_get_code() == CPL_ERROR_UNSPECIFIED) {
116  cpl_msg_warning(cpl_func,
117  "Ignoring WCSLIB unspecified error");
118  cpl_error_reset();
119  }
120 
121  assure( !cpl_error_get_code(), return,
122  "Failed to convert from world to physical coordinates");
123 
124  assure( cpl_matrix_get_ncol(to) == 2,
125  return, "%"CPL_SIZE_FORMAT" columns, 2 expected",
126  cpl_matrix_get_ncol(to));
127 
128  assure( cpl_matrix_get_nrow(to) == fors_std_star_list_size(stars),
129  return, "%"CPL_SIZE_FORMAT" rows, %d expected",
130  cpl_matrix_get_nrow(to), fors_std_star_list_size(stars));
131 
132  assure( status != NULL, return, NULL );
133 
134  assure( cpl_array_get_size(status) == fors_std_star_list_size(stars),
135  return, "Status array size is %"CPL_SIZE_FORMAT", %d expected",
136  cpl_array_get_size(status), fors_std_star_list_size(stars));
137 
138  for (star = fors_std_star_list_first(stars), i = 0;
139  star != NULL;
140  star = fors_std_star_list_next(stars), i++) {
141 
142  if (cpl_array_get_int(status, i, NULL) != 0) {
143  cpl_msg_warning(cpl_func, "Catalogue star %d: "
144  "non-zero status = %d from WCSLIB",
145  i, cpl_array_get_int(status, i, NULL));
146  }
147  star->pixel->x = cpl_matrix_get(to, i, 0);
148  star->pixel->y = cpl_matrix_get(to, i, 1);
149  }
150  }
151 
152 #if 0 /* pre WCSLIB code */
153  double deg_pr_pixel = 0.1/3600;
154  fors_std_star *star;
155 
156  cpl_msg_warning(cpl_func,
157  "WCSLIB not available, "
158  "applying fake transformation");
159 
160  for (star = fors_std_star_list_first(stars);
161  star != NULL;
162  star = fors_std_star_list_next(stars)) {
163 
164  star->pixel->x = (star->ra / deg_pr_pixel - 293000)/10;
165  star->pixel->y = (star->dec / deg_pr_pixel / 10 + 169800)/10;
166  }
167 #endif
168 
169  cleanup;
170  return;
171 }
172 
173 
174 #undef cleanup
175 #define cleanup \
176 do { \
177  cpl_table_delete(t); \
178 } while (0)
179 
192 void fors_phot_table_load(const cpl_frame *phot_table_frame,
193  const fors_setting *setting,
194  double *color_term,
195  double *dcolor_term,
196  double *ext_coeff,
197  double *dext_coeff,
198  double *expected_zeropoint,
199  double *dexpected_zeropoint)
200 {
201  cpl_table *t = NULL;
202 
203  assure( setting != NULL, return, NULL );
204 /* %%%
205  assure( setting->filter_name != NULL, return, "No filter name provided");
206 */
207  assure( phot_table_frame != NULL, return, NULL );
208  /* color_term may be NULL */
209  /* assure( ext_coeff != NULL, return, NULL ); it may also be NULL (Carlo) */
210  /* expected_zeropoint may be NULL */
211 
212  assure( (color_term == NULL) == (dcolor_term == NULL), return, NULL );
213  assure( (ext_coeff == NULL) == (dext_coeff == NULL), return, NULL );
214  assure( (expected_zeropoint == NULL) == (dexpected_zeropoint == NULL),
215  return, NULL );
216 
217  assure( cpl_frame_get_filename(phot_table_frame) != NULL, return, NULL );
218 
219  if (color_term) {
220  *color_term = 0.0;
221  *dcolor_term = 0.0;
222  }
223  if (ext_coeff) {
224  *ext_coeff = 0.0;
225  *dext_coeff = 0.0;
226  }
227  if (expected_zeropoint) {
228  *expected_zeropoint = 0.0;
229  *dexpected_zeropoint = 0.0;
230  }
231 
232  if (setting->filter_name == NULL) {
233  cpl_msg_warning(cpl_func, "Zeropoint computation is not supported "
234  "for non-standard filters");
235  return;
236  }
237 
238  /* Verify instrument setting */
239  //fixme: for user-friendliness we should verify the setting, except the filter
240  // (because this table contains data for all filters)
241  if (0) {
242  fors_setting_verify(setting, phot_table_frame, NULL);
243  assure( !cpl_error_get_code(), return,
244  "Could not verify %s setting",
245  cpl_frame_get_filename(phot_table_frame));
246  }
247 
248  t = cpl_table_load(cpl_frame_get_filename(phot_table_frame), 1, 1);
249 
250  assure( !cpl_error_get_code(), return, "Could not load %s",
251  cpl_frame_get_filename(phot_table_frame));
252 
253  assure( cpl_table_get_nrow(t) > 0, return,
254  "Empty table %s", cpl_frame_get_filename(phot_table_frame));
255 
256  {
257  const char *const colname[] = {
258  FORS_DATA_PHOT_FILTER,
259  FORS_DATA_PHOT_EXTCOEFF,
260  FORS_DATA_PHOT_DEXTCOEFF,
261  FORS_DATA_PHOT_ZEROPOINT,
262  FORS_DATA_PHOT_DZEROPOINT,
263  FORS_DATA_PHOT_COLORTERM,
264  FORS_DATA_PHOT_DCOLORTERM};
265 
266  const cpl_type coltype[] = {CPL_TYPE_STRING,
267  CPL_TYPE_DOUBLE,
268  CPL_TYPE_DOUBLE,
269  CPL_TYPE_DOUBLE,
270  CPL_TYPE_DOUBLE,
271  CPL_TYPE_DOUBLE,
272  CPL_TYPE_DOUBLE};
273 
274  int colrequired[7]; /* same # of elements as above */
275 
276  colrequired[0] = 1;
277  colrequired[1] = ext_coeff ? 1 : 0;
278  colrequired[2] = ext_coeff ? 1 : 0;
279  colrequired[3] = expected_zeropoint ? 1 : 0;
280  colrequired[4] = expected_zeropoint ? 1 : 0;
281  colrequired[5] = color_term ? 1 : 0;
282  colrequired[6] = color_term ? 1 : 0;
283 
284  unsigned i;
285  for (i = 0; i < sizeof(colname) / sizeof(*colname); i++) {
286 
287  if (colrequired[i]) {
288  assure( cpl_table_has_column(t, colname[i]), return,
289  "%s: Missing column %s",
290  cpl_frame_get_filename(phot_table_frame), colname[i]);
291 
292  assure( cpl_table_get_column_type(t, colname[i]) == coltype[i],
293  return,
294  "%s column %s type is %s, %s expected",
295  cpl_frame_get_filename(phot_table_frame),
296  colname[i],
297  fors_type_get_string(cpl_table_get_column_type(t,
298  colname[i])),
299  fors_type_get_string(coltype[i]));
300 
301  assure( cpl_table_count_invalid(t, colname[i]) == 0, return,
302  "%s column %s has invalid values",
303  cpl_frame_get_filename(phot_table_frame),
304  colname[i]);
305  }
306  }
307  }
308  /* Input validation done */
309 
310  cpl_msg_debug(cpl_func, "Searching for filter: %s", setting->filter_name);
311 
312  bool found = false;
313  int i;
314  for (i = 0; i < cpl_table_get_nrow(t) && !found; i++) {
315  const char *phot_filter = cpl_table_get_string(t, FORS_DATA_PHOT_FILTER, i);
316 
317  assure( phot_filter != NULL, return, "%s, row %d: Null %s",
318  cpl_frame_get_filename(phot_table_frame), i+1, FORS_DATA_PHOT_FILTER);
319 
320  if (strcmp(setting->filter_name, phot_filter) == 0) {
321 
322  found = true;
323 
324  if (color_term != NULL) {
325  *color_term = cpl_table_get_double(t, FORS_DATA_PHOT_COLORTERM, i, NULL);
326  *dcolor_term = cpl_table_get_double(t, FORS_DATA_PHOT_DCOLORTERM, i, NULL);
327  }
328 
329  if (ext_coeff != NULL) {
330  *ext_coeff = cpl_table_get_double(t, FORS_DATA_PHOT_EXTCOEFF, i, NULL);
331  *dext_coeff = cpl_table_get_double(t, FORS_DATA_PHOT_DEXTCOEFF, i, NULL);
332  }
333 
334  if (expected_zeropoint != NULL) {
335  *expected_zeropoint =
336  cpl_table_get_double(t, FORS_DATA_PHOT_ZEROPOINT, i, NULL);
337  *dexpected_zeropoint =
338  cpl_table_get_double(t, FORS_DATA_PHOT_DZEROPOINT, i, NULL);
339  }
340  }
341  }
342 
343  if (found == false) {
344  cpl_msg_warning(cpl_func, "Entry for filter %s missing in input "
345  "photometric table (%s): assuming all photometric "
346  "coefficients Z, E, and color term, equal to zero.",
347  setting->filter_name,
348  cpl_frame_get_filename(phot_table_frame));
349  *color_term = 0.0;
350  *dcolor_term = 0.0;
351  *ext_coeff = 0.0;
352  *dext_coeff = 0.0;
353  *expected_zeropoint = 0.0;
354  *dexpected_zeropoint = 0.0;
355  }
356 
357  /*
358  assure( found, return, "%s: Missing entry for filter '%s'",
359  cpl_frame_get_filename(phot_table_frame), setting->filter_name);
360  */
361 
362  cleanup;
363  return;
364 }
365 
366 
367 #undef cleanup
368 #define cleanup \
369 do { \
370  cpl_table_delete(table); \
371 } while(0)
372 
389 cpl_table *fors_phot_coeff_create(const fors_setting *setting,
390  double color_term,
391  double dcolor_term,
392  double ext_coeff,
393  double dext_coeff,
394  double zeropoint,
395  double dzeropoint)
396 {
397  cpl_table *table = cpl_table_new(1);
398 
399  if (table == NULL) {
400  return NULL;
401  }
402 
403  if (dcolor_term > 0.0 || dext_coeff > 0.0 || dzeropoint > 0.0) {
404  cpl_table_new_column(table, FORS_DATA_PHOT_FILTER, CPL_TYPE_STRING);
405  cpl_table_set_string(table, FORS_DATA_PHOT_FILTER,
406  0, setting->filter_name);
407  }
408  else {
409  cleanup;
410  return NULL;
411  }
412 
413  /*
414  * Create only the necessary columns for the new table
415  */
416 
417  if (dext_coeff > 0.0) {
418  cpl_table_new_column(table, FORS_DATA_PHOT_EXTCOEFF, CPL_TYPE_DOUBLE);
419  cpl_table_new_column(table, FORS_DATA_PHOT_DEXTCOEFF, CPL_TYPE_DOUBLE);
420  cpl_table_set_double(table, FORS_DATA_PHOT_EXTCOEFF, 0, ext_coeff);
421  cpl_table_set_double(table, FORS_DATA_PHOT_DEXTCOEFF, 0, dext_coeff);
422  }
423 
424  if (dzeropoint > 0.0) {
425  cpl_table_new_column(table, FORS_DATA_PHOT_ZEROPOINT, CPL_TYPE_DOUBLE);
426  cpl_table_new_column(table, FORS_DATA_PHOT_DZEROPOINT, CPL_TYPE_DOUBLE);
427  cpl_table_set_double(table, FORS_DATA_PHOT_ZEROPOINT, 0, zeropoint);
428  cpl_table_set_double(table, FORS_DATA_PHOT_DZEROPOINT, 0, dzeropoint);
429  }
430 
431  if (dcolor_term > 0.0) {
432  cpl_table_new_column(table, FORS_DATA_PHOT_COLORTERM, CPL_TYPE_DOUBLE);
433  cpl_table_new_column(table, FORS_DATA_PHOT_DCOLORTERM, CPL_TYPE_DOUBLE);
434  cpl_table_set_double(table, FORS_DATA_PHOT_COLORTERM, 0, color_term);
435  cpl_table_set_double(table, FORS_DATA_PHOT_DCOLORTERM, 0, dcolor_term);
436  }
437 
438  return table;
439 }
const char * fors_type_get_string(cpl_type t)
Textual representation of CPL type.
Definition: fors_utils.c:496
void fors_setting_verify(const fors_setting *ref_setting, const cpl_frame *frame, fors_setting **setting)
Verify that instrument settings are compatible.
Definition: fors_setting.c:401
#define assure(EXPR)
Definition: list.c:101