isaac_spc_flat.c

00001 /* $Id: isaac_spc_flat.c,v 1.37 2011/03/03 14:03:51 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2011/03/03 14:03:51 $
00024  * $Revision: 1.37 $
00025  * $Name: HEAD $
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     int             *   labels;
00244     int                 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, nlabels);
00319         cpl_msg_indent_more();
00320         flat_one = cpl_frameset_extract(flatframes, labels, i);
00321         spflat = isaac_spc_flat_reduce(flat_one);
00322         cpl_msg_indent_less();
00323 
00324         /* Save the products */
00325         cpl_msg_info(cpl_func, "Save the products");
00326         cpl_msg_indent_more();
00327         if (!cpl_errorstate_is_equal(prestate)) {
00328             cpl_image_delete(spflat);
00329             irplib_error_recover(prestate, "Could not reduce set %d/%d", 1+i,
00330                                  nlabels);
00331         } else if (spflat == NULL) {
00332             cpl_msg_warning(cpl_func, "Cannot reduce set nb %d", i+1);
00333         } else {
00334             isaac_spc_flat_save(spflat, i+1, flat_one, parlist, framelist);
00335             cpl_image_delete(spflat);
00336             did_reduce = CPL_TRUE;
00337         }
00338         cpl_msg_indent_less();
00339         cpl_frameset_delete(flat_one);
00340     }
00341     
00342     /* Free and return */
00343     cpl_frameset_delete(flatframes);
00344     cpl_free(labels); 
00345 
00346     cpl_ensure_code(did_reduce, CPL_ERROR_ILLEGAL_INPUT);
00347 
00348     return cpl_error_set_where(cpl_func); /* Propagate error, if any */
00349 }
00350 
00351 /*----------------------------------------------------------------------------*/
00358 /*----------------------------------------------------------------------------*/
00359 static cpl_image * isaac_spc_flat_reduce(cpl_frameset * flatframes)
00360 {
00361     cpl_imagelist       *   diffs;
00362     cpl_vector          *   medians;
00363     double                  med, mean;
00364     cpl_image           *   avg_ima;
00365     cpl_image           *   fitted;
00366     int                     nima, nx, ny;
00367     int                     i;
00368 
00369     /* Test entries */
00370     if (flatframes == NULL) return NULL;
00371 
00372     /* Load input image set */
00373     cpl_msg_info(cpl_func, "Compute the difference images");
00374     if ((diffs = isaac_spc_flat_diffs(flatframes)) == NULL) {
00375         cpl_msg_error(cpl_func, "Cannot create the difference images");
00376         return NULL;
00377     }
00378     nima = cpl_imagelist_get_size(diffs);
00379     nx = cpl_image_get_size_x(cpl_imagelist_get(diffs, 0));
00380     ny = cpl_image_get_size_y(cpl_imagelist_get(diffs, 0));
00381 
00382     /* Compute medians on diff images */
00383     cpl_msg_info(cpl_func, "Compute statistics on images");
00384     cpl_msg_indent_more();
00385     medians = cpl_vector_new(nima);
00386 
00387     /* Compute some stats on input images */
00388     for (i=0; i<nima; i++) {
00389         med = cpl_image_get_median_window(cpl_imagelist_get(diffs, i),
00390                 (nx-MEDIAN_XSIZE)/2.0, (ny-MEDIAN_YSIZE)/2.0,
00391                 (nx+MEDIAN_XSIZE)/2.0, (ny+MEDIAN_YSIZE)/2.0);
00392         if (cpl_vector_set(medians, i, med) != CPL_ERROR_NONE) {
00393             cpl_msg_error(cpl_func, "Cannot compute the medians");
00394             cpl_vector_delete(medians);
00395             cpl_imagelist_delete(diffs);
00396             cpl_msg_indent_less();
00397             return NULL;
00398         }
00399     }
00400 
00401     /* Compute stdev and mean of the medians */
00402     isaac_spc_flat_config.med_avg   = cpl_vector_get_mean(medians);
00403     if (nima >= 2) 
00404         isaac_spc_flat_config.med_stdev=cpl_vector_get_stdev(medians);
00405     cpl_vector_delete(medians);
00406     cpl_msg_info(cpl_func, "Average of the medians: %g", 
00407             isaac_spc_flat_config.med_avg);
00408     cpl_msg_info(cpl_func, "Standard deviation of the medians: %g", 
00409             isaac_spc_flat_config.med_stdev);
00410     cpl_msg_indent_less();
00411 
00412     /* Divide by the mean in the vig in the difference image */
00413     cpl_msg_info(cpl_func, "Normalise the images");
00414     for (i=0; i<nima; i++) {
00415 
00416         /* Support for window readout */
00417         if ((nx != 1024) || (ny != 1024)) {
00418             mean = cpl_image_get_mean(cpl_imagelist_get(diffs, i));
00419         } else {
00420             mean = cpl_image_get_mean_window(cpl_imagelist_get(diffs, i),
00421                     isaac_spc_flat_config.llx, isaac_spc_flat_config.lly,
00422                     isaac_spc_flat_config.urx, isaac_spc_flat_config.ury);
00423         }
00424         if (cpl_image_divide_scalar(cpl_imagelist_get(diffs, i), mean) != 
00425                 CPL_ERROR_NONE) {
00426             cpl_msg_error(cpl_func, "Cannot normalise the image");
00427             cpl_imagelist_delete(diffs);
00428             return NULL;
00429         }
00430     }
00431 
00432     /* Replace by 0 the pixels whose value is <low and >high */
00433     for (i=0; i<nima; i++) {
00434         if (cpl_image_threshold(cpl_imagelist_get(diffs, i), 
00435                 isaac_spc_flat_config.low_thresh,
00436                 isaac_spc_flat_config.high_thresh,
00437                 0.0, 0.0) != CPL_ERROR_NONE) {
00438             cpl_msg_error(cpl_func, "Cannot threshold the image");
00439             cpl_imagelist_delete(diffs);
00440             return NULL;
00441         }
00442     }
00443 
00444     /* Average the image list to one image */
00445     cpl_msg_info(cpl_func, "Stack the images");
00446     if ((avg_ima = cpl_imagelist_collapse_create(diffs)) == NULL) {
00447         cpl_msg_error(cpl_func, "Cannot collapse the image list");
00448         cpl_imagelist_delete(diffs);
00449         return NULL;
00450     }
00451     cpl_imagelist_delete(diffs);
00452 
00453     /* Divide the output image by the fit    */
00454     cpl_msg_info(cpl_func, "Divide by a fit");
00455     if ((fitted = isaac_spc_flat_divide_fit(avg_ima,
00456                     isaac_spc_flat_config.fit_order,
00457                     isaac_spc_flat_config.fit_size,
00458                     isaac_spc_flat_config.offset)) == NULL) {
00459         cpl_msg_error(cpl_func, "Cannot collapse the image list");
00460         cpl_image_delete(avg_ima);
00461         return NULL;
00462     }
00463     cpl_image_delete(avg_ima);
00464     
00465     return fitted;
00466 }
00467 
00468 /*----------------------------------------------------------------------------*/
00474 /*----------------------------------------------------------------------------*/
00475 static cpl_imagelist * isaac_spc_flat_diffs(cpl_frameset * in) 
00476 {
00477     int                     nima;
00478     cpl_imagelist       *   out;
00479     cpl_image           *   in1;
00480     cpl_image           *   in2;
00481     cpl_frame           *   cur_frame;
00482     int                     i;
00483  
00484     /* Initialise */
00485     nima = cpl_frameset_get_size(in);
00486 
00487     /* Expect an even number of frames */
00488     if (nima % 2) {
00489         cpl_msg_error(cpl_func, "Odd nb of frames");
00490         return NULL;
00491     }
00492 
00493     /* Create the output image list */
00494     out = cpl_imagelist_new();
00495 
00496     /* Loop on all pairs */
00497     for (i=0; i<nima/2; i++) {
00498         cur_frame = cpl_frameset_get_frame(in, 2*i);
00499         if ((in1 = cpl_image_load(cpl_frame_get_filename(cur_frame), 
00500                         CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00501             cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i);
00502             cpl_imagelist_delete(out);
00503             return NULL;
00504         }
00505         cur_frame = cpl_frameset_get_frame(in, 2*i+1);
00506         if ((in2 = cpl_image_load(cpl_frame_get_filename(cur_frame), 
00507                         CPL_TYPE_FLOAT, 0, 0)) == NULL) {
00508             cpl_msg_error(cpl_func, "Cannot load the image %d", 2*i+1);
00509             cpl_image_delete(in1);
00510             cpl_imagelist_delete(out);
00511             return NULL;
00512         }
00513         cpl_image_subtract(in1, in2);
00514         cpl_image_delete(in2);
00515         cpl_imagelist_set(out, in1, i);
00516     }
00517     return out;
00518 }
00519 
00520 /*----------------------------------------------------------------------------*/
00526 /*----------------------------------------------------------------------------*/
00527 static cpl_image * isaac_spc_flat_divide_fit(
00528         cpl_image   *   in,
00529         int             order,
00530         int             xsize,
00531         int             offset) 
00532 {
00533     int                     nx, ny;
00534     int                     xstart, xend, ystart, yend;
00535     cpl_image           *   collapsed;
00536     float               *   pcollapsed;
00537     cpl_image           *   extracted;
00538     float               *   pextracted;
00539     int                     nb_samples;
00540     cpl_matrix          *   xvec;
00541     cpl_vector          *   yvec;
00542     cpl_polynomial      *   poly_fit;
00543     cpl_polynomial      *   poly_2d;
00544     cpl_image           *   fit_image;
00545     cpl_image           *   out;
00546     int                     power[2];
00547     int                     i;
00548     const int               maxdeg1d = order - 1;
00549     const cpl_boolean       sampsym = CPL_TRUE; /* xvec is symmetric */
00550     
00551     /* Test entries */
00552     if (in == NULL) return NULL;
00553 
00554     /* Initialise */
00555     nx = cpl_image_get_size_x(in);
00556     ny = cpl_image_get_size_y(in);
00557     
00558     /* Determine the zone to extract */
00559     xstart = (int)((nx - xsize)/2) + 1;
00560     xend = xstart + xsize - 1;
00561     if ((xstart<1) || (xend>nx)) {
00562         cpl_msg_error(cpl_func, "bad X size specified");
00563         return NULL;
00564     }
00565 
00566     /* Extract the central zone and collapse it */
00567     if ((collapsed = cpl_image_collapse_window_create(in, xstart, 1, xend, ny, 
00568                     1)) == NULL) {
00569         cpl_msg_error(cpl_func, "Cannot collpase a part of the image");
00570         return NULL;
00571     }
00572     pcollapsed = cpl_image_get_data_float(collapsed);
00573 
00574     /* Find the 'valid' zone in the 1D image */
00575     ystart = 1;
00576     while ((fabs(pcollapsed[ystart-1]) < 1e-4) && (ystart < nx)) ystart++;
00577     ystart += offset;
00578 
00579     yend = ny;
00580     while ((fabs(pcollapsed[yend-1]) <1e-4) && (yend > 1)) yend--;
00581     yend -= offset;
00582 
00583     if (ystart > yend) {
00584         cpl_msg_error(cpl_func, "invalid coordinates of the zone to extract");
00585         cpl_image_delete(collapsed);
00586         return NULL;
00587     }
00588 
00589     /* Extract the 1D signal to fit */
00590     if ((extracted = cpl_image_extract(collapsed, 1, ystart, 1, yend))==NULL) {
00591         cpl_msg_error(cpl_func, "cannot extract 1D image");
00592         cpl_image_delete(collapsed);
00593         return NULL;
00594     }
00595     cpl_image_delete(collapsed);
00596     pextracted = cpl_image_get_data_float(extracted);
00597 
00598     /* Fit the polynomial */
00599     nb_samples = cpl_image_get_size_y(extracted);
00600     xvec = cpl_matrix_new(1, nb_samples);
00601     yvec = cpl_vector_new(nb_samples);
00602     for (i=0; i<nb_samples; i++) {
00603         cpl_matrix_set(xvec, 0, i, (double)(ystart + i));
00604         cpl_vector_set(yvec,    i, (double)(pextracted[i] / xsize));
00605     }
00606     cpl_image_delete(extracted);
00607     poly_fit = cpl_polynomial_new(1);
00608     if (cpl_polynomial_fit(poly_fit, xvec, &sampsym, yvec, NULL, CPL_FALSE,
00609                            NULL, &maxdeg1d)) {
00610         cpl_msg_error(cpl_func, "cannot fit the 1D signal");
00611         cpl_matrix_delete(xvec);
00612         cpl_vector_delete(yvec);
00613         cpl_polynomial_delete(poly_fit);
00614         return NULL;
00615     }
00616     cpl_matrix_delete(xvec);
00617     cpl_vector_delete(yvec);
00618     
00619     /* The polynomial for image generation must be 2d */
00620     poly_2d = cpl_polynomial_new(2);
00621     power[0] = 0; power[1] = 0;
00622     cpl_polynomial_set_coeff(poly_2d, power, 
00623             cpl_polynomial_get_coeff(poly_fit, &(power[1])));
00624     power[0] = 0; power[1] = 1;
00625     cpl_polynomial_set_coeff(poly_2d, power, 
00626             cpl_polynomial_get_coeff(poly_fit, &(power[1])));
00627     power[0] = 0; power[1] = 2;
00628     cpl_polynomial_set_coeff(poly_2d, power, 
00629             cpl_polynomial_get_coeff(poly_fit, &(power[1])));
00630     cpl_polynomial_delete(poly_fit);
00631     
00632     /* Create the fit image */
00633     fit_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00634     cpl_image_fill_polynomial(fit_image, poly_2d, 1.0, 1.0, 1.0, 1.0);
00635     cpl_polynomial_delete(poly_2d);
00636     
00637     /* Divide the input image by the polynomial image */
00638     if ((out = cpl_image_divide_create(in, fit_image)) == NULL) {
00639         cpl_msg_error(cpl_func, "cannot divide the images");
00640         cpl_image_delete(fit_image);
00641         return NULL;
00642     }
00643     cpl_image_delete(fit_image);
00644 
00645     return out;
00646 }
00647 
00648 /*----------------------------------------------------------------------------*/
00658 /*----------------------------------------------------------------------------*/
00659 static int isaac_spc_flat_save(
00660         cpl_image           *   flat,
00661         int                     set_nb,
00662         cpl_frameset        *   set,
00663         cpl_parameterlist   *   parlist,
00664         cpl_frameset        *   set_tot)
00665 {
00666     cpl_propertylist    *   plist;
00667     cpl_propertylist    *   qclist;
00668     cpl_propertylist    *   paflist;
00669     const cpl_frame           *   ref_frame;
00670     const char          *   sval;
00671     int                     arm;
00672     const char          *   procat;
00673     char                *   filename;
00674 
00675     /* Get the QC params in qclist */
00676     qclist = cpl_propertylist_new();
00677  
00678     /* Get the reference frame */
00679     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00680     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00681                     0)) == NULL) {
00682         cpl_msg_error(cpl_func, "getting header from reference frame");
00683         cpl_propertylist_delete(qclist);
00684         return -1;
00685     }
00686     /* Test the status */
00687     if (cpl_error_get_code()) {
00688         cpl_propertylist_delete(qclist);
00689         cpl_propertylist_delete(plist);
00690         return -1;
00691     }
00692    /* Get the arm used */
00693     sval = isaac_pfits_get_arm(plist);
00694     if (sval==NULL) {
00695         cpl_msg_error(cpl_func, "Cannot get the arm used");
00696         cpl_propertylist_delete(plist);
00697         cpl_propertylist_delete(qclist);
00698         return -1;
00699     }
00700     if (sval[0] == 'S') arm = 1;
00701     else if (sval[0] == 'L') arm = 2;
00702     else {
00703         cpl_msg_error(cpl_func, "Unsupported arm");
00704         cpl_propertylist_delete(plist);
00705         cpl_propertylist_delete(qclist);
00706         return -1;
00707     }
00708     sval = isaac_pfits_get_filter(plist);
00709     if (cpl_error_get_code()) cpl_error_reset();
00710     else cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", sval);
00711     cpl_propertylist_delete(plist);
00712     cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT NCOUNTS",
00713             isaac_spc_flat_config.med_avg);
00714     cpl_propertylist_append_double(qclist, "ESO QC SPECFLAT STDEV",
00715             isaac_spc_flat_config.med_stdev);
00716 
00717     /* Write the flat image */
00718     procat = arm == 1 ? ISAAC_SPC_FLAT_SW_RES : ISAAC_SPC_FLAT_LW_RES;
00719     filename = cpl_sprintf("isaac_spc_flat_set%02d.fits", set_nb);
00720     irplib_dfs_save_image(set_tot,
00721             parlist,
00722             set,
00723             flat,
00724             CPL_BPP_IEEE_FLOAT,
00725             "isaac_spc_flat",
00726             procat,
00727             qclist,
00728             NULL,
00729             PACKAGE "/" PACKAGE_VERSION,
00730             filename);
00731     cpl_free(filename);
00732 
00733     /* Get the reference frame */
00734     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
00735 
00736     /* Get FITS header from reference file */
00737     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
00738                     0)) == NULL) {
00739         cpl_msg_error(cpl_func, "getting header from reference frame");
00740         cpl_propertylist_delete(qclist);
00741         return -1;
00742     }
00743     
00744     /* Get the keywords for the paf file */
00745     paflist = cpl_propertylist_new();
00746     cpl_propertylist_copy_property_regexp(paflist, plist, 
00747         "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
00748         "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
00749         "ESO INS GRAT WLEN|ESO INS OPTI1 ID|ESO DET DIT|ESO INS LAMP3 SET)$",0);
00750     cpl_propertylist_delete(plist);
00751     
00752     /* Copy the QC in paflist */
00753     cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
00754     cpl_propertylist_delete(qclist);
00755 
00756     /* PRO.CATG */
00757     cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG, procat);
00758 
00759     /* Save the PAF file */
00760     filename = cpl_sprintf("isaac_spc_flat_set%02d.paf", set_nb);
00761     cpl_dfs_save_paf("ISAAC",
00762             "isaac_spc_flat",
00763             paflist,
00764             filename);
00765     cpl_free(filename);
00766     cpl_propertylist_delete(paflist);
00767     return  0;
00768 }
00769 
00770 /*----------------------------------------------------------------------------*/
00777 /*----------------------------------------------------------------------------*/
00778 static int isaac_spc_flat_compare(
00779         const cpl_frame *   frame1, 
00780         const cpl_frame *   frame2) 
00781 {
00782     int                     comparison;
00783     cpl_propertylist    *   plist1;
00784     cpl_propertylist    *   plist2;
00785     const char          *   sval1,
00786                         *   sval2;
00787     double                  dval1, dval2;
00788 
00789     /* Test entries */
00790     if (frame1==NULL || frame2==NULL) return -1;
00791 
00792     /* Get property lists */
00793     if ((plist1=cpl_propertylist_load(cpl_frame_get_filename(frame1),
00794                     0)) == NULL) {
00795         cpl_msg_error(cpl_func, "getting header from reference frame");
00796         return -1;
00797     }
00798     if ((plist2=cpl_propertylist_load(cpl_frame_get_filename(frame2),
00799                     0)) == NULL) {
00800         cpl_msg_error(cpl_func, "getting header from reference frame");
00801         cpl_propertylist_delete(plist1);
00802         return -1;
00803     }
00804 
00805     /* Test status */
00806     if (cpl_error_get_code()) {
00807         cpl_propertylist_delete(plist1);
00808         cpl_propertylist_delete(plist2);
00809         return -1;
00810     }
00811 
00812     comparison = 1;
00813 
00814     /* Compare the slit used */
00815     sval1 = isaac_pfits_get_opti1_id(plist1);
00816     sval2 = isaac_pfits_get_opti1_id(plist2);
00817     if (cpl_error_get_code()) {
00818         cpl_msg_error(cpl_func, "cannot get the slit used");
00819         cpl_propertylist_delete(plist1);
00820         cpl_propertylist_delete(plist2);
00821         return -1;
00822     }
00823     if (strcmp(sval1, sval2)) comparison = 0;
00824 
00825     /* Compare the resolution */
00826     sval1 = isaac_pfits_get_resolution(plist1);
00827     sval2 = isaac_pfits_get_resolution(plist2);
00828     if (cpl_error_get_code()) {
00829         cpl_msg_error(cpl_func, "cannot get the resolution");
00830         cpl_propertylist_delete(plist1);
00831         cpl_propertylist_delete(plist2);
00832         return -1;
00833     }
00834     if (strcmp(sval1, sval2)) comparison = 0;
00835 
00836     /* Compare the central wavelength */
00837     dval1 = isaac_pfits_get_wlen(plist1);
00838     dval2 = isaac_pfits_get_wlen(plist2);
00839     if (cpl_error_get_code()) {
00840         cpl_msg_error(cpl_func, "cannot get the central wavelength");
00841         cpl_propertylist_delete(plist1);
00842         cpl_propertylist_delete(plist2);
00843         return -1;
00844     }
00845     if (fabs(dval1-dval2) > 1e-4) comparison = 0;
00846 
00847     cpl_propertylist_delete(plist1);
00848     cpl_propertylist_delete(plist2);
00849     return comparison;
00850 }
00851 
00852 

Generated on Wed Mar 9 15:43:10 2011 for ISAAC Pipeline Reference Manual by  doxygen 1.5.8