isaac_spc_flat.c

00001 /* $Id: isaac_spc_flat.c,v 1.40 2013-03-12 08:06:48 llundin Exp $
00002  *
00003  * This file is part of the ISAAC Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2013-03-12 08:06:48 $
00024  * $Revision: 1.40 $
00025  * $Name: not supported by cvs2svn $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <string.h>
00037 #include <math.h>
00038 #include <cpl.h>
00039 
00040 #include "irplib_utils.h"
00041 
00042 #include "isaac_utils.h"
00043 #include "isaac_pfits.h"
00044 #include "isaac_dfs.h"
00045 
00046 /*-----------------------------------------------------------------------------
00047                                 Defines
00048  -----------------------------------------------------------------------------*/
00049 
00050 #define MEDIAN_XSIZE        200
00051 #define MEDIAN_YSIZE        200
00052 
00053 /*-----------------------------------------------------------------------------
00054                             Functions prototypes
00055  -----------------------------------------------------------------------------*/
00056 
00057 static int isaac_spc_flat_create(cpl_plugin *);
00058 static int isaac_spc_flat_exec(cpl_plugin *);
00059 static int isaac_spc_flat_destroy(cpl_plugin *);
00060 static int isaac_spc_flat(cpl_parameterlist *, cpl_frameset *);
00061 static cpl_image * isaac_spc_flat_reduce(cpl_frameset *);
00062 static cpl_imagelist * isaac_spc_flat_diffs(cpl_frameset *); 
00063 static cpl_image * isaac_spc_flat_divide_fit(cpl_image *, int, int, int);
00064 static int isaac_spc_flat_save(cpl_image *, int, cpl_frameset *, 
00065         cpl_parameterlist *, cpl_frameset *);
00066 static int isaac_spc_flat_compare(const cpl_frame *, const cpl_frame *); 
00067 
00068 /*-----------------------------------------------------------------------------
00069                             Static variables
00070  -----------------------------------------------------------------------------*/
00071 
00072 static struct {
00073     /* Inputs */
00074     double      low_thresh;
00075     double      high_thresh;
00076     int         fit_order;
00077     int         fit_size;
00078     int         offset;
00079     int         llx;
00080     int         lly;
00081     int         urx;
00082     int         ury;
00083     /* Outputs */
00084     double      med_stdev;
00085     double      med_avg;
00086 } isaac_spc_flat_config;
00087 
00088 static char isaac_spc_flat_description[] = 
00089 "isaac_spc_flat -- ISAAC spectro flat-field creation.\n"
00090 "The files listed in the Set Of Frames (sof-file) must be tagged:\n"
00091 "raw-file.fits "ISAAC_SPC_FLAT_RAW"\n";
00092 
00093 /*-----------------------------------------------------------------------------
00094                                 Functions code
00095  -----------------------------------------------------------------------------*/
00096 
00097 /*----------------------------------------------------------------------------*/
00105 /*----------------------------------------------------------------------------*/
00106 int cpl_plugin_get_info(cpl_pluginlist * list)
00107 {
00108     cpl_recipe  *   recipe = cpl_calloc(1, sizeof(*recipe));
00109     cpl_plugin  *   plugin = &recipe->interface;
00110 
00111     cpl_plugin_init(plugin,
00112                     CPL_PLUGIN_API,
00113                     ISAAC_BINARY_VERSION,
00114                     CPL_PLUGIN_TYPE_RECIPE,
00115                     "isaac_spc_flat",
00116                     "Spectro flat recipe",
00117                     isaac_spc_flat_description,
00118                     "Lars Lundin",
00119                     PACKAGE_BUGREPORT,
00120                     isaac_get_license(),
00121                     isaac_spc_flat_create,
00122                     isaac_spc_flat_exec,
00123                     isaac_spc_flat_destroy);
00124 
00125     cpl_pluginlist_append(list, plugin);
00126     
00127     return 0;
00128 }
00129 
00130 /*----------------------------------------------------------------------------*/
00139 /*----------------------------------------------------------------------------*/
00140 static int isaac_spc_flat_create(cpl_plugin * plugin)
00141 {
00142     cpl_recipe      * recipe;
00143     cpl_parameter   * p;
00144 
00145     /* Get the recipe out of the plugin */
00146     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00147         recipe = (cpl_recipe *)plugin;
00148     else return -1;
00149 
00150     /* Create the parameters list in the cpl_recipe object */
00151     recipe->parameters = cpl_parameterlist_new();
00152 
00153     /* Fill the parameters list */
00154     /* --thresholds */
00155     p = cpl_parameter_new_value("isaac.isaac_spc_flat.thresholds", 
00156             CPL_TYPE_STRING, "Low and high thresholds", "isaac.isaac_spc_flat",
00157             "0.01,3.0");
00158     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "thresholds");
00159     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00160     cpl_parameterlist_append(recipe->parameters, p);
00161     /* --fit_order */
00162     p = cpl_parameter_new_value("isaac.isaac_spc_flat.fit_order", CPL_TYPE_INT,
00163             "Order for the fit", "isaac.isaac_spc_flat", 3);
00164     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fit_order");
00165     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00166     cpl_parameterlist_append(recipe->parameters, p);
00167     /* --fit_size */
00168     p = cpl_parameter_new_value("isaac.isaac_spc_flat.fit_size", CPL_TYPE_INT,
00169             "Size for the fit", "isaac.isaac_spc_flat", 200);
00170     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fit_size");
00171     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00172     cpl_parameterlist_append(recipe->parameters, p);
00173     /* --offset */
00174     p = cpl_parameter_new_value("isaac.isaac_spc_flat.offset", CPL_TYPE_INT,
00175             "Offset", "isaac.isaac_spc_flat", 40);
00176     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "offset");
00177     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00178     cpl_parameterlist_append(recipe->parameters, p);
00179     /* --zone */
00180     p = cpl_parameter_new_value("isaac.isaac_spc_flat.zone", 
00181             CPL_TYPE_STRING, "Zone to consider", "isaac.isaac_spc_flat",
00182             "256,256,768,768");
00183     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "zone");
00184     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00185     cpl_parameterlist_append(recipe->parameters, p);
00186     /* Return */
00187     return 0;
00188 }
00189 
00190 /*----------------------------------------------------------------------------*/
00196 /*----------------------------------------------------------------------------*/
00197 static int isaac_spc_flat_exec(cpl_plugin * plugin)
00198 {
00199     cpl_recipe  *   recipe;
00200 
00201     /* Get the recipe out of the plugin */
00202     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00203         recipe = (cpl_recipe *)plugin;
00204     else return -1;
00205 
00206     return isaac_spc_flat(recipe->parameters, recipe->frames);
00207 }
00208 
00209 /*----------------------------------------------------------------------------*/
00215 /*----------------------------------------------------------------------------*/
00216 static int isaac_spc_flat_destroy(cpl_plugin * plugin)
00217 {
00218     cpl_recipe  *   recipe;
00219 
00220     /* Get the recipe out of the plugin */
00221     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00222         recipe = (cpl_recipe *)plugin;
00223     else return -1;
00224 
00225     cpl_parameterlist_delete(recipe->parameters);
00226     return 0;
00227 }
00228 
00229 /*----------------------------------------------------------------------------*/
00236 /*----------------------------------------------------------------------------*/
00237 static int isaac_spc_flat(
00238         cpl_parameterlist   *   parlist, 
00239         cpl_frameset        *   framelist)
00240 {
00241     const char      *   sval;
00242     cpl_parameter   *   par;
00243     cpl_size        *   labels;
00244     cpl_size            nlabels;
00245     cpl_frameset    *   flatframes;
00246     cpl_frameset    *   flat_one;
00247     cpl_image       *   spflat;
00248     int                 i;
00249     cpl_boolean         did_reduce = CPL_FALSE;
00250     
00251     /* Initialise */
00252     par = NULL;
00253     isaac_spc_flat_config.med_stdev = 0.0;
00254     isaac_spc_flat_config.med_avg = 0.0;
00255 
00256     /* Retrieve input parameters */
00257     /* --thresholds */
00258     par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.thresholds"); 
00259     sval = cpl_parameter_get_string(par);
00260     if (sscanf(sval, "%lg,%lg",
00261                     &isaac_spc_flat_config.low_thresh,
00262                     &isaac_spc_flat_config.high_thresh)!=2) {
00263         return -1;
00264     }
00265     /* --fit_order */
00266     par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.fit_order");
00267     isaac_spc_flat_config.fit_order = cpl_parameter_get_int(par);
00268     /* --fit_size */
00269     par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.fit_size");
00270     isaac_spc_flat_config.fit_size = cpl_parameter_get_int(par);
00271     /* --offset */
00272     par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.offset");
00273     isaac_spc_flat_config.offset = cpl_parameter_get_int(par);
00274     /* --zone */
00275     par = cpl_parameterlist_find(parlist, "isaac.isaac_spc_flat.zone"); 
00276     sval = cpl_parameter_get_string(par);
00277     if (sscanf(sval, "%d,%d,%d,%d",
00278                     &isaac_spc_flat_config.llx,
00279                     &isaac_spc_flat_config.lly,
00280                     &isaac_spc_flat_config.urx,
00281                     &isaac_spc_flat_config.ury)!=4) {
00282         return -1;
00283     }
00284 
00285     /* Identify the RAW and CALIB frames in the input frameset */
00286     if (isaac_dfs_set_groups(framelist)) {
00287         cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
00288         return -1;
00289     }
00290 
00291     /* Retrieve raw frames */
00292     if ((flatframes = isaac_extract_frameset(framelist,
00293                     ISAAC_SPC_FLAT_RAW)) == NULL) {
00294         cpl_msg_error(cpl_func, "Cannot find flat frames in the input list");
00295         return -1;
00296     }
00297 
00298     /* The number of frames must be even */
00299     if (cpl_frameset_get_size(flatframes) % 2) {
00300         cpl_msg_error(cpl_func, "An even nb of frames expected in input");
00301         cpl_frameset_delete(flatframes);
00302         return -1;
00303     }
00304     
00305     /* Labelise all input frames */
00306     if ((labels = cpl_frameset_labelise(flatframes, isaac_spc_flat_compare, 
00307                 &nlabels)) == NULL) {
00308         cpl_msg_error(cpl_func, "Cannot labelise input frames");
00309         cpl_frameset_delete(flatframes);
00310         return -1; 
00311     }
00312    
00313     /* Extract settings and reduce each of them */
00314     for (i=0; i<nlabels; i++) {
00315         cpl_errorstate prestate = cpl_errorstate_get();
00316 
00317         /* Reduce data set nb i */
00318         cpl_msg_info(cpl_func, "Reduce data set no %d out of %d", i+1,
00319                      (int)nlabels);
00320         cpl_msg_indent_more();
00321         flat_one = cpl_frameset_extract(flatframes, labels, i);
00322         spflat = isaac_spc_flat_reduce(flat_one);
00323         cpl_msg_indent_less();
00324 
00325         /* Save the products */
00326         cpl_msg_info(cpl_func, "Save the products");
00327         cpl_msg_indent_more();
00328         if (!cpl_errorstate_is_equal(prestate)) {
00329             cpl_image_delete(spflat);
00330             irplib_error_recover(prestate, "Could not reduce set %d/%d", 1+i,
00331                                  (int)nlabels);
00332         } else if (spflat == NULL) {
00333             cpl_msg_warning(cpl_func, "Cannot reduce set nb %d", i+1);
00334         } else {
00335             isaac_spc_flat_save(spflat, i+1, flat_one, parlist, framelist);
00336             cpl_image_delete(spflat);
00337             did_reduce = CPL_TRUE;
00338         }
00339         cpl_msg_indent_less();
00340         cpl_frameset_delete(flat_one);
00341     }
00342     
00343     /* Free and return */
00344     cpl_frameset_delete(flatframes);
00345     cpl_free(labels); 
00346 
00347     cpl_ensure_code(did_reduce, CPL_ERROR_ILLEGAL_INPUT);
00348 
00349     return cpl_error_set_where(cpl_func); /* Propagate error, if any */
00350 }
00351 
00352 /*----------------------------------------------------------------------------*/
00359 /*----------------------------------------------------------------------------*/
00360 static cpl_image * isaac_spc_flat_reduce(cpl_frameset * flatframes)
00361 {
00362     cpl_imagelist       *   diffs;
00363     cpl_vector          *   medians;
00364     double                  med, mean;
00365     cpl_image           *   avg_ima;
00366     cpl_image           *   fitted;
00367     int                     nima, nx, ny;
00368     int                     i;
00369 
00370     /* Test entries */
00371     if (flatframes == NULL) return NULL;
00372 
00373     /* Load input image set */
00374     cpl_msg_info(cpl_func, "Compute the difference images");
00375     if ((diffs = isaac_spc_flat_diffs(flatframes)) == NULL) {
00376         cpl_msg_error(cpl_func, "Cannot create the difference images");
00377         return NULL;
00378     }
00379     nima = cpl_imagelist_get_size(diffs);
00380     nx = cpl_image_get_size_x(cpl_imagelist_get(diffs, 0));
00381     ny = cpl_image_get_size_y(cpl_imagelist_get(diffs, 0));
00382 
00383     /* Compute medians on diff images */
00384     cpl_msg_info(cpl_func, "Compute statistics on images");
00385     cpl_msg_indent_more();
00386     medians = cpl_vector_new(nima);
00387 
00388     /* Compute some stats on input images */
00389     for (i=0; i<nima; i++) {
00390         med = cpl_image_get_median_window(cpl_imagelist_get(diffs, i),
00391                 (nx-MEDIAN_XSIZE)/2.0, (ny-MEDIAN_YSIZE)/2.0,
00392                 (nx+MEDIAN_XSIZE)/2.0, (ny+MEDIAN_YSIZE)/2.0);
00393         if (cpl_vector_set(medians, i, med) != CPL_ERROR_NONE) {
00394             cpl_msg_error(cpl_func, "Cannot compute the medians");
00395             cpl_vector_delete(medians);
00396             cpl_imagelist_delete(diffs);
00397             cpl_msg_indent_less();
00398             return NULL;
00399         }
00400     }
00401 
00402     /* Compute stdev and mean of the medians */
00403     isaac_spc_flat_config.med_avg   = cpl_vector_get_mean(medians);
00404     if (nima >= 2) 
00405         isaac_spc_flat_config.med_stdev=cpl_vector_get_stdev(medians);
00406     cpl_vector_delete(medians);
00407     cpl_msg_info(cpl_func, "Average of the medians: %g", 
00408             isaac_spc_flat_config.med_avg);
00409     cpl_msg_info(cpl_func, "Standard deviation of the medians: %g", 
00410             isaac_spc_flat_config.med_stdev);
00411     cpl_msg_indent_less();
00412 
00413     /* Divide by the mean in the vig in the difference image */
00414     cpl_msg_info(cpl_func, "Normalise the images");
00415     for (i=0; i<nima; i++) {
00416 
00417         /* Support for window readout */
00418         if ((nx != 1024) || (ny != 1024)) {
00419             mean = cpl_image_get_mean(cpl_imagelist_get(diffs, i));
00420         } else {
00421             mean = cpl_image_get_mean_window(cpl_imagelist_get(diffs, i),
00422                     isaac_spc_flat_config.llx, isaac_spc_flat_config.lly,
00423                     isaac_spc_flat_config.urx, isaac_spc_flat_config.ury);
00424         }
00425         if (cpl_image_divide_scalar(cpl_imagelist_get(diffs, i), mean) != 
00426                 CPL_ERROR_NONE) {
00427             cpl_msg_error(cpl_func, "Cannot normalise the image");
00428             cpl_imagelist_delete(diffs);
00429             return NULL;
00430         }
00431     }
00432 
00433     /* Replace by 0 the pixels whose value is <low and >high */
00434     for (i=0; i<nima; i++) {
00435         if (cpl_image_threshold(cpl_imagelist_get(diffs, i), 
00436                 isaac_spc_flat_config.low_thresh,
00437                 isaac_spc_flat_config.high_thresh,
00438                 0.0, 0.0) != CPL_ERROR_NONE) {
00439             cpl_msg_error(cpl_func, "Cannot threshold the image");
00440             cpl_imagelist_delete(diffs);
00441             return NULL;
00442         }
00443     }
00444 
00445     /* Average the image list to one image */
00446     cpl_msg_info(cpl_func, "Stack the images");
00447     if ((avg_ima = cpl_imagelist_collapse_create(diffs)) == NULL) {
00448         cpl_msg_error(cpl_func, "Cannot collapse the image list");
00449         cpl_imagelist_delete(diffs);
00450         return NULL;
00451     }
00452     cpl_imagelist_delete(diffs);
00453 
00454     /* Divide the output image by the fit    */
00455     cpl_msg_info(cpl_func, "Divide by a fit");
00456     if ((fitted = isaac_spc_flat_divide_fit(avg_ima,
00457                     isaac_spc_flat_config.fit_order,
00458                     isaac_spc_flat_config.fit_size,
00459                     isaac_spc_flat_config.offset)) == NULL) {
00460         cpl_msg_error(cpl_func, "Cannot collapse the image list");
00461         cpl_image_delete(avg_ima);
00462         return NULL;
00463     }
00464     cpl_image_delete(avg_ima);
00465     
00466     return fitted;
00467 }
00468 
00469 /*----------------------------------------------------------------------------*/
00475 /*----------------------------------------------------------------------------*/
00476 static cpl_imagelist * isaac_spc_flat_diffs(cpl_frameset * in) 
00477 {
00478     int                     nima;
00479     cpl_imagelist       *   out;
00480     cpl_image           *   in1;
00481     cpl_image           *   in2;
00482     cpl_frame           *   cur_frame;
00483     int                     i;
00484  
00485     /* Initialise */
00486     nima = cpl_frameset_get_size(in);
00487 
00488     /* Expect an even number of frames */
00489     if (nima % 2) {
00490         cpl_msg_error(cpl_func, "Odd nb of frames");
00491         return NULL;
00492     }
00493 
00494     /* Create the output image list */
00495     out = cpl_imagelist_new();
00496 
00497     /* Loop on all pairs */
00498     for (i=0; i<nima/2; i++) {
00499         cur_frame = cpl_frameset_get_frame(in, 2*i);
00500         if ((in1 = cpl_image_load(cpl_frame_get_filename(cur_frame), 
00501                         CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00502             cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i);
00503             cpl_imagelist_delete(out);
00504             return NULL;
00505         }
00506         cur_frame = cpl_frameset_get_frame(in, 2*i+1);
00507         if ((in2 = cpl_image_load(cpl_frame_get_filename(cur_frame), 
00508                         CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00509             cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i+1);
00510             cpl_image_delete(in1);
00511             cpl_imagelist_delete(out);
00512             return NULL;
00513         }
00514         cpl_image_subtract(in1, in2);
00515         cpl_image_delete(in2);
00516         cpl_imagelist_set(out, in1, i);
00517     }
00518     return out;
00519 }
00520 
00521 /*----------------------------------------------------------------------------*/
00527 /*----------------------------------------------------------------------------*/
00528 static cpl_image * isaac_spc_flat_divide_fit(
00529         cpl_image   *   in,
00530         int             order,
00531         int             xsize,
00532         int             offset) 
00533 {
00534     int                     nx, ny;
00535     int                     xstart, xend, ystart, yend;
00536     cpl_image           *   collapsed;
00537     float               *   pcollapsed;
00538     cpl_image           *   extracted;
00539     float               *   pextracted;
00540     int                     nb_samples;
00541     cpl_matrix          *   xvec;
00542     cpl_vector          *   yvec;
00543     cpl_polynomial      *   poly_fit;
00544     cpl_polynomial      *   poly_2d;
00545     cpl_image           *   fit_image;
00546     cpl_image           *   out;
00547     cpl_size                power[2];
00548     int                     i;
00549     const cpl_size          maxdeg1d = order - 1;
00550     const cpl_boolean       sampsym = CPL_TRUE; /* xvec is symmetric */
00551     
00552     /* Test entries */
00553     if (in == NULL) return NULL;
00554 
00555     /* Initialise */
00556     nx = cpl_image_get_size_x(in);
00557     ny = cpl_image_get_size_y(in);
00558     
00559     /* Determine the zone to extract */
00560     xstart = (int)((nx - xsize)/2) + 1;
00561     xend = xstart + xsize - 1;
00562     if ((xstart<1) || (xend>nx)) {
00563         cpl_msg_error(cpl_func, "bad X size specified");
00564         return NULL;
00565     }
00566 
00567     /* Extract the central zone and collapse it */
00568     if ((collapsed = cpl_image_collapse_window_create(in, xstart, 1, xend, ny, 
00569                     1)) == NULL) {
00570         cpl_msg_error(cpl_func, "Cannot collpase a part of the image");
00571         return NULL;
00572     }
00573     pcollapsed = cpl_image_get_data_float(collapsed);
00574 
00575     /* Find the 'valid' zone in the 1D image */
00576     ystart = 1;
00577     while ((fabs(pcollapsed[ystart-1]) < 1e-4) && (ystart < nx)) ystart++;
00578     ystart += offset;
00579 
00580     yend = ny;
00581     while ((fabs(pcollapsed[yend-1]) <1e-4) && (yend > 1)) yend--;
00582     yend -= offset;
00583 
00584     if (ystart > yend) {
00585         cpl_msg_error(cpl_func, "invalid coordinates of the zone to extract");
00586         cpl_image_delete(collapsed);
00587         return NULL;
00588     }
00589 
00590     /* Extract the 1D signal to fit */
00591     if ((extracted = cpl_image_extract(collapsed, 1, ystart, 1, yend))==NULL) {
00592         cpl_msg_error(cpl_func, "cannot extract 1D image");
00593         cpl_image_delete(collapsed);
00594         return NULL;
00595     }
00596     cpl_image_delete(collapsed);
00597     pextracted = cpl_image_get_data_float(extracted);
00598 
00599     /* Fit the polynomial */
00600     nb_samples = cpl_image_get_size_y(extracted);
00601     xvec = cpl_matrix_new(1, nb_samples);
00602     yvec = cpl_vector_new(nb_samples);
00603     for (i=0; i<nb_samples; i++) {
00604         cpl_matrix_set(xvec, 0, i, (double)(ystart + i));
00605         cpl_vector_set(yvec,    i, (double)(pextracted[i] / xsize));
00606     }
00607     cpl_image_delete(extracted);
00608     poly_fit = cpl_polynomial_new(1);
00609     if (cpl_polynomial_fit(poly_fit, xvec, &sampsym, yvec, NULL, CPL_FALSE,
00610                            NULL, &maxdeg1d)) {
00611         cpl_msg_error(cpl_func, "cannot fit the 1D signal");
00612         cpl_matrix_delete(xvec);
00613         cpl_vector_delete(yvec);
00614         cpl_polynomial_delete(poly_fit);
00615         return NULL;
00616     }
00617     cpl_matrix_delete(xvec);
00618     cpl_vector_delete(yvec);
00619     
00620     /* The polynomial for image generation must be 2d */
00621     poly_2d = cpl_polynomial_new(2);
00622     power[0] = 0; power[1] = 0;
00623     cpl_polynomial_set_coeff(poly_2d, power, 
00624             cpl_polynomial_get_coeff(poly_fit, power + 1));
00625     power[0] = 0; power[1] = 1;
00626     cpl_polynomial_set_coeff(poly_2d, power, 
00627             cpl_polynomial_get_coeff(poly_fit, power + 1));
00628     power[0] = 0; power[1] = 2;
00629     cpl_polynomial_set_coeff(poly_2d, power, 
00630             cpl_polynomial_get_coeff(poly_fit, power + 1));
00631     cpl_polynomial_delete(poly_fit);
00632     
00633     /* Create the fit image */
00634     fit_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00635     cpl_image_fill_polynomial(fit_image, poly_2d, 1.0, 1.0, 1.0, 1.0);
00636     cpl_polynomial_delete(poly_2d);
00637     
00638     /* Divide the input image by the polynomial image */
00639     if ((out = cpl_image_divide_create(in, fit_image)) == NULL) {
00640         cpl_msg_error(cpl_func, "cannot divide the images");
00641         cpl_image_delete(fit_image);
00642         return NULL;
00643     }
00644     cpl_image_delete(fit_image);
00645 
00646     return out;
00647 }
00648 
00649 /*----------------------------------------------------------------------------*/
00659 /*----------------------------------------------------------------------------*/
00660 static int isaac_spc_flat_save(
00661         cpl_image           *   flat,
00662         int                     set_nb,
00663         cpl_frameset        *   set,
00664         cpl_parameterlist   *   parlist,
00665         cpl_frameset        *   set_tot)
00666 {
00667     cpl_propertylist    *   plist;
00668     cpl_propertylist    *   qclist;
00669     cpl_propertylist    *   paflist;
00670     const cpl_frame           *   ref_frame;
00671     const char          *   sval;
00672     int                     arm;
00673     const char          *   procat;
00674     char                *   filename;
00675 
00676     /* Get the QC params in qclist */
00677     qclist = cpl_propertylist_new();
00678  
00679     /* Get the reference frame */
00680     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00681     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00682                     0)) == NULL) {
00683         cpl_msg_error(cpl_func, "getting header from reference frame");
00684         cpl_propertylist_delete(qclist);
00685         return -1;
00686     }
00687     /* Test the status */
00688     if (cpl_error_get_code()) {
00689         cpl_propertylist_delete(qclist);
00690         cpl_propertylist_delete(plist);
00691         return -1;
00692     }
00693    /* Get the arm used */
00694     sval = isaac_pfits_get_arm(plist);
00695     if (sval==NULL) {
00696         cpl_msg_error(cpl_func, "Cannot get the arm used");
00697         cpl_propertylist_delete(plist);
00698         cpl_propertylist_delete(qclist);
00699         return -1;
00700     }
00701     if (sval[0] == 'S') arm = 1;
00702     else if (sval[0] == 'L') arm = 2;
00703     else {
00704         cpl_msg_error(cpl_func, "Unsupported arm");
00705         cpl_propertylist_delete(plist);
00706         cpl_propertylist_delete(qclist);
00707         return -1;
00708     }
00709     sval = isaac_pfits_get_filter(plist);
00710     if (cpl_error_get_code()) cpl_error_reset();
00711     else cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", sval);
00712     cpl_propertylist_delete(plist);
00713     cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT NCOUNTS",
00714             isaac_spc_flat_config.med_avg);
00715     cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT STDEV",
00716             isaac_spc_flat_config.med_stdev);
00717 
00718     /* Write the flat image */
00719     procat = arm == 1 ? ISAAC_SPC_FLAT_SW_RES : ISAAC_SPC_FLAT_LW_RES;
00720     filename = cpl_sprintf("isaac_spc_flat_set%02d.fits", set_nb);
00721     irplib_dfs_save_image(set_tot,
00722             parlist,
00723             set,
00724             flat,
00725             CPL_BPP_IEEE_FLOAT,
00726             "isaac_spc_flat",
00727             procat,
00728             qclist,
00729             NULL,
00730             PACKAGE "/" PACKAGE_VERSION,
00731             filename);
00732     cpl_free(filename);
00733 
00734     /* Get the reference frame */
00735     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00736 
00737     /* Get FITS header from reference file */
00738     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00739                     0)) == NULL) {
00740         cpl_msg_error(cpl_func, "getting header from reference frame");
00741         cpl_propertylist_delete(qclist);
00742         return -1;
00743     }
00744     
00745     /* Get the keywords for the paf file */
00746     paflist = cpl_propertylist_new();
00747     cpl_propertylist_copy_property_regexp(paflist, plist, 
00748         "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
00749         "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
00750         "ESO INS GRAT WLEN|ESO INS OPTI1 ID|ESO DET DIT|ESO INS LAMP3 SET)$",0);
00751     cpl_propertylist_delete(plist);
00752     
00753     /* Copy the QC in paflist */
00754     cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
00755     cpl_propertylist_delete(qclist);
00756 
00757     /* PRO.CATG */
00758     cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG, procat);
00759 
00760     /* Save the PAF file */
00761     filename = cpl_sprintf("isaac_spc_flat_set%02d.paf", set_nb);
00762     cpl_dfs_save_paf("ISAAC",
00763             "isaac_spc_flat",
00764             paflist,
00765             filename);
00766     cpl_free(filename);
00767     cpl_propertylist_delete(paflist);
00768     return  0;
00769 }
00770 
00771 /*----------------------------------------------------------------------------*/
00778 /*----------------------------------------------------------------------------*/
00779 static int isaac_spc_flat_compare(
00780         const cpl_frame *   frame1, 
00781         const cpl_frame *   frame2) 
00782 {
00783     int                     comparison;
00784     cpl_propertylist    *   plist1;
00785     cpl_propertylist    *   plist2;
00786     const char          *   sval1,
00787                         *   sval2;
00788     double                  dval1, dval2;
00789 
00790     /* Test entries */
00791     if (frame1==NULL || frame2==NULL) return -1;
00792 
00793     /* Get property lists */
00794     if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
00795                     0)) == NULL) {
00796         cpl_msg_error(cpl_func, "getting header from reference frame");
00797         return -1;
00798     }
00799     if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
00800                     0)) == NULL) {
00801         cpl_msg_error(cpl_func, "getting header from reference frame");
00802         cpl_propertylist_delete(plist1);
00803         return -1;
00804     }
00805 
00806     /* Test status */
00807     if (cpl_error_get_code()) {
00808         cpl_propertylist_delete(plist1);
00809         cpl_propertylist_delete(plist2);
00810         return -1;
00811     }
00812 
00813     comparison = 1;
00814 
00815     /* Compare the slit used */
00816     sval1 = isaac_pfits_get_opti1_id(plist1);
00817     sval2 = isaac_pfits_get_opti1_id(plist2);
00818     if (cpl_error_get_code()) {
00819         cpl_msg_error(cpl_func, "cannot get the slit used");
00820         cpl_propertylist_delete(plist1);
00821         cpl_propertylist_delete(plist2);
00822         return -1;
00823     }
00824     if (strcmp(sval1, sval2)) comparison = 0;
00825 
00826     /* Compare the resolution */
00827     sval1 = isaac_pfits_get_resolution(plist1);
00828     sval2 = isaac_pfits_get_resolution(plist2);
00829     if (cpl_error_get_code()) {
00830         cpl_msg_error(cpl_func, "cannot get the resolution");
00831         cpl_propertylist_delete(plist1);
00832         cpl_propertylist_delete(plist2);
00833         return -1;
00834     }
00835     if (strcmp(sval1, sval2)) comparison = 0;
00836 
00837     /* Compare the central wavelength */
00838     dval1 = isaac_pfits_get_wlen(plist1);
00839     dval2 = isaac_pfits_get_wlen(plist2);
00840     if (cpl_error_get_code()) {
00841         cpl_msg_error(cpl_func, "cannot get the central wavelength");
00842         cpl_propertylist_delete(plist1);
00843         cpl_propertylist_delete(plist2);
00844         return -1;
00845     }
00846     if (fabs(dval1-dval2) > 1e-4) comparison = 0;
00847 
00848     cpl_propertylist_delete(plist1);
00849     cpl_propertylist_delete(plist2);
00850     return comparison;
00851 }
00852 
00853 
Generated on Mon Feb 17 15:04:43 2014 for ISAAC Pipeline Reference Manual by  doxygen 1.6.3