IIINSTRUMENT Pipeline Reference Manual  1.5.13
sofi_spc_flat.c
1 /* $Id: sofi_spc_flat.c,v 1.32 2013-03-12 08:04:51 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:51 $
24  * $Revision: 1.32 $
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 <string.h>
37 #include <math.h>
38 #include <cpl.h>
39 
40 #include "irplib_plugin.h"
41 #include "irplib_utils.h"
42 
43 #include "sofi_utils.h"
44 #include "sofi_pfits.h"
45 #include "sofi_dfs.h"
46 
47 /*-----------------------------------------------------------------------------
48  Defines
49  -----------------------------------------------------------------------------*/
50 
51 #define RECIPE_STRING "sofi_spc_flat"
52 
53 #define MEDIAN_XSIZE 200
54 #define MEDIAN_YSIZE 200
55 
56 /*-----------------------------------------------------------------------------
57  Functions prototypes
58  -----------------------------------------------------------------------------*/
59 
60 static cpl_image * sofi_spc_flat_reduce(cpl_frameset *);
61 static cpl_imagelist * sofi_spc_flat_diffs(cpl_frameset *);
62 static cpl_image * sofi_spc_flat_divide_fit(cpl_image *, int, int, int);
63 static cpl_error_code sofi_spc_flat_save(cpl_frameset *, int, const cpl_image *,
64  const cpl_frameset *,
65  const cpl_parameterlist *);
66 static int sofi_spc_flat_compare(const cpl_frame *, const cpl_frame *);
67 
68 cpl_recipe_define(sofi_spc_flat, SOFI_BINARY_VERSION,
69  "Lars Lundin", PACKAGE_BUGREPORT, "2002,2003,2009",
70  "SOFI spectro flat-field creation",
71  RECIPE_STRING " -- SOFI spectro flat-field creation.\n"
72  "The files listed in the Set Of Frames (sof-file) "
73  "must be tagged:\n"
74  "raw-file.fits "SOFI_SPC_FLAT_RAW"\n");
75 
76 /*-----------------------------------------------------------------------------
77  Static variables
78  -----------------------------------------------------------------------------*/
79 
80 static struct {
81  /* Inputs */
82  double low_thresh;
83  double high_thresh;
84  int fit_order;
85  int fit_size;
86  int offset;
87  int llx;
88  int lly;
89  int urx;
90  int ury;
91  /* Outputs */
92  double med_stdev;
93  double med_avg;
94 } sofi_spc_flat_config;
95 
96 
97 /*-----------------------------------------------------------------------------
98  Functions code
99  -----------------------------------------------------------------------------*/
100 
101 /*----------------------------------------------------------------------------*/
109 /*----------------------------------------------------------------------------*/
110 static
111 cpl_error_code sofi_spc_flat_fill_parameterlist(cpl_parameterlist * self)
112 {
113  const char * context = PACKAGE "." RECIPE_STRING;
114  cpl_error_code err;
115 
116  cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
117 
118  /* Fill the parameters list */
119 
120  /* --thresholds */
121  err = irplib_parameterlist_set_string(self, PACKAGE, RECIPE_STRING,
122  "thresholds", "0.01,3.0", NULL,
123  context, "Low and high thresholds");
124  cpl_ensure_code(!err, err);
125 
126  /* --fit_order */
127  err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "fit_order",
128  3, NULL, context, "Order of the fit");
129  cpl_ensure_code(!err, err);
130 
131  /* --fit_size */
132  err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "fit_size",
133  200, NULL, context, "Size of the fit");
134  cpl_ensure_code(!err, err);
135 
136  /* --offset */
137  err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "offset",
138  40, NULL, context, "Offset");
139  cpl_ensure_code(!err, err);
140 
141  /* --zone */
142  err = irplib_parameterlist_set_string(self, PACKAGE, RECIPE_STRING,
143  "zone", "256,256,768,768", NULL,
144  context, "Zone to process [pixel]");
145  cpl_ensure_code(!err, err);
146 
147  return CPL_ERROR_NONE;
148 }
149 
150 
151 /*----------------------------------------------------------------------------*/
159 /*----------------------------------------------------------------------------*/
160 static int sofi_spc_flat(cpl_frameset * framelist,
161  const cpl_parameterlist * parlist)
162 {
163  const int nframes = cpl_frameset_get_size(framelist);
164  const char * sval;
165  cpl_frameset * flatframes = NULL;
166  cpl_size * labels = NULL;
167  cpl_size nlabels;
168  int nflats;
169  int i;
170 
171  /* Initialise */
172  sofi_spc_flat_config.med_stdev = 0.0;
173  sofi_spc_flat_config.med_avg = 0.0;
174 
175  /* Retrieve input parameters */
176  /* --thresholds */
177  sval = irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
178  "thresholds");
179  bug_if(sval == NULL);
180  skip_if (sscanf(sval, "%lg,%lg",
181  &sofi_spc_flat_config.low_thresh,
182  &sofi_spc_flat_config.high_thresh) != 2);
183 
184  /* --fit_order */
185  sofi_spc_flat_config.fit_order
186  = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
187  "fit_order");
188  /* --fit_size */
189  sofi_spc_flat_config.fit_size
190  = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
191  "fit_size");
192  /* --offset */
193  sofi_spc_flat_config.offset
194  = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
195  "offset");
196  /* --zone */
197  sval = irplib_parameterlist_get_string(parlist, PACKAGE, RECIPE_STRING,
198  "zone");
199  bug_if(sval == NULL);
200  skip_if (sscanf(sval, "%d,%d,%d,%d",
201  &sofi_spc_flat_config.llx,
202  &sofi_spc_flat_config.lly,
203  &sofi_spc_flat_config.urx,
204  &sofi_spc_flat_config.ury) != 4);
205 
206 
207  /* Identify the RAW and CALIB frames in the input frameset */
208  skip_if (sofi_dfs_set_groups(framelist));
209 
210  /* Retrieve raw frames */
211  flatframes = sofi_extract_frameset(framelist, SOFI_SPC_FLAT_RAW);
212  error_if (flatframes == NULL, CPL_ERROR_DATA_NOT_FOUND,
213  "Cannot find flat frames in the input frame list");
214 
215  nflats = cpl_frameset_get_size(flatframes);
216 
217  /* The number of frames must be even */
218  error_if (cpl_frameset_get_size(flatframes) % 2, CPL_ERROR_ILLEGAL_INPUT,
219  "The number of flat frames must be even, not %d", nflats);
220 
221  /* Labelise all input frames */
222  labels = cpl_frameset_labelise(flatframes, sofi_spc_flat_compare, &nlabels);
223  error_if (labels == NULL, cpl_error_get_code(),
224  "Cannot labelise input frames");
225 
226  /* Extract settings and reduce each of them */
227  for (i=0; i < nlabels; i++) {
228  /* Reduce data set nb i */
229  cpl_errorstate prestate = cpl_errorstate_get();
230  cpl_frameset * flat_one = cpl_frameset_extract(flatframes, labels, i);
231  cpl_image * spflat;
232 
233  cpl_msg_info(cpl_func, "Reducing set %d/%d", i+1, (int)nlabels);
234 
235  spflat = sofi_spc_flat_reduce(flat_one);
236 
237  if (spflat == NULL) {
238  cpl_msg_warning(cpl_func, "Could not reduce set %d:", i+1);
239  cpl_errorstate_dump(prestate, CPL_FALSE,
240  irplib_errorstate_dump_warning);
241  cpl_errorstate_set(prestate);
242  } else {
243  sofi_spc_flat_save(framelist, i+1, spflat, flat_one, parlist);
244  cpl_image_delete(spflat);
245  }
246  cpl_frameset_delete(flat_one);
247  if (!cpl_errorstate_is_equal(prestate)) break;
248  }
249  skip_if(i != nlabels);
250 
251  error_if (cpl_frameset_get_size(framelist) == nframes,
252  CPL_ERROR_ILLEGAL_INPUT, "No products produced from %d flat "
253  "frames grouped into %d set(s)", nflats, (int)nlabels);
254 
255  end_skip;
256 
257  cpl_frameset_delete(flatframes);
258  cpl_free(labels);
259  return cpl_error_get_code();
260 }
261 
262 /*----------------------------------------------------------------------------*/
269 /*----------------------------------------------------------------------------*/
270 static cpl_image * sofi_spc_flat_reduce(cpl_frameset * flatframes)
271 {
272  cpl_imagelist * diffs;
273  cpl_vector * medians;
274  double med, mean;
275  cpl_image * avg_ima;
276  cpl_image * fitted;
277  int nima, nx, ny;
278  int nframes;
279  int i;
280 
281  /* Test entries */
282  if (flatframes == NULL) return NULL;
283  nframes = cpl_frameset_get_size(flatframes);
284  if (nframes != 4) {
285  cpl_msg_error(cpl_func, "Expect 4 frames in input, not %d", nframes);
286  return NULL;
287  }
288 
289  /* Load input image set */
290  cpl_msg_info(cpl_func, "Compute the difference images");
291  if ((diffs = sofi_spc_flat_diffs(flatframes)) == NULL) {
292  cpl_msg_error(cpl_func, "Cannot create the difference images");
293  return NULL;
294  }
295  nima = cpl_imagelist_get_size(diffs);
296  nx = cpl_image_get_size_x(cpl_imagelist_get(diffs, 0));
297  ny = cpl_image_get_size_y(cpl_imagelist_get(diffs, 0));
298 
299  /* Compute medians on diff images */
300  cpl_msg_info(cpl_func, "Compute statistics on images");
301  cpl_msg_indent_more();
302  medians = cpl_vector_new(nima);
303 
304  /* Compute some stats on input images */
305  for (i=0; i<nima; i++) {
306  med = cpl_image_get_median_window(cpl_imagelist_get(diffs, i),
307  (nx-MEDIAN_XSIZE)/2.0, (ny-MEDIAN_YSIZE)/2.0,
308  (nx+MEDIAN_XSIZE)/2.0, (ny+MEDIAN_YSIZE)/2.0);
309  if (cpl_vector_set(medians, i, med) != CPL_ERROR_NONE) {
310  cpl_msg_error(cpl_func, "Cannot compute the medians");
311  cpl_vector_delete(medians);
312  cpl_imagelist_delete(diffs);
313  cpl_msg_indent_less();
314  return NULL;
315  }
316  }
317 
318  /* Compute stdev and mean of the medians */
319  sofi_spc_flat_config.med_avg = cpl_vector_get_mean(medians);
320  if (nima >= 2)
321  sofi_spc_flat_config.med_stdev=cpl_vector_get_stdev(medians);
322  cpl_vector_delete(medians);
323  cpl_msg_info(cpl_func, "Average of the medians: %g",
324  sofi_spc_flat_config.med_avg);
325  cpl_msg_info(cpl_func, "Standard deviation of the medians: %g",
326  sofi_spc_flat_config.med_stdev);
327  cpl_msg_indent_less();
328 
329  /* Divide by the mean in the vig in the difference image */
330  cpl_msg_info(cpl_func, "Normalise the images");
331  for (i=0; i<nima; i++) {
332  mean = cpl_image_get_mean_window(cpl_imagelist_get(diffs, i),
333  sofi_spc_flat_config.llx, sofi_spc_flat_config.lly,
334  sofi_spc_flat_config.urx, sofi_spc_flat_config.ury);
335  if (cpl_image_divide_scalar(cpl_imagelist_get(diffs, i), mean) !=
336  CPL_ERROR_NONE) {
337  cpl_msg_error(cpl_func, "Cannot normalise the image");
338  cpl_imagelist_delete(diffs);
339  return NULL;
340  }
341  }
342 
343  /* Replace by 0 the pixels whose value is <low and >high */
344  for (i=0; i<nima; i++) {
345  if (cpl_image_threshold(cpl_imagelist_get(diffs, i),
346  sofi_spc_flat_config.low_thresh,
347  sofi_spc_flat_config.high_thresh,
348  0.0, 0.0) != CPL_ERROR_NONE) {
349  cpl_msg_error(cpl_func, "Cannot threshold the image");
350  cpl_imagelist_delete(diffs);
351  return NULL;
352  }
353  }
354 
355  /* Average the image list to one image */
356  cpl_msg_info(cpl_func, "Stack the images");
357  if ((avg_ima = cpl_imagelist_collapse_create(diffs)) == NULL) {
358  cpl_msg_error(cpl_func, "Cannot collapse the image list");
359  cpl_imagelist_delete(diffs);
360  return NULL;
361  }
362  cpl_imagelist_delete(diffs);
363 
364  /* Divide the output image by the fit */
365  cpl_msg_info(cpl_func, "Divide by a fit");
366  if ((fitted = sofi_spc_flat_divide_fit(avg_ima,
367  sofi_spc_flat_config.fit_order,
368  sofi_spc_flat_config.fit_size,
369  sofi_spc_flat_config.offset)) == NULL) {
370  cpl_msg_error(cpl_func, "Cannot collapse the image list");
371  cpl_image_delete(avg_ima);
372  return NULL;
373  }
374  cpl_image_delete(avg_ima);
375 
376  return fitted;
377 }
378 
379 /*----------------------------------------------------------------------------*/
385 /*----------------------------------------------------------------------------*/
386 static cpl_imagelist * sofi_spc_flat_diffs(cpl_frameset * in)
387 {
388  int nima;
389  cpl_imagelist * out;
390  cpl_image * in1;
391  cpl_image * in2;
392  cpl_frame * cur_frame;
393  int i;
394 
395  /* Initialise */
396  nima = cpl_frameset_get_size(in);
397 
398  /* Expect an even number of frames */
399  if ((nima % 2) || (nima != 4)) {
400  cpl_msg_error(cpl_func, "Wrong nb of frames");
401  return NULL;
402  }
403 
404  /* Create the output image list */
405  out = cpl_imagelist_new();
406 
407  /* Loop on all pairs */
408  for (i=0; i<nima/2; i++) {
409  cur_frame = cpl_frameset_get_position(in, 2*i);
410  if ((in1 = cpl_image_load(cpl_frame_get_filename(cur_frame),
411  CPL_TYPE_FLOAT, 0, 0)) == NULL) {
412  cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i);
413  cpl_imagelist_delete(out);
414  return NULL;
415  }
416  cur_frame = cpl_frameset_get_position(in, 2*i+1);
417  if ((in2 = cpl_image_load(cpl_frame_get_filename(cur_frame),
418  CPL_TYPE_FLOAT, 0, 0)) == NULL) {
419  cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i+1);
420  cpl_image_delete(in1);
421  cpl_imagelist_delete(out);
422  return NULL;
423  }
424 
425  /* Expected series: off on on off */
426  if (i==0) {
427  cpl_image_subtract(in2, in1);
428  cpl_image_delete(in1);
429  cpl_imagelist_set(out, in2, i);
430  } else {
431  cpl_image_subtract(in1, in2);
432  cpl_image_delete(in2);
433  cpl_imagelist_set(out, in1, i);
434  }
435  }
436  return out;
437 }
438 
439 /*----------------------------------------------------------------------------*/
445 /*----------------------------------------------------------------------------*/
446 static cpl_image * sofi_spc_flat_divide_fit(
447  cpl_image * in,
448  int order,
449  int xsize,
450  int offset)
451 {
452  const cpl_size degree = order - 1;
453  int nx, ny;
454  int xstart, xend, ystart, yend;
455  cpl_image * collapsed;
456  float * pcollapsed;
457  cpl_image * extracted;
458  float * pextracted;
459  int nb_samples;
460  cpl_matrix * xvec;
461  cpl_vector * yvec;
462  cpl_polynomial * poly_fit;
463  cpl_polynomial * poly_2d;
464  cpl_image * fit_image;
465  cpl_image * out;
466  cpl_size power[2];
467  int i;
468 
469  /* Test entries */
470  if (in == NULL) return NULL;
471 
472  /* Initialise */
473  nx = cpl_image_get_size_x(in);
474  ny = cpl_image_get_size_y(in);
475 
476  /* Determine the zone to extract */
477  xstart = (int)((nx - xsize)/2) + 1;
478  xend = xstart + xsize - 1;
479  if ((xstart<1) || (xend>nx)) {
480  cpl_msg_error(cpl_func, "bad X size specified");
481  return NULL;
482  }
483 
484  /* Extract the central zone and collapse it */
485  if ((collapsed = cpl_image_collapse_window_create(in, xstart, 1, xend, ny,
486  1)) == NULL) {
487  cpl_msg_error(cpl_func, "Cannot collpase a part of the image");
488  return NULL;
489  }
490  pcollapsed = cpl_image_get_data_float(collapsed);
491 
492  /* Find the 'valid' zone in the 1D image */
493  ystart = 1;
494  while ((fabs(pcollapsed[ystart-1]) < 1e-4) && (ystart < nx)) ystart++;
495  ystart += offset;
496 
497  yend = ny;
498  while ((fabs(pcollapsed[yend-1]) <1e-4) && (yend > 1)) yend--;
499  yend -= offset;
500 
501  if (ystart > yend) {
502  cpl_msg_error(cpl_func, "invalid coordinates of the zone to extract");
503  cpl_image_delete(collapsed);
504  return NULL;
505  }
506 
507  /* Extract the 1D signal to fit */
508  if ((extracted = cpl_image_extract(collapsed, 1, ystart, 1, yend))==NULL) {
509  cpl_msg_error(cpl_func, "cannot extract 1D image");
510  cpl_image_delete(collapsed);
511  return NULL;
512  }
513  cpl_image_delete(collapsed);
514  pextracted = cpl_image_get_data_float(extracted);
515 
516  /* Fit the polynomial */
517  nb_samples = cpl_image_get_size_y(extracted);
518  xvec = cpl_matrix_new(1, nb_samples);
519  yvec = cpl_vector_new(nb_samples);
520  for (i=0; i<nb_samples; i++) {
521  cpl_matrix_set(xvec, 0, i, (double)(ystart + i));
522  cpl_vector_set(yvec, i, (double)(pextracted[i] / xsize));
523  }
524  cpl_image_delete(extracted);
525  poly_fit = cpl_polynomial_new(1);
526  if (cpl_polynomial_fit(poly_fit, xvec, NULL, yvec, NULL, CPL_FALSE,
527  NULL, &degree)) {
528  cpl_msg_error(cpl_func, "cannot fit the 1D signal");
529  cpl_polynomial_delete(poly_fit);
530  cpl_matrix_delete(xvec);
531  cpl_vector_delete(yvec);
532  return NULL;
533  }
534  cpl_matrix_delete(xvec);
535  cpl_vector_delete(yvec);
536 
537  /* The polynomial for image generation must be 2d */
538  poly_2d = cpl_polynomial_new(2);
539  power[0] = 0; power[1] = 0;
540  cpl_polynomial_set_coeff(poly_2d, power,
541  cpl_polynomial_get_coeff(poly_fit, power + 1));
542  power[0] = 0; power[1] = 1;
543  cpl_polynomial_set_coeff(poly_2d, power,
544  cpl_polynomial_get_coeff(poly_fit, power + 1));
545  power[0] = 0; power[1] = 2;
546  cpl_polynomial_set_coeff(poly_2d, power,
547  cpl_polynomial_get_coeff(poly_fit, power + 1));
548  cpl_polynomial_delete(poly_fit);
549 
550  /* Create the fit image */
551  fit_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
552  cpl_image_fill_polynomial(fit_image, poly_2d, 1.0, 1.0, 1.0, 1.0);
553  cpl_polynomial_delete(poly_2d);
554 
555  /* Divide the input image by the polynomial image */
556  if ((out = cpl_image_divide_create(in, fit_image)) == NULL) {
557  cpl_msg_error(cpl_func, "cannot divide the images");
558  cpl_image_delete(fit_image);
559  return NULL;
560  }
561  cpl_image_delete(fit_image);
562 
563  return out;
564 }
565 
566 /*----------------------------------------------------------------------------*/
576 /*----------------------------------------------------------------------------*/
577 static cpl_error_code sofi_spc_flat_save(cpl_frameset * set_tot,
578  int set_nb,
579  const cpl_image * flat,
580  const cpl_frameset * set,
581  const cpl_parameterlist * parlist)
582 {
583 #define SOFI_SPC_FLAT_PAF \
584  "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG" \
585  "|ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME" \
586  "|ESO INS GRAT WLEN|ESO INS OPTI1 ID|ESO DET DIT|ESO INS LAMP3 SET)$"
587 
588  cpl_errorstate prestate = cpl_errorstate_get();
589  /* Get the reference frame */
590  const cpl_frame * ref_frame
591  = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
592  /* Get the QC params in qclist */
593  cpl_propertylist * qclist = cpl_propertylist_new();
594  cpl_propertylist * plist = cpl_propertylist_load_regexp
595  (cpl_frame_get_filename(ref_frame), 0, SOFI_SPC_FLAT_PAF
596  "|^ESO INS FILT[12] ID$", 0);
597  const char * sval;
598  char * filename;
599 
600  skip_if(0);
601 
602  sval = sofi_pfits_get_filter(plist);
603  if (sval == NULL) {
604  cpl_msg_warning(cpl_func, "Could not get filter for set %d:", set_nb);
605  cpl_errorstate_dump(prestate, CPL_FALSE,
606  irplib_errorstate_dump_warning);
607  cpl_errorstate_set(prestate);
608  } else {
609  cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", sval);
610  }
611 
612  cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT NCOUNTS",
613  sofi_spc_flat_config.med_avg);
614  cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT STDEV",
615  sofi_spc_flat_config.med_stdev);
616 
617  /* Write the flat image */
618  filename = cpl_sprintf(RECIPE_STRING "_set%02d" CPL_DFS_FITS, set_nb);
619  irplib_dfs_save_image(set_tot, parlist, set, flat, CPL_BPP_IEEE_FLOAT,
620  RECIPE_STRING, SOFI_SPC_FLAT_RES, qclist, NULL,
621  PACKAGE "/" PACKAGE_VERSION, filename);
622  cpl_free(filename);
623  skip_if(0);
624 
625  cpl_propertylist_copy_property_regexp(qclist, plist,
626  SOFI_SPC_FLAT_PAF, 0);
627  cpl_propertylist_empty(plist);
628 
629  /* Save the PAF file */
630  filename = cpl_sprintf(RECIPE_STRING "_set%02d" CPL_DFS_PAF, set_nb);
631  cpl_dfs_save_paf("SOFI", RECIPE_STRING, qclist, filename);
632  cpl_free(filename);
633 
634  skip_if(0);
635 
636  end_skip;
637 
638  cpl_propertylist_delete(qclist);
639  cpl_propertylist_delete(plist);
640 
641  return cpl_error_get_code();
642 }
643 
644 /*----------------------------------------------------------------------------*/
651 /*----------------------------------------------------------------------------*/
652 static int sofi_spc_flat_compare(
653  const cpl_frame * frame1,
654  const cpl_frame * frame2)
655 {
656  int comparison;
657  cpl_propertylist * plist1;
658  cpl_propertylist * plist2;
659  const char * sval1,
660  * sval2;
661 
662  /* Test entries */
663  if (frame1==NULL || frame2==NULL) return CPL_ERROR_UNSPECIFIED;
664 
665  /* Get property lists */
666  if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
667  0)) == NULL) {
668  cpl_msg_error(cpl_func, "getting header from reference frame");
669  return CPL_ERROR_UNSPECIFIED;
670  }
671  if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
672  0)) == NULL) {
673  cpl_msg_error(cpl_func, "getting header from reference frame");
674  cpl_propertylist_delete(plist1);
675  return CPL_ERROR_UNSPECIFIED;
676  }
677 
678  /* Test status */
679  if (cpl_error_get_code()) {
680  cpl_propertylist_delete(plist1);
681  cpl_propertylist_delete(plist2);
682  return CPL_ERROR_UNSPECIFIED;
683  }
684 
685  comparison = 1;
686 
687  /* Compare the slit used */
688  sval1 = sofi_pfits_get_opti1_id(plist1);
689  sval2 = sofi_pfits_get_opti1_id(plist2);
690  if (cpl_error_get_code()) {
691  cpl_msg_error(cpl_func, "cannot get the slit used");
692  cpl_propertylist_delete(plist1);
693  cpl_propertylist_delete(plist2);
694  return CPL_ERROR_UNSPECIFIED;
695  }
696  if (strcmp(sval1, sval2)) comparison = 0;
697 
698  /* Compare the filter */
699  sval1 = sofi_pfits_get_filter(plist1);
700  sval2 = sofi_pfits_get_filter(plist2);
701  if (cpl_error_get_code()) {
702  cpl_msg_error(cpl_func, "cannot get the filter");
703  cpl_propertylist_delete(plist1);
704  cpl_propertylist_delete(plist2);
705  return CPL_ERROR_UNSPECIFIED;
706  }
707  if (strcmp(sval1, sval2)) comparison = 0;
708 
709  cpl_propertylist_delete(plist1);
710  cpl_propertylist_delete(plist2);
711  return comparison;
712 }
713 
714 
sofi_pfits_get_opti1_id
const char * sofi_pfits_get_opti1_id(const cpl_propertylist *plist)
find out the OPTI1.ID key
Definition: sofi_pfits.c:424
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_pfits_get_filter
const char * sofi_pfits_get_filter(const cpl_propertylist *plist)
find out which wave band is active in short wavelength
Definition: sofi_pfits.c:243