IIINSTRUMENT Pipeline Reference Manual  1.5.13
sofi_img_illum.c
1 /* $Id: sofi_img_illum.c,v 1.24 2013-03-12 08:04:52 llundin Exp $
2  *
3  * This file is part of the SOFI 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: llundin $
23  * $Date: 2013-03-12 08:04:52 $
24  * $Revision: 1.24 $
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 <math.h>
37 #include <cpl.h>
38 
39 #include "irplib_plugin.h"
40 #include "irplib_utils.h"
41 #include "irplib_calib.h"
42 #include "irplib_strehl.h"
43 
44 #include "sofi_utils.h"
45 #include "sofi_pfits.h"
46 #include "sofi_dfs.h"
47 
48 /*-----------------------------------------------------------------------------
49  Defines
50  -----------------------------------------------------------------------------*/
51 
52 #define RECIPE_STRING "sofi_img_illum"
53 
54 /*-----------------------------------------------------------------------------
55  Functions prototypes
56  -----------------------------------------------------------------------------*/
57 
58 static cpl_image * sofi_img_illum_reduce(cpl_frameset *, const char *,
59  const char *, const char *,
60  cpl_table **);
61 static cpl_bivector * sofi_img_illum_find_pos(const cpl_imagelist *,
62  const cpl_bivector *);
63 static cpl_vector * sofi_img_illum_phot(cpl_imagelist *, cpl_bivector *,int *);
64 static
65 cpl_error_code sofi_img_illum_save(cpl_frameset *, const cpl_image *,
66  const cpl_table *, const cpl_parameterlist *);
67 
68 cpl_recipe_define(sofi_img_illum, SOFI_BINARY_VERSION,
69  "Lars Lundin", PACKAGE_BUGREPORT, "2002,2003,2009",
70  "SOFI imaging illumination frame recipe",
71  RECIPE_STRING " -- SOFI imaging illumination frame recipe.\n"
72  "The files listed in the Set Of Frames (sof-file) "
73  "must be tagged:\n"
74  "raw-file.fits "SOFI_IMG_ILLUM_RAW" or\n"
75  "flat-file.fits "SOFI_CALIB_FLAT" or\n"
76  "dark-file.fits "SOFI_CALIB_DARK"\n");
77 
78 /*-----------------------------------------------------------------------------
79  Static variables
80  -----------------------------------------------------------------------------*/
81 
82 static struct {
83  /* Inputs */
84  int s_hx;
85  int s_hy;
86  double star_r;
87  double bg_r1;
88  double bg_r2;
89  int pos_x;
90  int pos_y;
91 
92  /* Outputs */
93  cpl_size poly_deg;
94  double illum1;
95  double illumx;
96  double illumy;
97  double illumxy;
98  double illumxx;
99  double illumyy;
100 } sofi_img_illum_config;
101 
102 
103 /*-----------------------------------------------------------------------------
104  Functions code
105  -----------------------------------------------------------------------------*/
106 
107 /*----------------------------------------------------------------------------*/
115 /*----------------------------------------------------------------------------*/
116 static
117 cpl_error_code sofi_img_illum_fill_parameterlist(cpl_parameterlist * self)
118 {
119  const char * context = PACKAGE "." RECIPE_STRING;
120  cpl_error_code err;
121 
122  cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
123 
124  /* Fill the parameters list */
125 
126  /* --star_r */
127  err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING, "star_r",
128  10.0, NULL, context,
129  "The star radius [pixel]");
130  cpl_ensure_code(!err, err);
131 
132  /* --bg_r1 */
133  err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING, "bg_r1",
134  12.0, NULL, context, "The internal "
135  "background radius [pixel]");
136  cpl_ensure_code(!err, err);
137 
138  /* --bg_r2 */
139  err = irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING, "bg_r2",
140  30.0, NULL, context, "The external "
141  "background radius [pixel]");
142  cpl_ensure_code(!err, err);
143 
144  /* --s_hx */
145  err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "s_hx",
146  50, NULL, context, "Half-size of the "
147  "search box in X [pixel]");
148  cpl_ensure_code(!err, err);
149 
150  /* --s_hy */
151  err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "s_hy",
152  50, NULL, context, "Half-size of the "
153  "search box in Y [pixel]");
154  cpl_ensure_code(!err, err);
155 
156  /* --pos_x */
157  err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "pos_x",
158  -1, NULL, context, "The star "
159  "X-position [pixel]");
160  cpl_ensure_code(!err, err);
161 
162  /* --pos_y */
163  err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "pos_y",
164  -1, NULL, context, "The star "
165  "Y-position [pixel]");
166  cpl_ensure_code(!err, err);
167 
168  return CPL_ERROR_NONE;
169 }
170 
171 
172 /*----------------------------------------------------------------------------*/
180 /*----------------------------------------------------------------------------*/
181 static int sofi_img_illum(cpl_frameset * framelist,
182  const cpl_parameterlist * parlist)
183 {
184  cpl_frameset * rawframes = NULL;
185  cpl_image * ima = NULL;
186  cpl_table * flux = NULL;
187  const char * flat;
188  const char * dark;
189 
190 
191  /* Retrieve input parameters */
192  sofi_img_illum_config.s_hx
193  = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
194  "s_hx");
195  sofi_img_illum_config.s_hy
196  = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
197  "s_hy");
198  sofi_img_illum_config.star_r
199  = irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING,
200  "star_r");
201  sofi_img_illum_config.bg_r1
202  = irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING,
203  "bg_r1");
204  sofi_img_illum_config.bg_r2
205  = irplib_parameterlist_get_double(parlist, PACKAGE, RECIPE_STRING,
206  "bg_r2");
207  sofi_img_illum_config.pos_x
208  = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
209  "pos_x");
210  sofi_img_illum_config.pos_y
211  = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
212  "pos_y");
213 
214  bug_if(0);
215 
216  /* Identify the RAW and CALIB frames in the input frameset */
217  skip_if (sofi_dfs_set_groups(framelist));
218 
219  /* Retrieve calibration data */
220  flat = sofi_extract_filename(framelist, SOFI_CALIB_FLAT);
221  dark = sofi_extract_filename(framelist, SOFI_CALIB_DARK);
222 
223  /* Retrieve raw frames */
224  rawframes = sofi_extract_frameset(framelist, SOFI_IMG_ILLUM_RAW);
225  error_if (rawframes == NULL, CPL_ERROR_DATA_NOT_FOUND,
226  "Cannot find any raw frame in the input");
227 
228  /* Apply the data reduction */
229  cpl_msg_info(cpl_func, "Apply the reduction");
230  cpl_msg_indent_more();
231  ima = sofi_img_illum_reduce(rawframes, flat, dark, NULL, &flux);
232  cpl_msg_indent_less();
233 
234  skip_if (ima == NULL);
235 
236  /* Save the products */
237  cpl_msg_info(cpl_func, "Saving the products");
238  skip_if (sofi_img_illum_save(framelist, ima, flux, parlist));
239 
240  end_skip;
241 
242  cpl_image_delete(ima);
243  cpl_table_delete(flux);
244  cpl_frameset_delete(rawframes);
245 
246  return cpl_error_get_code();
247 }
248 
249 /*----------------------------------------------------------------------------*/
260 /*----------------------------------------------------------------------------*/
261 static cpl_image * sofi_img_illum_reduce(
262  cpl_frameset * raw,
263  const char * flat,
264  const char * dark,
265  const char * bpm,
266  cpl_table ** fl)
267 {
268  cpl_bivector * offsets;
269  cpl_imagelist * in;
270  cpl_bivector * positions;
271  cpl_matrix * purged_pos;
272  double * positions_x,
273  * positions_y;
274  cpl_vector * flux;
275  cpl_vector * purged_flux;
276  cpl_polynomial * poly;
277  cpl_image * poly_ima;
278  int nval, nx, ny;
279  cpl_size power[2];
280  int i, j;
281 
282  /* Initialise */
283  *fl = NULL;
284 
285  /* Get the offsets from the raw frames */
286  cpl_msg_info(cpl_func, "Get the offsets from the files headers");
287  cpl_msg_indent_more();
288  if ((offsets = sofi_get_offsets(raw)) == NULL) {
289  cpl_msg_error(cpl_func, "Cannot get the offsets");
290  cpl_msg_indent_less();
291  return NULL;
292  }
293  cpl_msg_indent_less();
294 
295  /* Load the input data */
296  cpl_msg_info(cpl_func, "Load the input data");
297  cpl_msg_indent_more();
298  if ((in = cpl_imagelist_load_frameset(raw, CPL_TYPE_FLOAT, 1, 0)) == NULL) {
299  cpl_msg_error(cpl_func, "Cannot load input data");
300  cpl_bivector_delete(offsets);
301  cpl_msg_indent_less();
302  return NULL;
303  }
304  cpl_msg_indent_less();
305 
306  /* Apply the calibrations */
307  if (flat || dark || bpm) {
308  cpl_msg_info(cpl_func, "Apply the calibrations");
309  cpl_msg_indent_more();
310  if (irplib_flat_dark_bpm_calib(in, flat, dark, bpm) == -1) {
311  cpl_msg_error(cpl_func, "Cannot calibrate the data");
312  cpl_imagelist_delete(in);
313  cpl_bivector_delete(offsets);
314  cpl_msg_indent_less();
315  return NULL;
316  }
317  cpl_msg_indent_less();
318  }
319 
320  /* Find the positions */
321  cpl_msg_info(cpl_func, "Find the positions");
322  cpl_msg_indent_more();
323  if ((positions=sofi_img_illum_find_pos(in, offsets)) == NULL) {
324  cpl_msg_error(cpl_func, "Cannot find the positions");
325  cpl_imagelist_delete(in);
326  cpl_bivector_delete(offsets);
327  cpl_msg_indent_less();
328  return NULL;
329  }
330  cpl_bivector_delete(offsets);
331  cpl_msg_indent_less();
332 
333  /* Compute the photometry */
334  cpl_msg_info(cpl_func, "Compute the photometry");
335  cpl_msg_indent_more();
336  if ((flux=sofi_img_illum_phot(in, positions, &nval)) == NULL) {
337  cpl_msg_error(cpl_func, "Cannot find the positions");
338  cpl_imagelist_delete(in);
339  cpl_bivector_delete(positions);
340  cpl_msg_indent_less();
341  return NULL;
342  }
343  nx = cpl_image_get_size_x(cpl_imagelist_get(in, 0));
344  ny = cpl_image_get_size_y(cpl_imagelist_get(in, 0));
345  cpl_imagelist_delete(in);
346  cpl_msg_indent_less();
347  if (nval < 1) {
348  cpl_msg_error(cpl_func, "No flux computed");
349  cpl_bivector_delete(positions);
350  cpl_vector_delete(flux);
351  return NULL;
352  }
353 
354  /* Purge positions */
355  purged_pos = cpl_matrix_new(2, nval);
356  positions_x = cpl_bivector_get_x_data(positions);
357  positions_y = cpl_bivector_get_y_data(positions);
358  purged_flux = cpl_vector_new(nval);
359  j = 0;
360  for (i=0; i<cpl_vector_get_size(flux); i++) {
361  if (fabs(cpl_vector_get(flux, i)) > 0) {
362  cpl_matrix_set(purged_pos, 0, j, positions_x[i]);
363  cpl_matrix_set(purged_pos, 1, j, positions_y[i]);
364  cpl_vector_set(purged_flux, j, cpl_vector_get(flux, i));
365  j++;
366  }
367  }
368 
369  /* Create the flux table */
370  *fl = cpl_table_new(cpl_vector_get_size(flux));
371  cpl_table_new_column(*fl, "POSX", CPL_TYPE_DOUBLE);
372  cpl_table_new_column(*fl, "POSY", CPL_TYPE_DOUBLE);
373  cpl_table_new_column(*fl, "FLUX", CPL_TYPE_DOUBLE);
374  for (i=0; i<cpl_vector_get_size(flux); i++) {
375  cpl_table_set_double(*fl, "POSX", i, positions_x[i]);
376  cpl_table_set_double(*fl, "POSY", i, positions_y[i]);
377  cpl_table_set_double(*fl, "FLUX", i, cpl_vector_get(flux, i));
378  }
379  cpl_bivector_delete(positions);
380  cpl_vector_delete(flux);
381 
382  /* Degree of the 2D-polynomial */
383  if (nval >= 6) {
384  sofi_img_illum_config.poly_deg = 2;
385  } else if (nval >= 3) {
386  sofi_img_illum_config.poly_deg = 1;
387  } else {
388  sofi_img_illum_config.poly_deg = 0;
389  }
390  cpl_msg_info(cpl_func, "Fitting a %d-degree 2D-polynomial to %d points",
391  (int)sofi_img_illum_config.poly_deg, nval);
392  poly = cpl_polynomial_new(2);
393  if (cpl_polynomial_fit(poly, purged_pos, NULL, purged_flux, NULL,
394  CPL_FALSE, NULL, &(sofi_img_illum_config.poly_deg))) {
395  cpl_matrix_delete(purged_pos);
396  cpl_vector_delete(purged_flux);
397  cpl_error_set_where(cpl_func);
398  cpl_polynomial_delete(poly);
399  cpl_table_delete(*fl);
400  *fl = NULL;
401  return NULL;
402  }
403  cpl_matrix_delete(purged_pos);
404  cpl_vector_delete(purged_flux);
405 
406  /* Fill the coeffs */
407  power[0] = 0; power[1] = 0;
408  sofi_img_illum_config.illum1 = cpl_polynomial_get_coeff(poly, power);
409  if (sofi_img_illum_config.poly_deg >= 1) {
410  power[0] = 1; power[1] = 0;
411  sofi_img_illum_config.illumx = cpl_polynomial_get_coeff(poly, power);
412  power[0] = 0; power[1] = 1;
413  sofi_img_illum_config.illumy = cpl_polynomial_get_coeff(poly, power);
414  }
415  if (sofi_img_illum_config.poly_deg >= 2) {
416  power[0] = 1; power[1] = 1;
417  sofi_img_illum_config.illumxy = cpl_polynomial_get_coeff(poly, power);
418  power[0] = 2; power[1] = 0;
419  sofi_img_illum_config.illumxx = cpl_polynomial_get_coeff(poly, power);
420  power[0] = 0; power[1] = 2;
421  sofi_img_illum_config.illumyy = cpl_polynomial_get_coeff(poly, power);
422  }
423  cpl_msg_info(cpl_func, "P(X,Y)=a0+a1*X+a2*Y+a3*X*Y+a4*X^2+a5*Y^2");
424  cpl_msg_info(cpl_func, "a0 = %g", sofi_img_illum_config.illum1);
425  cpl_msg_info(cpl_func, "a1 = %g", sofi_img_illum_config.illumx);
426  cpl_msg_info(cpl_func, "a2 = %g", sofi_img_illum_config.illumy);
427  cpl_msg_info(cpl_func, "a3 = %g", sofi_img_illum_config.illumxy);
428  cpl_msg_info(cpl_func, "a4 = %g", sofi_img_illum_config.illumxx);
429  cpl_msg_info(cpl_func, "a5 = %g", sofi_img_illum_config.illumyy);
430 
431  /* Create the polynomial image */
432  poly_ima = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
433  cpl_image_fill_polynomial(poly_ima, poly, 1.0, 1.0, 1.0, 1.0);
434  cpl_polynomial_delete(poly);
435 
436  /* Normalise the image */
437  cpl_image_normalise(poly_ima, CPL_NORM_MEAN);
438 
439  return poly_ima;
440 }
441 
442 /*----------------------------------------------------------------------------*/
451 /*----------------------------------------------------------------------------*/
452 static cpl_vector * sofi_img_illum_phot(
453  cpl_imagelist * ilist,
454  cpl_bivector * positions,
455  int * nvalid)
456 {
457  cpl_vector * flux;
458  cpl_image * cur_ima;
459  double * positions_x;
460  double * positions_y;
461  int ni;
462  int nok;
463  double bg, fl;
464  int i;
465 
466  /* Test entries */
467  if (ilist == NULL || positions == NULL || nvalid == NULL) return NULL;
468  ni = cpl_imagelist_get_size(ilist);
469  positions_x = cpl_bivector_get_x_data(positions);
470  positions_y = cpl_bivector_get_y_data(positions);
471  nok = 0;
472 
473  /* Create the flux vector */
474  flux = cpl_vector_new(ni);
475 
476  /* Loop on the frames */
477  for (i=0; i<ni; i++) {
478  cur_ima = cpl_imagelist_get(ilist, i);
479  bg = irplib_strehl_ring_background(cur_ima, (int)positions_x[i],
480  (int)positions_y[i], sofi_img_illum_config.bg_r1,
481  sofi_img_illum_config.bg_r2, IRPLIB_BG_METHOD_MEDIAN);
482  fl = irplib_strehl_disk_flux(cur_ima, (int)positions_x[i],
483  (int)positions_y[i], sofi_img_illum_config.star_r, bg);
484  cpl_vector_set(flux, i, fl);
485  if (fabs(fl)>1e-3) nok++;
486  cpl_msg_info(cpl_func, "Flux for image %d: %g", i+1, fl);
487  }
488  *nvalid = nok;
489  return flux;
490 }
491 
492 /*----------------------------------------------------------------------------*/
500 /*----------------------------------------------------------------------------*/
501 static cpl_bivector * sofi_img_illum_find_pos(const cpl_imagelist * ilist,
502  const cpl_bivector * offsets)
503 {
504  const int ni = cpl_imagelist_get_size(ilist);
505  const int nx = cpl_image_get_size_x(cpl_imagelist_get_const(ilist, 0));
506  const int ny = cpl_image_get_size_y(cpl_imagelist_get_const(ilist, 0));
507  cpl_bivector * positions;
508  double * positions_x;
509  double * positions_y;
510  const double * offsets_x = cpl_bivector_get_x_data_const(offsets);
511  const double * offsets_y = cpl_bivector_get_y_data_const(offsets);
512  cpl_image * img_window = NULL;
513  cpl_image * img_filter = NULL;
514  cpl_mask * kernel = NULL;
515  int i;
516 
517 
518  cpl_ensure(ilist != NULL, CPL_ERROR_NULL_INPUT, NULL);
519  cpl_ensure(offsets != NULL, CPL_ERROR_NULL_INPUT, NULL);
520  cpl_ensure(cpl_bivector_get_size(offsets) == ni,
521  CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
522 
523  /* Create the positions bivector */
524  positions = cpl_bivector_new(ni);
525  positions_x = cpl_bivector_get_x_data(positions);
526  positions_y = cpl_bivector_get_y_data(positions);
527 
528  /* Create the kernel */
529  kernel = cpl_mask_new(3, 3);
530  cpl_mask_not(kernel);
531 
532  /* Loop on all the images */
533  for (i=0; i < ni; i++) {
534  const cpl_image * image = cpl_imagelist_get_const(ilist, i);
535 
536  /* Define zone */
537  const int pos_x = sofi_img_illum_config.pos_x > 0
538  ? sofi_img_illum_config.pos_x : nx/2;
539  const int pos_y = sofi_img_illum_config.pos_y > 0
540  ? sofi_img_illum_config.pos_y : ny/2;
541 
542  const int llx = pos_x + offsets_x[i] - sofi_img_illum_config.s_hx;
543  const int urx = pos_x + offsets_x[i] + sofi_img_illum_config.s_hx;
544  const int lly = pos_y + offsets_y[i] - sofi_img_illum_config.s_hy;
545  const int ury = pos_y + offsets_y[i] + sofi_img_illum_config.s_hy;
546 
547  cpl_size posx, posy;
548 
549  /* Test zone */
550  if (llx > urx || lly > ury || llx < 1 || urx > nx || lly < 1 ||
551  ury > ny) {
552  (void)cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
553  "Bad specified zone: llx=%d, urx=%d, "
554  "lly=%d, ury=%d", llx, urx, lly, ury);
555  break;
556  }
557 
558 
559  /* Extract */
560  cpl_image_delete(img_window);
561  cpl_image_delete(img_filter);
562  img_window = cpl_image_extract(image, llx, lly, urx, ury);
563  img_filter = cpl_image_new(1 + urx - llx, 1 + ury - lly,
564  cpl_image_get_type(img_window));
565 
566  cpl_image_filter_mask(img_filter, img_window, kernel,
567  CPL_FILTER_MEDIAN, CPL_BORDER_FILTER);
568 
569  /* Find the max */
570  cpl_image_get_maxpos(img_filter, &posx, &posy);
571  positions_x[i] = llx + posx;
572  positions_y[i] = lly + posy;
573  cpl_msg_info(cpl_func, "Star found at pos %g, %g in image %d",
574  positions_x[i], positions_y[i], i+1);
575 
576  }
577  cpl_image_delete(img_window);
578  cpl_image_delete(img_filter);
579  cpl_mask_delete(kernel);
580  if (i != ni) {
581  cpl_bivector_delete(positions);
582  positions = NULL;
583  }
584 
585  return positions;
586 }
587 
588 /*----------------------------------------------------------------------------*/
598 /*----------------------------------------------------------------------------*/
599 static cpl_error_code sofi_img_illum_save(cpl_frameset * set,
600  const cpl_image * ima,
601  const cpl_table * flux,
602  const cpl_parameterlist * parlist)
603 {
604  const cpl_frame * ref_frame;
605  cpl_propertylist * plist;
606  cpl_propertylist * paflist;
607  cpl_propertylist * qclist;
608 
609  /* Get the QC params in qclist */
610  qclist = cpl_propertylist_new();
611  cpl_propertylist_append_double(qclist, "ESO QC ILLUM1",
612  sofi_img_illum_config.illum1);
613  cpl_propertylist_append_double(qclist, "ESO QC ILLUMX",
614  sofi_img_illum_config.illumx);
615  cpl_propertylist_append_double(qclist, "ESO QC ILLUMY",
616  sofi_img_illum_config.illumy);
617  cpl_propertylist_append_double(qclist, "ESO QC ILLUMXY",
618  sofi_img_illum_config.illumxy);
619  cpl_propertylist_append_double(qclist, "ESO QC ILLUMXX",
620  sofi_img_illum_config.illumxx);
621  cpl_propertylist_append_double(qclist, "ESO QC ILLUMYY",
622  sofi_img_illum_config.illumyy);
623 
624  /* Write the image */
625  irplib_dfs_save_image(set,
626  parlist,
627  set,
628  ima,
629  CPL_BPP_IEEE_FLOAT,
630  "sofi_img_illum",
631  SOFI_IMG_ILLUM_RES,
632  qclist,
633  NULL,
634  PACKAGE "/" PACKAGE_VERSION,
635  "sofi_img_illum.fits");
636 
637  /* Write the table */
638  if (flux != NULL) {
639  irplib_dfs_save_table(set,
640  parlist,
641  set,
642  flux,
643  NULL,
644  "sofi_img_illum",
645  SOFI_IMG_ILLUM_TAB,
646  qclist,
647  NULL,
648  PACKAGE "/" PACKAGE_VERSION,
649  "sofi_img_illum_flux.fits");
650  }
651 
652  /* Get the reference frame */
653  ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
654 
655  /* Get FITS header from reference file */
656  if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
657  0)) == NULL) {
658  cpl_msg_error(cpl_func, "getting header from reference frame");
659  cpl_propertylist_delete(qclist);
660  return cpl_error_set_where(cpl_func);
661  }
662 
663  /* Get the keywords for the paf file */
664  paflist = cpl_propertylist_new();
665  cpl_propertylist_copy_property_regexp(paflist, plist,
666  "^(ARCFILE|MJD-OBS|ESO TPL ID|DATE-OBS|ESO DET DIT|ESO DET NDIT|"
667  "ESO DET NCORRS|ESO DET MODE NAME)$", 0);
668  cpl_propertylist_delete(plist);
669 
670  /* Copy the QC in paflist */
671  cpl_propertylist_copy_property_regexp(paflist, qclist, ".", 0);
672  cpl_propertylist_delete(qclist);
673 
674  /* Save the PAF file */
675  cpl_dfs_save_paf("SOFI",
676  "sofi_img_illum",
677  paflist,
678  "sofi_img_illum.paf");
679  cpl_propertylist_delete(paflist);
680  return cpl_error_get_code();
681 }
sofi_extract_frameset
cpl_frameset * sofi_extract_frameset(const cpl_frameset *in, const char *tag)
Extract the frames with the given tag from a frameset.
Definition: sofi_utils.c:298
sofi_dfs_set_groups
int sofi_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: sofi_dfs.c:60
sofi_get_offsets
cpl_bivector * sofi_get_offsets(cpl_frameset *fset)
Get the offsets from a set of frames.
Definition: sofi_utils.c:181
sofi_extract_filename
const char * sofi_extract_filename(const cpl_frameset *in, const char *tag)
Extract the filename ffor the first frame of the given tag.
Definition: sofi_utils.c:342