FORS Pipeline Reference Manual  4.12.5
fors_std_cat.c
1 /* $Id: fors_std_cat.c,v 1.21 2013-09-10 15:19:08 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-09-10 15:19:08 $
24  * $Revision: 1.21 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 #include <fors_std_star.h>
33 #include <fors_utils.h>
34 #include <fors_instrument.h>
35 
36 #include <math.h>
37 #include <stdbool.h>
38 #include <string.h>
39 
40 const char *const FORS_STD_CAT_COLUMN_RA = "RA";
41 const char *const FORS_STD_CAT_COLUMN_DEC = "DEC";
42 const char *const FORS_STD_CAT_COLUMN_NAME = "OBJECT";
43 
44 typedef struct band_jacobian {
45  char band;
46  double mag[6]; /* 5 inputs, 1 constant */
47  double col[6]; /* 5 inputs, 1 constant */
49 
50 static void
51 fors_std_cat_propagate_uncorrelated_inputs( const double *in,
52  const double *din,
53  const double *jacobi_A,
54  const double *jacobi_B,
55  int size,
56  double *out_A,
57  double *out_B,
58  double *dout_A,
59  double *dout_B,
60  double *cov_AB);
61 
62 static cpl_error_code
63 fors_std_cat_import_generic_star( const double *band_values,
64  const double *band_errors,
65  const band_jacobian *jacobians,
66  int nband_values,
67  int nbands,
68  char band,
69  double *cat_mag,
70  double *dcat_mag,
71  double *color,
72  double *dcolor,
73  double *cov_catmag_color);
74 
75 static bool
76 fors_std_cat_check_band_support( cpl_error_code (*import_func)(
77  double *values,
78  double *errors,
79  char band,
80  double *out_A,
81  double *dout_A,
82  double *out_B,
83  double *dout_B,
84  double *out_cov),
85  int nvalues,
86  char band);
87 
88 static bool*
89 fors_std_cat_determine_required_columns( cpl_error_code (*import_func)(
90  double *values,
91  double *errors,
92  char band,
93  double *out_A,
94  double *dout_A,
95  double *out_B,
96  double *dout_B,
97  double *out_cov),
98  int nvalues,
99  char band);
100 
101 static cpl_error_code
102 fors_std_cat_reject_not_required_columns( cpl_array *column_names,
103  cpl_error_code (*import_func)(
104  double *values,
105  double *errors,
106  char band,
107  double *out_A,
108  double *dout_A,
109  double *out_B,
110  double *dout_B,
111  double *out_cov),
112  char band);
113 
114 static bool
115 fors_std_cat_table_check_columns( const cpl_table *cat_table,
116  const cpl_array *columns);
117 
118 static cpl_array *
119 fors_std_cat_create_error_column_names( const cpl_array *colnames);
120 
121 static cpl_error_code
122 fors_std_cat_landolt_star_import( double v_bv_ub_vr_vi[5],
123  double ERR_v_bv_ub_vr_vi[5],
124  char band,
125  double *cat_mag,
126  double *dcat_mag,
127  double *color,
128  double *dcolor,
129  double *cov_catmag_color);
130 
131 static cpl_array *
132 fors_std_cat_landolt_get_column_names( void);
133 
134 static cpl_error_code
135 fors_std_cat_stetson_star_import( double u_b_v_r_i[5],
136  double ERR_u_b_v_r_i[5],
137  char band,
138  double *cat_mag,
139  double *dcat_mag,
140  double *color,
141  double *dcolor,
142  double *cov_catmag_color);
143 
144 static cpl_array *
145 fors_std_cat_stetson_get_column_names( void);
146 
147 static bool
148 fors_std_cat_check_method_and_columns( cpl_table *catalogue,
149  cpl_array *colnames,
150  cpl_error_code (*import_func)(
151  double *values,
152  double *errors,
153  char band,
154  double *out_A,
155  double *dout_A,
156  double *out_B,
157  double *dout_B,
158  double *out_cov),
159  char band,
160  const char *method,
161  cpl_array **err_colnames,
162  bool *method_supports_band);
163 
164 #undef cleanup
165 #define cleanup
166 
180 static void
181 fors_std_cat_propagate_uncorrelated_inputs( const double *in,
182  const double *din,
183  const double *jacobi_A,
184  const double *jacobi_B,
185  int size,
186  double *out_A,
187  double *out_B,
188  double *dout_A,
189  double *dout_B,
190  double *cov_AB)
191 {
192  int n;
193 
194  *out_A = 0;
195  *out_B = 0;
196  *dout_A = 0;
197  *dout_B = 0;
198  *cov_AB = 0;
199 
200  for (n = 0; n < size; n++)
201  {
202  /* uncorrelated inputs are assumed! */
203  *out_A += (*jacobi_A) * (*in);
204  *out_B += (*jacobi_B) * (*in);
205  *dout_A += (*jacobi_A)*(*jacobi_A) * (*din)*(*din);
206  *dout_B += (*jacobi_B)*(*jacobi_B) * (*din)*(*din);
207  *cov_AB += (*jacobi_A)*(*jacobi_B) * (*din)*(*din);
208  jacobi_A++;
209  jacobi_B++;
210  in++;
211  din++;
212  }
213 
214  *dout_A = sqrt(*dout_A);
215  *dout_B = sqrt(*dout_B);
216 }
217 
218 #undef cleanup
219 #define cleanup
220 
247 static cpl_error_code
248 fors_std_cat_import_generic_star( const double *band_values,
249  const double *band_errors,
250  const band_jacobian *jacobians,
251  int nband_values,
252  int nbands,
253  char band,
254  double *cat_mag,
255  double *dcat_mag,
256  double *color,
257  double *dcolor,
258  double *cov_catmag_color)
259 {
260  int ib;
261  for (ib = 0; ib <= nbands; ib++)
262  {
263  if (jacobians[ib].band == band)
264  {
265  fors_std_cat_propagate_uncorrelated_inputs(
266  band_values,
267  band_errors,
268  jacobians[ib].mag,
269  jacobians[ib].col,
270  nband_values,
271  cat_mag,
272  color,
273  dcat_mag,
274  dcolor,
275  cov_catmag_color);
276  /* constant term */
277  *cat_mag += jacobians[ib].mag[nband_values];
278  *color += jacobians[ib].col[nband_values];
279 
280  return CPL_ERROR_NONE;
281  }
282  }
283 
284  cpl_error_set_message( cpl_func,
285  CPL_ERROR_UNSUPPORTED_MODE,
286  "unknown band \'%c\'",
287  band);
288  return cpl_error_get_code();
289 }
290 
291 #undef cleanup
292 #define cleanup \
293 do { \
294  cpl_free(values); values = NULL; \
295  cpl_free(errors); errors = NULL; \
296 } while (0)
297 
304 static bool
305 fors_std_cat_check_band_support( cpl_error_code (*import_func)(
306  double *values,
307  double *errors,
308  char band,
309  double *out_A,
310  double *dout_A,
311  double *out_B,
312  double *dout_B,
313  double *out_cov),
314  int nvalues,
315  char band)
316 {
317  double *values = NULL,
318  *errors = NULL;
319  double out[5];
320  cpl_errorstate errstat = cpl_errorstate_get();
321 
322 
323  values = cpl_calloc(nvalues, sizeof(*values));
324  errors = cpl_calloc(nvalues, sizeof(*errors));
325  (*import_func)( values, errors, band,
326  out + 0, out + 1, out + 2, out + 3, out + 4);
327  cpl_free(values);
328  cpl_free(errors);
329 
330  if (!cpl_errorstate_is_equal(errstat))
331  {
332  if (cpl_error_get_code() == CPL_ERROR_UNSUPPORTED_MODE)
333  {
334  cpl_errorstate_set(errstat); /* reset error */
335  }
336  else
337  {
338  cpl_error_set_where(cpl_func);
339  }
340  return false;
341  }
342  else
343  return true;
344 }
345 
346 #undef cleanup
347 #define cleanup \
348 do { \
349  cpl_free(required); required = NULL; \
350  cpl_free(values); values = NULL; \
351  cpl_free(errors); errors = NULL; \
352 } while (0)
353 
364 static bool*
365 fors_std_cat_determine_required_columns( cpl_error_code (*import_func)(
366  double *values,
367  double *errors,
368  char band,
369  double *out_A,
370  double *dout_A,
371  double *out_B,
372  double *dout_B,
373  double *out_cov),
374  int nvalues,
375  char band)
376 {
377  bool *required = NULL;
378  double *values = NULL,
379  *errors = NULL;
380  double out_offset[5];
381  int n;
382  cpl_errorstate errstat = cpl_errorstate_get();
383 
384  values = cpl_calloc(nvalues, sizeof(*values));
385  errors = cpl_calloc(nvalues, sizeof(*errors));
386  required = cpl_calloc(nvalues, sizeof(*required));
387 
388  /* get offset output values @ all inputs = 0.0 */
389  (*import_func)( values,
390  errors,
391  band,
392  out_offset + 0,
393  out_offset + 1,
394  out_offset + 2,
395  out_offset + 3,
396  out_offset + 4);
397 
398  /* successively switch on inputs
399  * (here we assume of course that they contribute independently) */
400  for (n = 0; n < nvalues; n++)
401  {
402  double out[5];
403  int i;
404 
405  values[n] = 1;
406  errors[n] = 1;
407  if (n > 0)
408  {
409  values[n-1] = 0;
410  errors[n-1] = 0;
411  }
412 
413  (*import_func)( values,
414  errors,
415  band,
416  out + 0,
417  out + 1,
418  out + 2,
419  out + 3,
420  out + 4);
421  if (!cpl_errorstate_is_equal(errstat))
422  {
423  cpl_error_set_where(cpl_func);
424  cleanup;
425  return required;
426  }
427 
428  for (i = 0; i < 5; i++)
429  if (fabs(out[i] - out_offset[i]) > 10*DBL_EPSILON)
430  required[n] = true;
431  }
432 
433  cpl_free(values);
434  cpl_free(errors);
435 
436  return required;
437 }
438 
439 #undef cleanup
440 #define cleanup \
441 do { \
442  cpl_free(required); required = NULL; \
443 } while (0)
444 
451 static cpl_error_code
452 fors_std_cat_reject_not_required_columns( cpl_array *column_names,
453  cpl_error_code (*import_func)(
454  double *values,
455  double *errors,
456  char band,
457  double *out_A,
458  double *dout_A,
459  double *out_B,
460  double *dout_B,
461  double *out_cov),
462  char band)
463 {
464  bool *required = NULL;
465  int ncolumns,
466  n;
467  cpl_errorstate errstat = cpl_errorstate_get();
468 
469  cassure_automsg( import_func != NULL,
470  CPL_ERROR_NULL_INPUT,
471  return cpl_error_get_code());
472  cassure_automsg( column_names != NULL,
473  CPL_ERROR_NULL_INPUT,
474  return cpl_error_get_code());
475  cassure_automsg( cpl_array_get_type(column_names)
476  == CPL_TYPE_STRING,
477  CPL_ERROR_NULL_INPUT,
478  return cpl_error_get_code());
479 
480  ncolumns = cpl_array_get_size(column_names);
481  required = fors_std_cat_determine_required_columns(
482  import_func,
483  ncolumns,
484  band);
485  assure( cpl_errorstate_is_equal(errstat),
486  return cpl_error_get_code(),
487  NULL);
488 
489  for (n = 0; n < ncolumns; n++)
490  {
491  if (!required[n])
492  {
493  cpl_array_set_invalid(column_names, n);
494  }
495  else
496  {
497  const char *name;
498  name = cpl_array_get_string(column_names, n);
499  if (name == NULL || name[0] == '\0')
500  {
501  cpl_error_set_message( cpl_func,
502  CPL_ERROR_DATA_NOT_FOUND,
503  "column %d required, but name not "
504  "specified",
505  n);
506  cleanup;
507  return cpl_error_get_code();
508  }
509  }
510  }
511  cpl_free(required);
512 
513  return (cpl_errorstate_is_equal(errstat) ?
514  CPL_ERROR_NONE :
515  cpl_error_get_code());
516 }
517 
518 #undef cleanup
519 #define cleanup
520 
528 static bool
529 fors_std_cat_table_check_columns( const cpl_table *cat_table,
530  const cpl_array *columns)
531 {
532  int ncols,
533  n;
534  cassure_automsg( cat_table != NULL,
535  CPL_ERROR_NULL_INPUT,
536  return false);
537  cassure_automsg( columns != NULL,
538  CPL_ERROR_NULL_INPUT,
539  return false);
540  cassure_automsg( cpl_array_get_type(columns)
541  == CPL_TYPE_STRING,
542  CPL_ERROR_NULL_INPUT,
543  return false);
544 
545  ncols = cpl_array_get_size(columns);
546  for (n = 0; n < ncols; n++)
547  {
548  const char *cs;
549  cs = cpl_array_get_string(columns, n);
550  if (cs != NULL
551  && (!cpl_table_has_column(cat_table, cs)))
552  {
553  return false;
554  }
555  }
556  return true;
557 }
558 
559 #undef cleanup
560 #define cleanup \
561 do { \
562  cpl_array_delete(errcolnames); errcolnames = NULL; \
563 } while (0)
564 
571 static cpl_array *
572 fors_std_cat_create_error_column_names( const cpl_array *colnames)
573 {
574  cpl_array *errcolnames = NULL;
575  int size,
576  n;
577 
578  cassure_automsg( colnames != NULL,
579  CPL_ERROR_NULL_INPUT,
580  return errcolnames);
581  cassure_automsg( cpl_array_get_type(colnames)
582  == CPL_TYPE_STRING,
583  CPL_ERROR_NULL_INPUT,
584  return errcolnames);
585 
586  size = cpl_array_get_size(colnames);
587 
588  errcolnames = cpl_array_new(size, CPL_TYPE_STRING);
589  for (n = 0; n < size; n++)
590  {
591  char estr[10];
592  const char *cs;
593  cs = cpl_array_get_string(colnames, n);
594  if (cs != NULL)
595  {
596  snprintf(estr, 9, "ERR_%s", cs);
597  cpl_array_set_string(errcolnames, n, estr);
598  }
599  }
600  return errcolnames;
601 }
602 
603 #undef cleanup
604 #define cleanup
605 
621 static cpl_error_code
622 fors_std_cat_landolt_star_import( double v_bv_ub_vr_vi[5],
623  double ERR_v_bv_ub_vr_vi[5],
624  char band,
625  double *cat_mag,
626  double *dcat_mag,
627  double *color,
628  double *dcolor,
629  double *cov_catmag_color)
630 {
631  cpl_error_code errc;
632 
633  static const band_jacobian jacobians[6] =
634  { /* V B-V U-B V-R V-I 1(const) */
635  { 'U', { 1, 1, 1, 0, 0, 0,},
636  { 0, 0, 1, 0, 0, 0,}, },
637  { 'B', { 1, 1, 0, 0, 0, 0,},
638  { 0, 1, 0, 0, 0, 0,}, },
639  /*(Fukugita et al. 1996, AJ 111, p1748)*/
640  { 'G', { 1, 0.56, 0, 0, 0,-0.12,},
641  { 0, 1, 0, 0, 0, 0,}, },
642  { 'V', { 1, 0, 0, 0, 0, 0,},
643  { 0, 1, 0, 0, 0, 0,}, },
644  { 'R', { 1, 0, 0, -1, 0, 0,},
645  { 0, 0, 0, 1, 0, 0,}, },
646  { 'I', { 1, 0, 0, 0, -1, 0,},
647  { 0, 0, 0, 1, 0, 0,}, },
648  };
649 
650  errc = fors_std_cat_import_generic_star(v_bv_ub_vr_vi,
651  ERR_v_bv_ub_vr_vi,
652  jacobians,
653  5, /* jac. columns without const */
654  6, /* n bands (U, B, G, ...) */
655  band,
656  cat_mag,
657  dcat_mag,
658  color,
659  dcolor,
660  cov_catmag_color);
661  if (errc != CPL_ERROR_NONE)
662  cpl_error_set_where(cpl_func);
663  return errc;
664 }
665 
666 #undef cleanup
667 #define cleanup
668 
675 static cpl_array *
676 fors_std_cat_landolt_get_column_names( void)
677 {
678  const char landolt_columns[5][4] = { "V", "B_V", "U_B", "V_R", "V_I" };
679  cpl_array *columns = NULL;
680  int c;
681 
682  columns = cpl_array_new(5, CPL_TYPE_STRING);
683 
684  for (c = 0; c < 5; c++)
685  cpl_array_set_string(columns, c, landolt_columns[c]);
686 
687  return columns;
688 }
689 
690 #undef cleanup
691 #define cleanup
692 
708 static cpl_error_code
709 fors_std_cat_stetson_star_import( double u_b_v_r_i[5],
710  double ERR_u_b_v_r_i[5],
711  char band,
712  double *cat_mag,
713  double *dcat_mag,
714  double *color,
715  double *dcolor,
716  double *cov_catmag_color)
717 {
718  cpl_error_code errc;
719 
720  static const band_jacobian jacobians[6] =
721  { /* U B V R I 1(const) */
722  { 'U', { 1, 0, 0, 0, 0, 0,},
723  { 1, -1, 0, 0, 0, 0,}, },
724  { 'B', { 0, 1, 0, 0, 0, 0,},
725  { 0, 1, -1, 0, 0, 0,}, },
726  /*(Fukugita et al. 1996, AJ 111, p1748)*/
727  { 'G', { 0, 0.56,(1.0-0.56),0, 0,-0.12,},
728  { 0, 1, -1, 0, 0, 0,}, },
729  { 'V', { 0, 0, 1, 0, 0, 0,},
730  { 0, 1, -1, 0, 0, 0,}, },
731  { 'R', { 0, 0, 0, 1, 0, 0,},
732  { 0, 0, 1, -1, 0, 0,}, },
733  { 'I', { 0, 0, 0, 0, 1, 0,},
734  { 0, 0, 1, -1, 0, 0,}, },
735  };
736 
737  errc = fors_std_cat_import_generic_star(u_b_v_r_i,
738  ERR_u_b_v_r_i,
739  jacobians,
740  5, /* jac. columns without const */
741  6, /* n bands (U, B, G, ...) */
742  band,
743  cat_mag,
744  dcat_mag,
745  color,
746  dcolor,
747  cov_catmag_color);
748  if (errc != CPL_ERROR_NONE)
749  cpl_error_set_where(cpl_func);
750  return errc;
751 }
752 
753 #undef cleanup
754 #define cleanup
755 
762 static cpl_array *
763 fors_std_cat_stetson_get_column_names( void)
764 {
765  const char stetson_columns[5][2] = { "U", "B", "V", "R", "I" };
766  cpl_array *columns = NULL;
767  int c;
768 
769  columns = cpl_array_new(5, CPL_TYPE_STRING);
770 
771  for (c = 0; c < 5; c++)
772  cpl_array_set_string(columns, c, stetson_columns[c]);
773 
774  return columns;
775 }
776 
777 #undef cleanup
778 #define cleanup \
779 do { \
780  if (err_colnames != NULL) \
781  { cpl_array_delete(*err_colnames); *err_colnames = NULL; } \
782  cat_type_detected = false; \
783 } while (0)
784 
799 static bool
800 fors_std_cat_check_method_and_columns( cpl_table *catalogue,
801  cpl_array *colnames,
802  cpl_error_code (*import_func)(
803  double *values,
804  double *errors,
805  char band,
806  double *out_A,
807  double *dout_A,
808  double *out_B,
809  double *dout_B,
810  double *out_cov),
811  char band,
812  const char *method,
813  cpl_array **err_colnames,
814  bool *method_supports_band)
815 {
816  bool band_supported = false,
817  cat_type_detected = false;
818  int ncols;
819  cpl_errorstate errstat = cpl_errorstate_get();
820 
821  cassure_automsg( catalogue != NULL,
822  CPL_ERROR_NULL_INPUT,
823  return cat_type_detected);
824  cassure_automsg( colnames != NULL,
825  CPL_ERROR_NULL_INPUT,
826  return cat_type_detected);
827  cassure_automsg( cpl_array_get_type(colnames)
828  == CPL_TYPE_STRING,
829  CPL_ERROR_NULL_INPUT,
830  return cat_type_detected);
831  cassure_automsg( import_func != NULL,
832  CPL_ERROR_NULL_INPUT,
833  return cat_type_detected);
834  cassure_automsg( method != NULL,
835  CPL_ERROR_NULL_INPUT,
836  return cat_type_detected);
837  cassure_automsg( err_colnames != NULL,
838  CPL_ERROR_NULL_INPUT,
839  return cat_type_detected);
840 
841  cleanup;
842 
843  ncols = cpl_array_get_size(colnames);
844  band_supported = fors_std_cat_check_band_support(
845  import_func,
846  ncols,
847  band);
848  if (band_supported)
849  {
850  int n;
851  /* determine the required values for the import function,
852  * and set other column names to NULL */
853  fors_std_cat_reject_not_required_columns(
854  colnames,
855  import_func,
856  band);
857 
858  /* for column names != NULL, prepend "ERR_" */
859  *err_colnames = fors_std_cat_create_error_column_names(colnames);
860 
861  for (n = 0; n < ncols; n++)
862  {
863  const char *s[2];
864  int i;
865  s[0] = cpl_array_get_string(colnames, n);
866  s[1] = cpl_array_get_string(*err_colnames, n);
867  if (s[0] != NULL)
868  for (i = 0; i < 2; i++)
869  {
870  cpl_msg_debug(cpl_func, "Required %s column for band %c: "
871  "%s (%sfound)",
872  method, band, s[i],
873  ( cpl_table_has_column(
874  catalogue, s[i]) ?
875  "" : "not ")
876  );
877  }
878  }
879 
880  /* check presence of column names != NULL */
881  cat_type_detected = ( fors_std_cat_table_check_columns(
882  catalogue,
883  colnames)
884  && fors_std_cat_table_check_columns(
885  catalogue,
886  *err_colnames));
887  }
888  if (method_supports_band != NULL)
889  *method_supports_band = band_supported;
890 
891  assure(cpl_errorstate_is_equal(errstat), return cat_type_detected, NULL);
892 
893  return cat_type_detected;
894 }
895 
896 #undef cleanup
897 #define cleanup \
898 do { \
899  fors_std_star_list_delete(&stdlist, fors_std_star_delete); \
900  fors_std_star_delete(&std_star); \
901  cpl_array_delete(columns); columns = NULL; \
902  cpl_array_delete(err_columns); err_columns = NULL; \
903  cpl_array_delete(frame_error_messages); frame_error_messages = NULL; \
904  cpl_table_delete(cat_table); cat_table = NULL; \
905  cpl_free(band_values); band_values = NULL; \
906  cpl_free(band_errors); band_errors = NULL; \
907 } while (0)
908 
915 fors_std_star_list *
916 fors_std_cat_load( const cpl_frameset *cat_frames,
917  char band,
918  bool require_all_frames,
919  double color_term,
920  double dcolor_term)
921 {
922  fors_std_star_list *stdlist = NULL;
923  fors_std_star *std_star = NULL;
924  cpl_array *columns = NULL,
925  *err_columns = NULL,
926  *frame_error_messages = NULL;
927  char **frame_error_strings = NULL;
928  cpl_table *cat_table = NULL;
929  const cpl_frame *cat_frame;
930  double *band_values = NULL,
931  *band_errors = NULL;
932  int iframe,
933  last_imethod = -1,
934  n_cat_entries = 0;
935  bool printed_warning = false,
936  checked_support = false,
937  printed_supported = false;
938  cpl_errorstate errstat = cpl_errorstate_get();
939 
940  struct method {
941  cpl_array* (*get_column_names_func)(void);
942  cpl_error_code (*star_import_func)(
943  double *values,
944  double *errors,
945  char band,
946  double *cat_mag,
947  double *dcat_mag,
948  double *color,
949  double *dcolor,
950  double *cov_catmag_color);
951  const char name[10];
952  bool band_supported;
953  } methods[2] = { { fors_std_cat_landolt_get_column_names,
954  fors_std_cat_landolt_star_import,
955  "Landolt",
956  false},
957  { fors_std_cat_stetson_get_column_names,
958  fors_std_cat_stetson_star_import,
959  "Stetson",
960  false}
961  };
962 
963  /* check input */
964  cassure_automsg( cat_frames != NULL,
965  CPL_ERROR_NULL_INPUT,
966  return stdlist);
967 
968  cassure( !fors_instrument_filterband_is_none(
969  band),
970  CPL_ERROR_ILLEGAL_INPUT,
971  return stdlist,
972  "no optical/filter band specified");
973  cassure( !fors_instrument_filterband_is_unknown(
974  band),
975  CPL_ERROR_ILLEGAL_INPUT,
976  return stdlist,
977  "optical/filter band is unknown");
978 
979  stdlist = fors_std_star_list_new();
980  /* error message container, don't abuse the error history for that since
981  * its size is limited */
982  frame_error_messages = cpl_array_new( cpl_frameset_get_size(cat_frames),
983  CPL_TYPE_STRING);
984  frame_error_strings = cpl_array_get_data_string(frame_error_messages);
985 
986  /* import all frames */
987  for (cat_frame = cpl_frameset_get_first_const(cat_frames), iframe = 0;
988  cat_frame != NULL;
989  cat_frame = cpl_frameset_get_next_const(cat_frames), iframe++)
990  {
991  int ncolumns,
992  row,
993  nrows,
994  imethod,
995  nmethods;
996  const char **column_value_names,
997  **column_error_names;
998  const char *filename;
999  bool cat_type_detected = false;
1000 
1001  filename = cpl_frame_get_filename(cat_frame);
1002  cassure( filename != NULL,
1003  CPL_ERROR_NULL_INPUT,
1004  return stdlist,
1005  "filename of frame %d is NULL",
1006  iframe);
1007 
1008  cpl_table_delete(cat_table);
1009  cat_table = cpl_table_load(filename, 1, 1);
1010  if (!cpl_errorstate_is_equal(errstat))
1011  {
1012  frame_error_strings[iframe] = cpl_sprintf(
1013  "could not load FITS table");
1014  if (require_all_frames)
1015  {
1016  cassure( 0,
1017  CPL_ERROR_DATA_NOT_FOUND,
1018  return stdlist,
1019  "%s: %s",
1020  filename,
1021  frame_error_strings[iframe]);
1022  }
1023  else
1024  {
1025  /* reset last error */
1026  cpl_errorstate_set(errstat);
1027  cpl_msg_warning( cpl_func, "Skipping %s (%s)",
1028  filename,
1029  frame_error_strings[iframe]);
1030  continue; /* skip this frame */
1031  }
1032  }
1033 
1034  /* determine the type of the catalogue, and
1035  * accordingly get the names of the required columns.
1036  * For the import functions, we keep the array with the correct
1037  * order of the input column names, but we just invalidate the
1038  * non-required column names. */
1039  nmethods = sizeof(methods)/sizeof(*methods);
1040  for (imethod = 0; imethod < nmethods; imethod++)
1041  {
1042  cpl_array_delete(columns);
1043  columns = methods[imethod].get_column_names_func();
1044 
1045  cat_type_detected = fors_std_cat_check_method_and_columns(
1046  cat_table,
1047  columns, /* is modified */
1048  methods[imethod].star_import_func,
1049  band,
1050  methods[imethod].name,
1051  &err_columns,
1052  &(methods[imethod].band_supported));
1053  passure(cpl_errorstate_is_equal(errstat), return stdlist);
1054  if (cat_type_detected)
1055  break;
1056  }
1057  if (!cat_type_detected)
1058  {
1059  if (!checked_support) /* FIXME: this should be checked in another
1060  function, called before looping over
1061  frames */
1062  {
1063  bool band_generally_supported = false;
1064  for (imethod = 0; imethod < nmethods; imethod++)
1065  {
1066  band_generally_supported |= methods[imethod].band_supported;
1067  }
1068  if (!band_generally_supported)
1069  {
1070  cpl_error_set_message( cpl_func,
1071  CPL_ERROR_UNSUPPORTED_MODE,
1072  "Optical band %c not supported",
1073  band);
1074  cleanup;
1075  return stdlist;
1076  }
1077  checked_support = true;
1078  }
1079 
1080  /* create an error message for this frame */
1081  if (!printed_supported)
1082  {
1083  char *supported_methods = NULL;
1084  for (imethod = 0; imethod < nmethods; imethod++)
1085  {
1086  if (methods[imethod].band_supported)
1087  {
1088  if (supported_methods == NULL)
1089  {
1090  supported_methods = cpl_sprintf(
1091  "%s",
1092  methods[imethod].name);
1093  }
1094  else /* strcat... */
1095  {
1096  char *s;
1097  s = cpl_sprintf("%s, %s",
1098  supported_methods,
1099  methods[imethod].name);
1100  cpl_free(supported_methods);
1101  supported_methods = s;
1102  }
1103  }
1104  }
1105  cpl_msg_warning( cpl_func,
1106  "Import of band %c supported for: "
1107  "%s",
1108  band,
1109  supported_methods);
1110  cpl_free(supported_methods);
1111  printed_supported = true;
1112  }
1113 
1114  frame_error_strings[iframe] = cpl_sprintf(
1115  "no cat. data for band %c found",
1116  band);
1117  if (require_all_frames)
1118  {
1119  cpl_error_set_message( cpl_func,
1120  CPL_ERROR_DATA_NOT_FOUND,
1121  "%s: %s",
1122  filename,
1123  frame_error_strings[iframe]);
1124  cleanup;
1125  return stdlist;
1126  }
1127  else
1128  {
1129  cpl_msg_warning( cpl_func, "Skipping %s (%s)",
1130  filename,
1131  frame_error_strings[iframe]);
1132  continue; /* skip this frame */
1133  }
1134  }
1135  else
1136  {
1137  cpl_msg_info( cpl_func,
1138  "Loading %s catalogue from %s",
1139  methods[imethod].name,
1140  filename);
1141  }
1142  if (last_imethod >= 0 && last_imethod != imethod && !printed_warning)
1143  {
1144  cpl_msg_warning( cpl_func,
1145  "Merging different types of "
1146  "catalogues");
1147  printed_warning = true;
1148  }
1149  last_imethod = imethod;
1150 
1151  /* prepare the actual import of catalogue values */
1152  ncolumns = cpl_array_get_size(columns);
1153 
1154  cpl_free(band_values);
1155  band_values = cpl_calloc(ncolumns, sizeof(*band_values));
1156  cpl_free(band_errors);
1157  band_errors = cpl_calloc(ncolumns, sizeof(*band_errors));
1158 
1159  column_value_names = cpl_array_get_data_string_const(columns);
1160  column_error_names = cpl_array_get_data_string_const(err_columns);
1161  passure(cpl_errorstate_is_equal(errstat), return stdlist);
1162 
1163  /* done with preparation, import stars from table rows */
1164  nrows = cpl_table_get_nrow(cat_table);
1165  n_cat_entries += nrows;
1166  for (row = 0; row < nrows; row++)
1167  {
1168  int ib,
1169  isnull;
1170  bool valid;
1171 
1172  /* read all required values from table, ignore others to:
1173  * a) save time, and
1174  * b) use stars that were observed in the required bands but not
1175  * in others */
1176  valid = true;
1177  for (ib = 0; ib < ncolumns; ib++)
1178  {
1179  if (column_value_names[ib] != NULL) /* if required */
1180  {
1181  band_values[ib] = cpl_table_get(
1182  cat_table,
1183  column_value_names[ib],
1184  row,
1185  &isnull);
1186  valid &= (isnull == 0);
1187 
1188  passure(column_error_names[ib] != NULL, return stdlist);
1189  band_errors[ib] = cpl_table_get(
1190  cat_table,
1191  column_error_names[ib],
1192  row,
1193  &isnull);
1194  valid &= (isnull == 0);
1195  }
1196  }
1197 
1198  if (!valid)
1199  continue;
1200 
1201  std_star = fors_std_star_new_from_table(
1202  cat_table,
1203  row,
1204  FORS_STD_CAT_COLUMN_RA,
1205  FORS_STD_CAT_COLUMN_DEC,
1206  NULL, NULL, /* corrected mag */
1207  NULL, NULL, /* catalogue mag */
1208  NULL, NULL, /* color */
1209  NULL, /* covariance */
1210  NULL, NULL, /* x, y */
1211  FORS_STD_CAT_COLUMN_NAME);
1212  assure( std_star != NULL,
1213  return stdlist,
1214  NULL);
1215 
1216  methods[imethod].star_import_func(
1217  band_values,
1218  band_errors,
1219  band,
1220  &(std_star->cat_magnitude),
1221  &(std_star->dcat_magnitude),
1222  &(std_star->color),
1223  &(std_star->dcolor),
1224  &(std_star->cov_catm_color));
1225  assure( cpl_errorstate_is_equal(errstat),
1226  return stdlist,
1227  NULL);
1228 
1229  fors_std_star_compute_corrected_mag(
1230  std_star,
1231  color_term,
1232  dcolor_term);
1233 
1234  fors_std_star_list_insert(stdlist, std_star);
1235  std_star = NULL;
1236  }
1237  }
1238 
1239  if (!require_all_frames)
1240  {
1241  cassure( cpl_array_has_invalid(
1242  frame_error_messages),
1243  CPL_ERROR_DATA_NOT_FOUND,
1244  return stdlist,
1245  "No valid catalogue frame found");
1246  }
1247 
1248  /* Fixing the fact that the list object supports no "append" */
1249  /*fors_std_star_list_reverse(stdlist);*/
1250 
1251  cpl_msg_info( cpl_func,
1252  "Found %d catalogue standard stars "
1253  "for band %c (of %d catalogue "
1254  "entries)",
1255  fors_std_star_list_size(stdlist),
1256  band,
1257  n_cat_entries);
1258 
1259  fors_std_star_list *retval = stdlist;
1260  stdlist = NULL;
1261  cleanup;
1262  return retval;
1263 }
1264 
1265 /*#undef cleanup
1266 #define cleanup \
1267 do { \
1268  cpl_array_delete(stetson_columns); stetson_columns = NULL; \
1269  cpl_frame_delete(cat_frame); cat_frame = NULL; \
1270 } while (0)
1271 */
1278 /*cpl_frame *
1279 fors_std_cat_test_create_stetson_format( const fors_std_star_list *stdl,
1280  char band)
1281 {
1282  cpl_array *stetson_columns = NULL;
1283  cpl_frame *cat_frame = NULL;
1284  cpl_errorstate errstat = cpl_errorstate_get();
1285 
1286  stetson_columns = fors_std_cat_stetson_get_column_names();
1287  assure(cpl_errorstate_is_equal(errstat), return cat_frame, NULL);
1288  fors_std_cat_reject_not_required_columns(
1289  stetson_columns,
1290  fors_std_cat_stetson_star_import,
1291  band);
1292  assure(cpl_errorstate_is_equal(errstat), return cat_frame, NULL);
1293  ...
1294 
1295 }*/
1296 
1297 /*----------------------------------------------------------------------------*/
1298 /* old deprecated code, kept for safety */
1299 /*----------------------------------------------------------------------------*/
1300 
1301 const char *const FORS_DATA_STD_MAG[FORS_NUM_FILTER] =
1302 {"U",
1303  "B",
1304  //"G",
1305  "V", /* G uses V */
1306  "V",
1307  "R",
1308  "I",
1309  "Z"};
1310 
1311 const char *const FORS_DATA_STD_DMAG[FORS_NUM_FILTER] =
1312 {"ERR_U",
1313  "ERR_B",
1314  //"ERR_G",
1315  "ERR_V", /* G uses V */
1316  "ERR_V",
1317  "ERR_R",
1318  "ERR_I",
1319  "ERR_Z"};
1320 
1321 const char *const FORS_DATA_STD_COL[FORS_NUM_FILTER] =
1322 {"U_B",
1323  "B_V",
1324  "B_V",
1325  "B_V",
1326  "V_R",
1327  "V_R",
1328  "?Z?"};
1329 
1330 const char *const FORS_DATA_STD_RA = "RA";
1331 const char *const FORS_DATA_STD_DEC = "DEC";
1332 const char *const FORS_DATA_STD_NAME = "OBJECT";
1333 
1334 #undef cleanup
1335 #define cleanup \
1336 do { \
1337  cpl_table_delete(t); \
1338  cpl_free((void *)ERR_B1); \
1339  cpl_free((void *)ERR_C1); \
1340  cpl_free((void *)ERR_C2); \
1341 } while(0)
1342 
1354 fors_std_star_list *
1355 fors_std_cat_load_old(const cpl_frameset *cat_frames,
1356  /*const fors_setting *setting,*/
1357  char optical_band,
1358  double color_term, double dcolor_term)
1359 {
1360  fors_std_star_list *c = NULL;
1361  cpl_table *t = NULL;
1362  const char *filename;
1363  const char *ERR_B1 = NULL;
1364  const char *ERR_C1 = NULL;
1365  const char *ERR_C2 = NULL;
1366 
1367  assure( cat_frames != NULL, return c, NULL );
1368  /*assure( setting != NULL, return c, NULL );*/
1369 
1370  /* For each input table
1371  if it contains the required column, then load
1372  */
1373  c = fors_std_star_list_new();
1374 
1375  const cpl_frame *cat_frame;
1376 
1377  for (cat_frame = cpl_frameset_get_first_const(cat_frames);
1378  cat_frame != NULL;
1379  cat_frame = cpl_frameset_get_next_const(cat_frames)) {
1380 
1381 
1382  filename = cpl_frame_get_filename(cat_frame);
1383  assure( filename != NULL, return c, NULL );
1384 
1385  cpl_table_delete(t);
1386  t = cpl_table_load(filename, 1, 1);
1387  assure( !cpl_error_get_code(), return c, "Could not load FITS catalogue %s",
1388  filename);
1389 
1390  assure( cpl_table_has_column(t, FORS_DATA_STD_RA), return c,
1391  "%s: Missing column %s", filename, FORS_DATA_STD_RA);
1392 
1393  assure( cpl_table_get_column_type(t, FORS_DATA_STD_RA) == CPL_TYPE_DOUBLE,
1394  return c,
1395  "%s: Column %s type is %s, double expected", filename, FORS_DATA_STD_RA,
1396  fors_type_get_string(cpl_table_get_column_type(t, FORS_DATA_STD_RA)));
1397 
1398 
1399  assure( cpl_table_has_column(t, FORS_DATA_STD_DEC), return c,
1400  "%s: Missing column %s", filename, FORS_DATA_STD_DEC);
1401 
1402  assure( cpl_table_get_column_type(t, FORS_DATA_STD_DEC) == CPL_TYPE_DOUBLE,
1403  return c,
1404  "%s: Column %s type is %s, double expected", filename, FORS_DATA_STD_DEC,
1405  fors_type_get_string(cpl_table_get_column_type(t, FORS_DATA_STD_DEC)));
1406 
1407 
1408  assure( cpl_table_has_column(t, FORS_DATA_STD_NAME), return c,
1409  "%s: Missing column %s", filename, FORS_DATA_STD_NAME);
1410 
1411  assure( cpl_table_get_column_type(t, FORS_DATA_STD_NAME) == CPL_TYPE_STRING,
1412  return c,
1413  "%s: Column %s type is %s, string expected", filename,
1414  FORS_DATA_STD_NAME,
1415  fors_type_get_string(cpl_table_get_column_type(t, FORS_DATA_STD_NAME)));
1416 
1417 
1418  /*const char *B1 = FORS_DATA_STD_MAG[setting->filter];
1419  assure( B1 != NULL, return c, NULL );*/
1420  char B1[2] = {'\0', '\0'};
1421  /* *B1 = fors_instrument_filterband_get_by_setting(setting);*/
1422  *B1 = optical_band;
1423 
1424  if ( cpl_table_has_column(t, B1) ) {
1425 
1426  /*
1427  The error propagation depends on which
1428  error bars are available, which are assumed to be
1429  uncorrelated
1430 
1431  Pseudo code:
1432 
1433  given band B1 and color term C1-C2
1434 
1435  If have ERR_B1 and ERR_C1 and ERR_C2
1436  // Stetson like
1437  B1 + c(C1 - B1) = (1-c)B1 + c C1
1438  (1-c)^2errB1^2 + c^2 errC1^2
1439  +errc^2 * (C1-B1)^2
1440 
1441  B1 + c(B1 - C2) = (1+c)B1 - c C2
1442 
1443  (1+c)^2errB1^2 + c^2 errC2^2
1444  +errc^2 (B1-C2)^2
1445 
1446  B1 + c(C1 - C2)
1447  errB1^2 + c^2 errC1^2 + c^2 errC2^2
1448  +errc^2 (C1-C2)^2
1449 
1450  Special case:
1451  G = V + 0.56*(B-V) - 0.12 (Fukugita et al. 1996, AJ 111, p1748)
1452 
1453  magG = G + c*(B-V) = V + (0.56+c)*(B-V) - 0.12
1454  = (1 - 0.56 - c)*V + (0.56+c)*B - 0.12
1455 
1456  errG^2 = (1 - 0.56 - c)^2*errV^2 + (0.56+c)^2*errB^2
1457  +errc^2 (B-V)^2
1458  else
1459  // Landolt like
1460  magU = V + (B-V) + (U-B) + c(U-B)
1461  err^2 = errV^2 + err(B-V)^2 + (1+c)^2 err(U-B)^2
1462  + errc^2 (U-B)^2
1463 
1464  magB = V + (B-V) + c(B-V)
1465  err^2 = errV^2 + (1+c)^2 err(B-V)^2
1466  + errc^2 (B-V)^2
1467 
1468  magG = V + (0.56+c)*(B-V) - 0.12 (Fukugita et al. 1996, AJ 111, p1748)
1469  err^2 = errV^2 + (0.56+c)^2*err(B-V)^2
1470  + errc^2 (B-V)^2
1471 
1472  magV = V + c(B-V)
1473  err^2 = errV^2 + c^2 err(B-V)^2
1474  + errc^2 (B-V)^2
1475 
1476  magR = V - (V-R) + c (V-R) = V + (c-1)(V-R)
1477  err^2 = errV^2 + (c-1)^2 err(V-R)^2
1478  + errc^2 (V-R)^2
1479 
1480  magI = V - (V-I) + c (V-R)
1481  err^2 = errV^2 + err(V-I)^2 + c^2 err(V-R)^2
1482  + errc^2 (V-R)^2
1483  */
1484 
1485  /* Find other bands, C1, C2 */
1486  const char *col;/* = FORS_DATA_STD_COL[setting->filter];*/
1487  switch (*B1)
1488  {
1489  case 'U': col = "U_B"; break;
1490  case 'B': col = "B_V"; break;
1491  case 'G': col = "B_V"; break;
1492  case 'V': col = "B_V"; break;
1493  case 'R': col = "V_R"; break;
1494  case 'I': col = "V_R"; break;
1495  case 'Z': col = "?Z?"; break;
1496  default: col = "";
1497  }
1498  double coeff = -color_term; /* per convention */
1499  double dcoeff = dcolor_term;
1500 
1501  assure( strlen(col) == strlen("X_Y"), return c,
1502  "Color term column must have format 'X_Y', is '%s'",
1503  col );
1504 
1505  assure( col[1] == '_', return c,
1506  "Color term column must have format 'X_Y', is '%s'",
1507  col );
1508 
1509  char C1[2] = {'\0', '\0'};
1510  char C2[2] = {'\0', '\0'};
1511 
1512  *C1 = col[0];
1513  *C2 = col[2];
1514 
1515  ERR_B1 = cpl_sprintf("ERR_%s", B1);
1516  ERR_C1 = cpl_sprintf("ERR_%s", C1);
1517  ERR_C2 = cpl_sprintf("ERR_%s", C2);
1518 
1519  /* Catalog data */
1520  double cat_mag, dcat_mag, color;
1521 
1522  /* Color corrected magnitude */
1523  double mag, dmag;
1524 
1525  int i;
1526  for (i = 0; i < cpl_table_get_nrow(t); i++) {
1527  if (cpl_table_has_column(t, ERR_B1) &&
1528  cpl_table_has_column(t, ERR_C1) &&
1529  cpl_table_has_column(t, ERR_C2)) {
1530 
1531  /* Stetson, four cases */
1532 /* if (setting->filter == FILTER_G) {*/
1533  if (*B1 == 'G') {
1534  if (cpl_table_is_valid(t, "V", i) &&
1535  cpl_table_is_valid(t, "B", i) &&
1536  cpl_table_is_valid(t, "ERR_B", i) &&
1537  cpl_table_is_valid(t, "ERR_V", i)) {
1538  double v = cpl_table_get_float(t, "V", i, NULL);
1539  double b = cpl_table_get_float(t, "B", i, NULL);
1540  double err_b = cpl_table_get_float(t, "ERR_B", i, NULL);
1541  double err_v = cpl_table_get_float(t, "ERR_V", i, NULL);
1542 
1543  color = b-v;
1544  mag = (1-0.56-coeff) * v + (0.56+coeff)*b - 0.12;
1545  cat_mag = (1-0.56 ) * v + (0.56 )*b - 0.12;
1546 
1547  dmag =
1548  sqrt(
1549  (1-0.56-coeff)*(1-0.56-coeff)*err_v*err_v +
1550  (0.56 +coeff)*(0.56 +coeff)*err_b*err_b +
1551  +
1552  dcoeff*dcoeff*color*color);
1553 
1554  dcat_mag = sqrt(
1555  (1-0.56-0)*(1-0.56-0)*err_v*err_v +
1556  (0.56 +0)*(0.56 +0)*err_b*err_b);
1557  }
1558  }
1559  else if (*B1 == *C2) {
1560  if (cpl_table_is_valid(t, B1, i) &&
1561  cpl_table_is_valid(t, C1, i) &&
1562  cpl_table_is_valid(t, ERR_B1, i) &&
1563  cpl_table_is_valid(t, ERR_C1, i)) {
1564  double b1 = cpl_table_get_float(t, B1, i, NULL);
1565  double c1 = cpl_table_get_float(t, C1, i, NULL);
1566  double err_b1 = cpl_table_get_float(t, ERR_B1, i, NULL);
1567  double err_c1 = cpl_table_get_float(t, ERR_C1, i, NULL);
1568 
1569  color = c1-b1;
1570 
1571  cat_mag = b1;
1572  dcat_mag = err_b1;
1573 
1574  mag =
1575  (1-coeff) * b1
1576  + coeff * c1;
1577  dmag =
1578  sqrt(
1579  (1-coeff)*(1-coeff)*err_b1*err_b1 +
1580  coeff*coeff *err_c1*err_c1
1581  +
1582  dcoeff*dcoeff*color*color);
1583  }
1584  else continue;
1585  }
1586  else if (*B1 == *C1) {
1587  if (cpl_table_is_valid(t, B1, i) &&
1588  cpl_table_is_valid(t, C2, i) &&
1589  cpl_table_is_valid(t, ERR_B1, i) &&
1590  cpl_table_is_valid(t, ERR_C2, i)) {
1591  double b1 = cpl_table_get_float(t, B1, i, NULL);
1592  double c2 = cpl_table_get_float(t, C2, i, NULL);
1593  double err_b1 = cpl_table_get_float(t, ERR_B1, i, NULL);
1594  double err_c2 = cpl_table_get_float(t, ERR_C2, i, NULL);
1595 
1596  color = b1-c2;
1597 
1598  cat_mag = b1;
1599  dcat_mag = err_b1;
1600 
1601  mag =
1602  (1+coeff) * b1
1603  - coeff * c2;
1604  dmag =
1605  sqrt(
1606  (1+coeff)*(1+coeff)*err_b1*err_b1 +
1607  coeff*coeff *err_c2*err_c2
1608  +
1609  dcoeff*dcoeff*color*color);
1610 
1611  }
1612  else continue;
1613  }
1614  else {
1615  /* All different */
1616  if (cpl_table_is_valid(t, B1, i) &&
1617  cpl_table_is_valid(t, C1, i) &&
1618  cpl_table_is_valid(t, C2, i) &&
1619  cpl_table_is_valid(t, ERR_B1, i) &&
1620  cpl_table_is_valid(t, ERR_C1, i) &&
1621  cpl_table_is_valid(t, ERR_C2, i)) {
1622  double b1 = cpl_table_get_float(t, B1, i, NULL);
1623  double c1 = cpl_table_get_float(t, C1, i, NULL);
1624  double c2 = cpl_table_get_float(t, C2, i, NULL);
1625  double err_b1 = cpl_table_get_float(t, ERR_B1, i, NULL);
1626  double err_c1 = cpl_table_get_float(t, ERR_C1, i, NULL);
1627  double err_c2 = cpl_table_get_float(t, ERR_C2, i, NULL);
1628 
1629  color = c1-c2;
1630 
1631  cat_mag = b1;
1632  dcat_mag = err_b1;
1633 
1634  mag = b1
1635  + coeff * c1
1636  - coeff * c2;
1637  dmag = sqrt(
1638  err_b1*err_b1 +
1639  coeff*coeff * err_c1*err_c1 +
1640  coeff*coeff * err_c2*err_c2 +
1641  dcoeff*dcoeff * color*color);
1642  }
1643  else continue;
1644  }
1645  } /* If stetson, else */
1646 /* else if (setting->filter == FILTER_G) {*/
1647  else if (*B1 == 'G') {
1648  if (cpl_table_is_valid(t, "V", i) &&
1649  cpl_table_is_valid(t, "B_V", i) &&
1650  cpl_table_is_valid(t, "ERR_V", i) &&
1651  cpl_table_is_valid(t, "ERR_B_V", i)) {
1652  double v = cpl_table_get_float(t, "V", i, NULL);
1653  double bv = cpl_table_get_float(t, "B_V", i, NULL);
1654  double err_v = cpl_table_get_float(t, "ERR_V", i, NULL);
1655  double err_b_v = cpl_table_get_float(t, "ERR_B_V", i, NULL);
1656 
1657  color = bv;
1658 
1659  cat_mag = v + (0.56)*(bv) - 0.12;
1660 
1661  mag = v + (0.56+coeff)*(bv) - 0.12;
1662  dmag =
1663  sqrt(
1664  err_v*err_v +
1665  (0.56+coeff)*(0.56+coeff)*err_b_v*err_b_v +
1666  +
1667  dcoeff*dcoeff*bv*bv);
1668  dcat_mag =
1669  sqrt(
1670  err_v*err_v +
1671  (0.56)*(0.56)*err_b_v*err_b_v);
1672  }
1673  }
1674  else switch (*B1) {
1675  /* Landolt, every band is a special case */
1676  case 'U':
1677  if (cpl_table_is_valid(t, "U", i) &&
1678  cpl_table_is_valid(t, "U_B", i) &&
1679  cpl_table_is_valid(t, "ERR_V", i) &&
1680  cpl_table_is_valid(t, "ERR_B_V", i) &&
1681  cpl_table_is_valid(t, "ERR_U_B", i)) {
1682 
1683  double err_v = cpl_table_get_float(t, "ERR_V", i, NULL);
1684  double err_bv = cpl_table_get_float(t, "ERR_B_V", i, NULL);
1685  double err_ub = cpl_table_get_float(t, "ERR_U_B", i, NULL);
1686  double ub = cpl_table_get_float(t, "U_B", i, NULL);
1687 
1688  color = ub;
1689 
1690  cat_mag = cpl_table_get_float(t, "U", i, NULL);
1691 
1692  mag = cat_mag + coeff * ub;
1693  dmag = sqrt(err_v*err_v + err_bv*err_bv+
1694  (1+coeff)*(1+coeff)*err_ub*err_ub +
1695  dcoeff*dcoeff*ub*ub);
1696 
1697  dcat_mag = sqrt(err_v*err_v + err_bv*err_bv+
1698  err_ub*err_ub);
1699  }
1700  else continue; /* to next for(...) iteration */
1701  break; /* out of switch */
1702  case 'B':
1703  if (cpl_table_is_valid(t, "B", i) &&
1704  cpl_table_is_valid(t, "B_V", i) &&
1705  cpl_table_is_valid(t, "ERR_V", i) &&
1706  cpl_table_is_valid(t, "ERR_B_V", i)) {
1707 
1708  double err_v = cpl_table_get_float(t, "ERR_V", i, NULL);
1709  double err_bv = cpl_table_get_float(t, "ERR_B_V", i, NULL);
1710  double bv = cpl_table_get_float(t, "B_V", i, NULL);
1711 
1712  color = bv;
1713  cat_mag = cpl_table_get_float(t, "B", i, NULL);
1714 
1715  mag = cat_mag +
1716  coeff * bv;
1717  dmag = sqrt(err_v*err_v +
1718  (1+coeff)*(1+coeff)*err_bv*err_bv +
1719  dcoeff*dcoeff*bv*bv);
1720  dcat_mag = sqrt(err_v*err_v +
1721  err_bv*err_bv);
1722  }
1723  else continue;
1724  break;
1725  case 'V':
1726  if (cpl_table_is_valid(t, "V", i) &&
1727  cpl_table_is_valid(t, "B_V", i) &&
1728  cpl_table_is_valid(t, "ERR_V", i) &&
1729  cpl_table_is_valid(t, "ERR_B_V", i)) {
1730 
1731  double err_v = cpl_table_get_float(t, "ERR_V", i, NULL);
1732  double err_bv = cpl_table_get_float(t, "ERR_B_V", i, NULL);
1733  double bv = cpl_table_get_float(t, "B_V", i, NULL);
1734 
1735  color = bv;
1736  cat_mag = cpl_table_get_float(t, "V", i, NULL);
1737  dcat_mag = err_v;
1738 
1739  mag = cat_mag + coeff * bv;
1740  dmag = sqrt(err_v*err_v +
1741  coeff*coeff*err_bv*err_bv +
1742  dcoeff*dcoeff*bv*bv);
1743  }
1744  else continue;
1745  break;
1746  case 'R':
1747  if (cpl_table_is_valid(t, "R", i) &&
1748  cpl_table_is_valid(t, "V_R", i) &&
1749  cpl_table_is_valid(t, "ERR_V", i) &&
1750  cpl_table_is_valid(t, "ERR_V_R", i)) {
1751 
1752  double err_v = cpl_table_get_float(t, "ERR_V", i, NULL);
1753  double err_vr = cpl_table_get_float(t, "ERR_V_R", i, NULL);
1754  double vr = cpl_table_get_float(t, "V_R", i, NULL);
1755 
1756  color = vr;
1757  cat_mag = cpl_table_get_float(t, "R", i, NULL);
1758  mag = cat_mag + coeff * vr;
1759  dmag = sqrt(err_v*err_v +
1760  (1-coeff)*(1-coeff)*err_vr*err_vr +
1761  dcoeff*dcoeff*vr*vr);
1762  dcat_mag = sqrt(err_v*err_v + err_vr*err_vr);
1763  }
1764  else continue;
1765  break;
1766  case 'I':
1767  if (cpl_table_is_valid(t, "I", i) &&
1768  cpl_table_is_valid(t, "V_R", i) &&
1769  cpl_table_is_valid(t, "ERR_V", i) &&
1770  cpl_table_is_valid(t, "ERR_V_I", i) &&
1771  cpl_table_is_valid(t, "ERR_V_R", i)) {
1772 
1773  double err_v = cpl_table_get_float(t, "ERR_V", i, NULL);
1774  double err_vi = cpl_table_get_float(t, "ERR_V_I", i, NULL);
1775  double err_vr = cpl_table_get_float(t, "ERR_V_R", i, NULL);
1776  double vr = cpl_table_get_float(t, "V_R", i, NULL);
1777 
1778  color = vr;
1779  cat_mag = cpl_table_get_float(t, "I", i, NULL);
1780  mag = cat_mag + coeff * vr;
1781  dmag = sqrt(err_v*err_v + err_vi*err_vi+
1782  coeff*coeff*err_vr*err_vr +
1783  dcoeff*dcoeff*vr*vr);
1784  dcat_mag = sqrt(err_v*err_v + err_vi*err_vi);
1785  }
1786  else continue;
1787  break;
1788  default:
1789  assure( false, return c,
1790  "Unknown filter: %s", B1);
1791  break;
1792  }
1793 
1794  double ra = cpl_table_get_double(t, FORS_DATA_STD_RA,
1795  i, NULL);
1796  double dec = cpl_table_get_double(t, FORS_DATA_STD_DEC,
1797  i, NULL);
1798 
1799  const char *std_name = cpl_table_get_string(t, FORS_DATA_STD_NAME,
1800  i);
1801 
1802  fors_std_star_list_insert(
1803  c, fors_std_star_new(ra, dec, mag, dmag,
1804  cat_mag, dcat_mag,
1805  color, -1, -1, std_name));
1806 
1807  } /* for each table row */
1808 
1809 #if 0 /* This is old code which removes doublets but is slow (O(n^2)),
1810  * Doublets will be removed during identification, after
1811  * selecting the (relatively few) stars that fall inside the CCD
1812  */
1813  double nearest_dist;
1814  if (fors_std_star_list_size(c) > 0) {
1815  fors_std_star *nearest = fors_std_star_list_min_val(
1816  c,
1817  (fors_std_star_list_func_eval)
1818  fors_std_star_dist_arcsec,
1819  std);
1820 
1821  nearest_dist = fors_std_star_dist_arcsec(std, nearest);
1822  cpl_msg_debug(cpl_func, "min dist = %f arcseconds",
1823  nearest_dist);
1824  }
1825 
1826  if (fors_std_star_list_size(c) == 0 || nearest_dist > 5) {
1827  fors_std_star_list_insert(c, std);
1828  }
1829  else {
1830  fors_std_star_delete(&std);
1831  }
1832 #endif
1833  } /* if has column B1 */
1834  else {
1835  cpl_msg_info(cpl_func, "Skipping catalog %s, no column %s",
1836  filename, B1);
1837  }
1838  } /* for each frame */
1839 
1840  cpl_msg_info(cpl_func, "Found %d catalogue standards",
1841  fors_std_star_list_size(c));
1842 
1843  /* fors_std_cat_print(c); */
1844 
1845  cleanup;
1846  return c;
1847 }
const char * fors_type_get_string(cpl_type t)
Textual representation of CPL type.
Definition: fors_utils.c:496
#define assure(EXPR)
Definition: list.c:101