VISIR Pipeline Reference Manual  4.1.0
visir_util_spc_std_cat.c
1 /* $Id: visir_util_spc_std_cat.c,v 1.56 2013-02-25 16:54:32 jtaylor Exp $
2  *
3  * This file is part of the VISIR Pipeline
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-02-25 16:54:32 $
24  * $Revision: 1.56 $
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 "visir_recipe.h"
37 #include "visir_spectro.h"
38 #include "visir_spc_distortion.h"
39 #include "visir_spc_photom.h"
40 #include "visir_cpl_compat.h"
41 #include <stdio.h>
42 #include <string.h>
43 
44 
45 
46 
47 /*-----------------------------------------------------------------------------
48  Recipe defines
49  -----------------------------------------------------------------------------*/
50 
51 #define RECIPE_STRING "visir_util_spc_std_cat"
52 
53 /*-----------------------------------------------------------------------------
54  Private Functions prototypes
55  -----------------------------------------------------------------------------*/
56 
57 static cpl_error_code visir_util_spc_std_cat_save(cpl_frameset *,
58  const cpl_parameterlist *,
59  const cpl_table *);
60 
61 VISIR_RECIPE_DEFINE
62 (visir_util_spc_std_cat, 0,
63  "Generate a FITS catalog of spectroscopic standard stars",
64  "This recipe shall be used to generate a FITS catalog of spectroscopic "
65  "standard stars for the VISIR pipeline.\n"
66  "The sof file shall consist of lines with the name of an ASCII-file named "
67  " <Star_Name>.txt, e.g. HD133165.txt and the tag " VISIR_SPC_CAT_ASCII ".\n"
68  "All input ASCII-files must comprise the same number of lines.\nThe first "
69  "line of the ASCII-file must have 6 fields separated by white-space.\nThe "
70  "first three fields are the RA (hh mm ss) which will be stored in degrees "
71  "in a table column labeled 'RA' - all three are non-negative and hh and mm "
72  "are integer.\n"
73  "The 3 last fields are the DEC (dd mm ss) which will be stored in degrees in "
74  "a table column labeled 'DEC' - all three are non-negative, dd and mm are "
75  "integer, and dd has either a '+' or a '-' prepended (including -00).\n"
76  "The remaining lines must all consist of two fields separated by white-"
77  "space.\n"
78  "The first field is the wavelength (in microns) and the second the (positive) "
79  "model flux in W/m2/m. The wavelengths must be identical in all the input "
80  "files.\n");
81 
82 /*----------------------------------------------------------------------------*/
86 /*----------------------------------------------------------------------------*/
87 
88 /*-----------------------------------------------------------------------------
89  Functions code
90  -----------------------------------------------------------------------------*/
91 
92 /*----------------------------------------------------------------------------*/
103 /*----------------------------------------------------------------------------*/
104 static int visir_util_spc_std_cat(cpl_frameset * framelist,
105  const cpl_parameterlist * parlist)
106 {
107  int nfiles;
108  cpl_bivector * spectrum = NULL; /* Flux model for one star */
109  cpl_table * catalog = NULL; /* Flux model for all stars */
110  cpl_array ** wlen_arr;
111  cpl_array ** flux_arr;
112  char ** star_arr;
113  FILE * in = NULL;
114  char line[1024];
115  const double * ras; /* RAs */
116  const double * decs; /* DECs */
117  const double max_radius = VISIR_STAR_MAX_RADIUS;
118  double mindist;
119  int iloc1, iloc2;
120  int nvals;
121  int i;
122 
123 
124  if (cpl_error_get_code()) return cpl_error_get_code();
125 
126  /* Identify the RAW frames in the input frameset */
127  skip_if (visir_dfs_set_groups(framelist));
128 
129  /* Get the number of files */
130  nfiles = cpl_frameset_get_size(framelist);
131 
132  skip_if (nfiles < 1);
133 
134  catalog = cpl_table_new(nfiles); /* One row per file */
135 
136  bug_if (catalog == NULL);
137 
138  nvals = 2300; /* 1st guess at length of spectra */
139 
140  bug_if (cpl_table_new_column(catalog, "STARS", CPL_TYPE_STRING));
141  bug_if (cpl_table_new_column(catalog, "RA", CPL_TYPE_DOUBLE));
142  bug_if (cpl_table_new_column(catalog, "DEC", CPL_TYPE_DOUBLE));
143  bug_if (cpl_table_new_column_array(catalog, "WAVELENGTHS", CPL_TYPE_DOUBLE,
144  nvals));
145  bug_if (cpl_table_new_column_array(catalog, "MODEL_FLUX", CPL_TYPE_DOUBLE,
146  nvals));
147 
148  star_arr = cpl_table_get_data_string(catalog, "STARS");
149  wlen_arr = cpl_table_get_data_array(catalog, "WAVELENGTHS");
150  flux_arr = cpl_table_get_data_array(catalog, "MODEL_FLUX");
151 
152  bug_if(star_arr == NULL);
153  bug_if(wlen_arr == NULL);
154  bug_if(flux_arr == NULL);
155 
156  /* Loop on all input frames */
157  for (i=0; i < cpl_frameset_get_size(framelist); i++) {
158  int ra1, ra2, dec1, dec2;
159  double ra3, dec3;
160  double ra, dec; /* Converted star position [degree] */
161  const char * fstart;
162  const char * fstop;
163  size_t ilen;
164  char isign;
165  double * wlen;
166  double * flux;
167  const cpl_frame * frame = cpl_frameset_get_position_const(framelist, i);
168  /* Get file name */
169  const char * filename = cpl_frame_get_filename(frame);
170 
171  skip_if (filename == NULL);
172 
173  /* Open the file */
174  if ((in = fopen(filename, "r")) == NULL) {
175  cpl_msg_error(cpl_func, "Could not open file number %d (%s)", i+1,
176  filename);
177  skip_if (1);
178  }
179 
180  /* Read header */
181  /* Get RA and DEC */
182  if (fgets(line, 1024, in) == NULL) {
183  cpl_msg_error(cpl_func, "fgets() returned NULL when reading the "
184  "first line in file number %d (%s)",
185  i+1, filename);
186  skip_if (1);
187  }
188 
189  if (sscanf(line, "%d %d %lg %c%d %d %lg ", &ra1, &ra2, &ra3, &isign,
190  &dec1, &dec2, &dec3) != 7) {
191  cpl_msg_error(cpl_func, "Invalid first line in file number %d (%s)",
192  i+1, filename);
193  skip_if (1);
194  }
195 
196  /* Get the flux model */
197  /* On 1st iteration a resizing may be needed */
198  spectrum = cpl_bivector_new(nvals);
199  skip_if (visir_bivector_load(spectrum, in));
200 
201  fclose(in);
202  in = NULL;
203 
204  if (i == 0) {
205  nvals = cpl_bivector_get_size(spectrum); /* Get actual length */
206  cpl_table_set_column_depth(catalog, "WAVELENGTHS", nvals);
207  cpl_table_set_column_depth(catalog, "MODEL_FLUX", nvals);
208  } else if (nvals != cpl_bivector_get_size(spectrum)) {
209  /* The number of vals must be the same in all files */
210  cpl_msg_error(cpl_func, "Length of spectrum in file number %d (%s) "
211  "is different from the previous (with length %d)",
212  i+1, filename, nvals);
213  skip_if (1);
214  }
215 
216  skip_if (visir_star_convert(line, ra1, ra2, ra3, isign, dec1, dec2,
217  dec3, cpl_bivector_get_y_data(spectrum),
218  nvals, &ra, &dec));
219 
220  /* Get the star name, i.e. the basename of the file */
221  fstart = strrchr(filename, '/');
222  fstart = fstart == NULL ? filename : 1 + fstart;
223  fstop = strrchr(fstart, '.');
224  /* ilen is the length of the star name without the null-terminator */
225  ilen = fstop == NULL ? strlen(fstart) : (size_t) (fstop - fstart);
226 
227  if ((int)ilen <= 0) {
228  cpl_msg_error(cpl_func, "File number %d (%s) has no basename for "
229  "the FITS table", i+1, filename);
230  skip_if(1);
231  }
232 
233  /* Create, copy and NULL-terminate starname */
234  star_arr[i] = cpl_malloc(1+ilen);
235  memcpy(star_arr[i], fstart, ilen);
236  star_arr[i][ilen] = '\0';
237 
238  /* Pointers to the wavelengths and fluxes of one star */
239  wlen = cpl_vector_unwrap(cpl_bivector_get_x(spectrum));
240  flux = cpl_vector_unwrap(cpl_bivector_get_y(spectrum));
241 
242  cpl_bivector_unwrap_vectors(spectrum);
243  spectrum = NULL;
244 
245  wlen_arr[i] = cpl_array_wrap_double(wlen, nvals);
246  flux_arr[i] = cpl_array_wrap_double(flux, nvals);
247 
248  bug_if (cpl_table_set_double(catalog, "RA", i, ra));
249  bug_if (cpl_table_set_double(catalog, "DEC", i, dec));
250 
251  }
252 
253  skip_if (i != nfiles);
254 
255  ras = cpl_table_get_data_double(catalog, "RA");
256  decs = cpl_table_get_data_double(catalog, "DEC");
257 
258  mindist = visir_star_dist_min(ras, decs, nfiles, &iloc1, &iloc2);
259 
260  if (mindist < max_radius) {
261  cpl_frame * floc1 = visir_frameset_get_frame(framelist, iloc1);
262  cpl_frame * floc2 = visir_frameset_get_frame(framelist, iloc2);
263  cpl_msg_warning(cpl_func, "The pair of closest stars is %s (%d) and %s "
264  "(%d) with the distance: %g",
265  cpl_frame_get_filename(floc1), iloc1,
266  cpl_frame_get_filename(floc2), iloc2, mindist);
267 
268  }
269  else {
270  cpl_frame * floc1 = visir_frameset_get_frame(framelist, iloc1);
271  cpl_frame * floc2 = visir_frameset_get_frame(framelist, iloc2);
272  cpl_msg_info(cpl_func, "The pair of closest stars is %s (%d) and %s "
273  "(%d) with the distance: %g",
274  cpl_frame_get_filename(floc1), iloc1,
275  cpl_frame_get_filename(floc2), iloc2, mindist);
276  }
277 
278  /* Save the table */
279  cpl_msg_info(cpl_func, "Saving the table with %d rows each with a spectrum "
280  "length of %d", nfiles, nvals);
281  skip_if (visir_util_spc_std_cat_save(framelist, parlist, catalog));
282 
283  end_skip;
284 
285  cpl_bivector_delete(spectrum);
286  cpl_table_delete(catalog);
287  if (in) fclose(in);
288 
289  return cpl_error_get_code();
290 }
291 
292 /*----------------------------------------------------------------------------*/
303 /*----------------------------------------------------------------------------*/
304 static
305 cpl_error_code visir_util_spc_std_cat_save(cpl_frameset * set,
306  const cpl_parameterlist * parlist,
307  const cpl_table * catalog)
308 {
309  cpl_propertylist * applist = cpl_propertylist_new();
310 
311 
312  bug_if (catalog == NULL);
313  bug_if (parlist == NULL);
314  bug_if (set == NULL);
315 
316  bug_if(cpl_propertylist_append_string(applist, "INSTRUME", "VISIR"));
317 
318  skip_if (irplib_dfs_save_table(set, parlist, set, catalog, NULL,
319  RECIPE_STRING, VISIR_SPEC_STD_CAT_PROCATG,
320  applist, NULL, visir_pipe_id,
321  RECIPE_STRING CPL_DFS_FITS));
322 
323  end_skip;
324 
325  cpl_propertylist_delete(applist);
326 
327  return cpl_error_get_code();
328 }
cpl_error_code irplib_dfs_save_table(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *usedframes, const cpl_table *table, const cpl_propertylist *tablelist, const char *recipe, const char *procat, const cpl_propertylist *applist, const char *remregexp, const char *pipe_id, const char *filename)
Save a table as a DFS-compliant pipeline product.
Definition: irplib_utils.c:335
int visir_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: visir_dfs.c:72