isaac_spc_startrace.c

00001 /* $Id: isaac_spc_startrace.c,v 1.50 2012/01/25 12:51:30 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: 2012/01/25 12:51:30 $
00024  * $Revision: 1.50 $
00025  * $Name: isaac-6_1_3 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <math.h>
00037 #include <float.h>
00038 #include <cpl.h>
00039 
00040 #include "irplib_plugin.h"
00041 #include "irplib_utils.h"
00042 #include "irplib_spectrum.h"
00043 
00044 #include "isaac_utils.h"
00045 #include "isaac_pfits.h"
00046 #include "isaac_dfs.h"
00047 
00048 /*-----------------------------------------------------------------------------
00049                                 Define
00050  -----------------------------------------------------------------------------*/
00051 
00052 #define RECIPE_STRING "isaac_spc_startrace"
00053 
00054 #define Z_LR_LEFT_REJ       300
00055 #define Z_LR_RIGHT_REJ      325
00056 #define SZ_LR_LEFT_REJ      300
00057 #define SZ_LR_RIGHT_REJ     325
00058 #define J_LR_LEFT_REJ       200
00059 #define J_LR_RIGHT_REJ      200
00060 #define SH_LR_LEFT_REJ      150 
00061 #define SH_LR_RIGHT_REJ     175
00062 #define SK_LR_LEFT_REJ      150
00063 #define SK_LR_RIGHT_REJ     175
00064 #define MR_LEFT_REJ         30
00065 #define MR_RIGHT_REJ        30
00066 
00067 /*-----------------------------------------------------------------------------
00068                             Functions prototypes
00069  -----------------------------------------------------------------------------*/
00070 
00071 static cpl_error_code isaac_spc_startrace_reduce(cpl_frameset *,
00072                                                  const cpl_frameset *,
00073                                                  const cpl_matrix *, char, 
00074                                                  const cpl_parameterlist *);
00075 
00076 static cpl_size * isaac_spc_startrace_resol(cpl_frameset *);
00077 static cpl_imagelist * isaac_spc_startrace_load(const cpl_frameset *);
00078 static cpl_matrix * isaac_spc_startrace_starpos(const cpl_frameset *);
00079 static cpl_polynomial * isaac_spc_startrace_shape(cpl_image *, double, char, 
00080         double *);
00081 static cpl_polynomial * isaac_spc_startrace_distor(cpl_polynomial **, 
00082         cpl_vector *, int, int);
00083 static cpl_error_code isaac_spc_startrace_save(cpl_frameset *,
00084                                                const cpl_table *,
00085                                                const cpl_matrix *,
00086                                                const cpl_vector *,
00087                                                cpl_polynomial **,
00088                                                const cpl_frameset *,
00089                                                char, 
00090                                                const cpl_parameterlist *);
00091  
00092 
00093 cpl_recipe_define(isaac_spc_startrace, ISAAC_BINARY_VERSION,
00094                   "Lars Lundin", PACKAGE_BUGREPORT, "2002, 2003, 2008", 
00095                   "ISAAC Spectro startrace recipe",
00096                   RECIPE_STRING " -- ISAAC Spectro startrace recipe\n"
00097                   "The files listed in the Set Of Frames (sof-file) " 
00098                   "must be tagged:\n"
00099                   "raw-file.fits "ISAAC_SPC_STARTRACE_IM_RAW" or\n"
00100                   "raw-file.fits "ISAAC_SPC_STARTRACE_SP_RAW"\n"
00101                   "Given N imaging frames, the spectro frames must consist of "
00102                   "N (or zero) low resolution frames and "
00103                   "N (or zero) medium resolution frames.");
00104 
00105 /*-----------------------------------------------------------------------------
00106                             Static variables
00107  -----------------------------------------------------------------------------*/
00108 
00109 static struct {
00110     /* Inputs */
00111     cpl_size    degree;
00112     int         spec_width;
00113     int         reject_left;
00114     int         reject_right;
00115     int         display;
00116     /* Outputs */
00117     int         arm;
00118     isaac_band  band;
00119     double      corr_is1;
00120     double      corr_is2;
00121     double      corr_is3;
00122     double      shapes_fit_q;
00123     double      dist1;
00124     double      distx;
00125     double      disty;
00126     double      distxy;
00127     double      distxx;
00128     double      distyy;
00129 } isaac_spc_startrace_config;
00130 
00131 /*-----------------------------------------------------------------------------
00132                                 Functions code
00133  -----------------------------------------------------------------------------*/
00134 
00135 /*----------------------------------------------------------------------------*/
00143 /*----------------------------------------------------------------------------*/
00144 static
00145 cpl_error_code isaac_spc_startrace_fill_parameterlist(cpl_parameterlist * self)
00146 {
00147     const char * context = PACKAGE "." RECIPE_STRING;
00148     cpl_error_code err;
00149 
00150     cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
00151 
00152     /* Fill the parameters list */
00153 
00154     /* --degree */
00155     err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00156                                        "degree", 3, "deg",
00157                                        context, "polynomial degree");
00158     cpl_ensure_code(!err, err);
00159 
00160     /* --spec_width */
00161     err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00162                                        "spectrum_width", 40, "spec_width",
00163                                        context, "spectrum width");
00164     cpl_ensure_code(!err, err);
00165 
00166      /* --reject_left */
00167     err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00168                                        "reject_left", -1, NULL,
00169                                        context, "left part rejection");
00170     cpl_ensure_code(!err, err);
00171 
00172      /* --reject_right */
00173     err = irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING,
00174                                        "reject_right", -1, NULL,
00175                                        context, "right part rejection");
00176     cpl_ensure_code(!err, err);
00177 
00178     /* --display */
00179     err = irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING,
00180                                         "display", CPL_FALSE, NULL, context,
00181                                         "Flag to make plots");
00182     cpl_ensure_code(!err, err);
00183 
00184     return CPL_ERROR_NONE;
00185 }
00186 
00187 
00188 /*----------------------------------------------------------------------------*/
00196 /*----------------------------------------------------------------------------*/
00197 static int isaac_spc_startrace(cpl_frameset            * framelist,
00198                                const cpl_parameterlist * parlist)
00199 {
00200     const char          *   sval;
00201     cpl_size            *   labels = NULL;
00202     const cpl_frame     *   cur_frame;
00203     cpl_propertylist    *   plist = NULL;
00204     cpl_frameset        *   imframes = NULL;
00205     cpl_frameset        *   spframes = NULL;
00206     cpl_frameset        *   spframes_lr = NULL;
00207     cpl_frameset        *   spframes_mr = NULL;
00208     cpl_matrix          *   star_pos = NULL;
00209     int                     ndone = 0;
00210     
00211 
00212     bug_if(0);
00213 
00214     /* Retrieve input parameters */
00215 
00216     /* Polynomial degree */
00217     isaac_spc_startrace_config.degree
00218         = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00219                                        "degree");
00220     /* Spectrum width */
00221     isaac_spc_startrace_config.spec_width
00222         = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00223                                        "spectrum_width");
00224     /* Rejection parameters */
00225     isaac_spc_startrace_config.reject_left
00226         = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00227                                        "reject_left");
00228     isaac_spc_startrace_config.reject_right
00229         = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
00230                                        "reject_right");
00231     /* Display */
00232     isaac_spc_startrace_config.display
00233         = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
00234                                         "display");
00235 
00236     /* Identify the RAW and CALIB frames in the input frameset */
00237     skip_if (isaac_dfs_set_groups(framelist));
00238  
00239     /* Get the arm used (SW or LW) */
00240     cur_frame = cpl_frameset_get_first_const(framelist);
00241     error_if(cur_frame == NULL, CPL_ERROR_DATA_NOT_FOUND,
00242              "Could not get 1st frame from frameset");
00243     plist = cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0);
00244     any_if("Could not load propertylist from 1st frame");
00245 
00246     sval = isaac_pfits_get_arm(plist);
00247     any_if("Could not get the arm");
00248 
00249     if (sval[0] == 'S') {
00250         isaac_spc_startrace_config.arm = 1;
00251     } else if (sval[0] == 'L') {
00252         isaac_spc_startrace_config.arm = 2;
00253     } else {
00254         error_if(1, CPL_ERROR_UNSUPPORTED_MODE, "Unsupported arm: %s", sval);
00255     }
00256 
00257     /* Get the band */
00258     sval = isaac_pfits_get_filter(plist);
00259     any_if("Could not get the filter");
00260 
00261     isaac_spc_startrace_config.band = isaac_get_bbfilter(sval);
00262     any_if("Could not get the band");
00263 
00264     cpl_propertylist_empty(plist);
00265     
00266     /* Retrieve raw frames */
00267     imframes = isaac_extract_frameset(framelist, ISAAC_SPC_STARTRACE_IM_RAW);
00268     error_if(imframes == NULL, CPL_ERROR_DATA_NOT_FOUND, "Could not find the "
00269              "imframes in the input list");
00270 
00271     spframes = isaac_extract_frameset(framelist, ISAAC_SPC_STARTRACE_SP_RAW);
00272     error_if(spframes == NULL, CPL_ERROR_DATA_NOT_FOUND, "Could not find the "
00273              "spframes in the input list");
00274 
00275     /* Separate LR and MR spectra */
00276     labels = isaac_spc_startrace_resol(spframes);
00277     error_if(labels == NULL, cpl_error_get_code(), "Could not differentiate "
00278              "LR and MR");
00279 
00280     spframes_lr = cpl_frameset_extract(spframes, labels, 1);
00281     spframes_mr = cpl_frameset_extract(spframes, labels, 2);
00282     cpl_free(labels);
00283     labels = NULL;
00284     
00285     /* Get the star positions */
00286     cpl_msg_info(cpl_func, "Get the star positions");
00287     star_pos = isaac_spc_startrace_starpos(imframes);
00288     error_if(star_pos == NULL, cpl_error_get_code(), "Could not find star the "
00289              "positions");
00290 
00291     cpl_frameset_delete(imframes);
00292     imframes = NULL;
00293 
00294     error_if (spframes_lr == NULL && spframes_mr == NULL,
00295               CPL_ERROR_UNSUPPORTED_MODE, "The %d spectro frames are not LR "
00296               "nor MR", (int)cpl_frameset_get_size(spframes));
00297     cpl_frameset_delete(spframes);
00298     spframes = NULL;
00299 
00300     if (spframes_lr != NULL) {
00301         cpl_errorstate prestate = cpl_errorstate_get();
00302         /* Reduction in LR */
00303         cpl_msg_info(cpl_func, "Reducing the LR spectra");
00304         if (isaac_spc_startrace_reduce(framelist, spframes_lr, star_pos,
00305                                        'L', parlist)) {
00306             irplib_error_recover(prestate, "Could not reduce the LR spectra");
00307         } else {
00308             ndone++;
00309         }
00310         cpl_frameset_delete(spframes_lr);
00311         spframes_lr = NULL;
00312     }
00313     if (spframes_mr != NULL) {
00314         cpl_errorstate prestate = cpl_errorstate_get();
00315         /* Reduction in MR */
00316         cpl_msg_info(cpl_func, "Reducing the MR spectra");
00317         if (isaac_spc_startrace_reduce(framelist, spframes_mr, star_pos,
00318                                        'M', parlist)) {
00319             irplib_error_recover(prestate, "Could not reduce the MR spectra");
00320         } else {
00321             ndone++;
00322         }
00323         cpl_frameset_delete(spframes_mr);
00324         spframes_mr = NULL;
00325     }
00326 
00327     error_if(!ndone, CPL_ERROR_ILLEGAL_INPUT, "Could not reduce the spectra");
00328 
00329     end_skip;
00330 
00331     cpl_free(labels);
00332     cpl_propertylist_delete(plist);
00333     cpl_frameset_delete(imframes);
00334     cpl_frameset_delete(spframes);
00335     cpl_frameset_delete(spframes_lr);
00336     cpl_frameset_delete(spframes_mr);
00337     cpl_matrix_delete(star_pos);
00338 
00339     return cpl_error_get_code();
00340 }
00341 
00342 /*----------------------------------------------------------------------------*/
00353 /*----------------------------------------------------------------------------*/
00354 static
00355 cpl_error_code isaac_spc_startrace_reduce(cpl_frameset            * framelist,
00356                                           const cpl_frameset      * spframes,
00357                                           const cpl_matrix        * star_pos,
00358                                           char                      resol,
00359                                           const cpl_parameterlist * parlist)
00360 {
00361     /* Load the input images */
00362     cpl_imagelist   * ilist = isaac_spc_startrace_load(spframes);
00363     const int         nframes = cpl_frameset_get_size(spframes);
00364     cpl_vector      * spec_pos = cpl_vector_new(nframes);
00365     double          * pspec_pos = cpl_vector_get_data(spec_pos);
00366     cpl_polynomial  * corresp = cpl_polynomial_new(1);
00367     cpl_polynomial ** shapes = cpl_calloc(nframes, sizeof(cpl_polynomial*));
00368     cpl_vector      * fit_q = cpl_vector_new(nframes);
00369     double          * pfit_q = cpl_vector_get_data(fit_q);
00370     const int         nx = cpl_image_get_size_x(cpl_imagelist_get(ilist, 0));
00371     cpl_polynomial  * distor = NULL;
00372     cpl_table       * out_tab = NULL;
00373     cpl_size          power[2];
00374     const cpl_size    maxdeg = 2;
00375     cpl_size          i;
00376 
00377     bug_if(0);
00378     bug_if(framelist == NULL);
00379     bug_if(star_pos == NULL);
00380     bug_if(parlist == NULL);
00381 
00382     error_if(cpl_matrix_get_ncol(star_pos) != nframes,
00383              CPL_ERROR_INCOMPATIBLE_INPUT, "Number of spectro frames (%d) "
00384              "differ from number of star positions (%d)", nframes,
00385              (int)cpl_matrix_get_ncol(star_pos));
00386 
00387     /* Find the spectra positions */
00388     for (i=0; i<nframes; i++) {
00389         const cpl_image * image = cpl_imagelist_get_const(ilist, i);
00390         const double mean = cpl_image_get_mean(image);
00391         const double min_bright = 20.0 * mean;
00392 
00393         error_if (irplib_spectrum_find_brightest(image, 0, NO_SHADOW,
00394                                                  min_bright, 0, &(pspec_pos[i])),
00395                   cpl_error_get_code(), "Could not detect spectrum in frame %d "
00396                   "of %d with mean flux=%g", (int)i+1, nframes, mean);
00397     }
00398 
00399     /* Compute spectra / star correspondance */
00400     error_if (cpl_polynomial_fit(corresp, star_pos, NULL, spec_pos, NULL,
00401                                  CPL_FALSE, NULL, &maxdeg), cpl_error_get_code(),
00402               "Could not fit a %d degree polynomial to the %d positions",
00403               (int)maxdeg, nframes);
00404 
00405     /* Store the result coefficients */
00406     i = 0;
00407     isaac_spc_startrace_config.corr_is1 = cpl_polynomial_get_coeff(corresp, &i);
00408     i = 1;
00409     isaac_spc_startrace_config.corr_is2 = cpl_polynomial_get_coeff(corresp, &i);
00410     i = 2;
00411     isaac_spc_startrace_config.corr_is3 = cpl_polynomial_get_coeff(corresp, &i);
00412     cpl_polynomial_delete(corresp);
00413     corresp = NULL;
00414     
00415     /* Compute the spectra shapes */
00416     for (i=0; i<nframes; i++) {
00417         shapes[i] = isaac_spc_startrace_shape(cpl_imagelist_get(ilist, i),
00418                                               cpl_vector_get(spec_pos, i), 
00419                                               resol, 
00420                                               &(pfit_q[i]));
00421 
00422         error_if (shapes[i] == NULL, cpl_error_get_code(), "Could not get the "
00423                   "shape of frame %d of %d", (int)i+1, nframes);
00424 
00425         cpl_msg_info(cpl_func, "Spectrum %d : Y = %g; Fit mse = %g", (int)i+1,
00426                      cpl_vector_get(spec_pos, i), pfit_q[i]);
00427     }
00428     isaac_spc_startrace_config.shapes_fit_q = cpl_vector_get_median_const(fit_q);
00429     cpl_vector_delete(fit_q);
00430     fit_q = NULL;
00431     cpl_imagelist_delete(ilist);
00432     ilist = NULL;
00433 
00434     /* Compute the 2d distortion */
00435     distor = isaac_spc_startrace_distor(shapes, spec_pos, nframes, nx);
00436     error_if (distor == NULL, cpl_error_get_code(),  "Could not compute the "
00437               "distortion");
00438    
00439     /* Create the table */
00440     out_tab = cpl_table_new(6);
00441     cpl_table_new_column(out_tab, "Degree_of_x", CPL_TYPE_INT);
00442     cpl_table_new_column(out_tab, "Degree_of_y", CPL_TYPE_INT);
00443     cpl_table_new_column(out_tab, "poly2d_coef", CPL_TYPE_DOUBLE);
00444     power[0] = 0; power[1] = 0;
00445     cpl_table_set_int(out_tab, "Degree_of_x", 0, power[0]);
00446     cpl_table_set_int(out_tab, "Degree_of_y", 0, power[1]);
00447     isaac_spc_startrace_config.dist1 = cpl_polynomial_get_coeff(distor, power);
00448     cpl_table_set_double(out_tab, "poly2d_coef", 0,
00449             isaac_spc_startrace_config.dist1);
00450     power[0] = 1; power[1] = 0;
00451     cpl_table_set_int(out_tab, "Degree_of_x", 1, power[0]);
00452     cpl_table_set_int(out_tab, "Degree_of_y", 1, power[1]);
00453     isaac_spc_startrace_config.distx = cpl_polynomial_get_coeff(distor, power);
00454     cpl_table_set_double(out_tab, "poly2d_coef", 1,
00455             isaac_spc_startrace_config.distx);
00456     power[0] = 0; power[1] = 1;
00457     cpl_table_set_int(out_tab, "Degree_of_x", 2, power[0]);
00458     cpl_table_set_int(out_tab, "Degree_of_y", 2, power[1]);
00459     isaac_spc_startrace_config.disty = cpl_polynomial_get_coeff(distor, power);
00460     cpl_table_set_double(out_tab, "poly2d_coef", 2,
00461             isaac_spc_startrace_config.disty);
00462     power[0] = 1; power[1] = 1;
00463     cpl_table_set_int(out_tab, "Degree_of_x", 3, power[0]);
00464     cpl_table_set_int(out_tab, "Degree_of_y", 3, power[1]);
00465     isaac_spc_startrace_config.distxy = cpl_polynomial_get_coeff(distor, power);
00466     cpl_table_set_double(out_tab, "poly2d_coef", 3,
00467             isaac_spc_startrace_config.distxy);
00468     power[0] = 2; power[1] = 0;
00469     cpl_table_set_int(out_tab, "Degree_of_x", 4, power[0]);
00470     cpl_table_set_int(out_tab, "Degree_of_y", 4, power[1]);
00471     isaac_spc_startrace_config.distxx = cpl_polynomial_get_coeff(distor, power);
00472     cpl_table_set_double(out_tab, "poly2d_coef", 4,
00473             isaac_spc_startrace_config.distxx);
00474     power[0] = 0; power[1] = 2;
00475     cpl_table_set_int(out_tab, "Degree_of_x", 5, power[0]);
00476     cpl_table_set_int(out_tab, "Degree_of_y", 5, power[1]);
00477     isaac_spc_startrace_config.distyy = cpl_polynomial_get_coeff(distor, power);
00478     cpl_table_set_double(out_tab, "poly2d_coef", 5,
00479             isaac_spc_startrace_config.distyy);
00480 
00481     cpl_polynomial_delete(distor);
00482     distor = NULL;
00483 
00484     /* Display result */
00485     cpl_msg_info(cpl_func, 
00486             "Distortion : Y(x,y) = a + bx + cy + dxy + exx + fyy");
00487     cpl_msg_info(cpl_func, "a = %g", isaac_spc_startrace_config.dist1);
00488     cpl_msg_info(cpl_func, "b = %g", isaac_spc_startrace_config.distx);
00489     cpl_msg_info(cpl_func, "c = %g", isaac_spc_startrace_config.disty);
00490     cpl_msg_info(cpl_func, "d = %g", isaac_spc_startrace_config.distxy);
00491     cpl_msg_info(cpl_func, "e = %g", isaac_spc_startrace_config.distxx);
00492     cpl_msg_info(cpl_func, "f = %g", isaac_spc_startrace_config.distyy);
00493 
00494     /* Write the product */
00495     skip_if (isaac_spc_startrace_save(framelist, out_tab, star_pos, spec_pos,
00496                                       shapes, spframes, resol, parlist));
00497 
00498     end_skip;
00499 
00500     cpl_polynomial_delete(distor);
00501     cpl_vector_delete(fit_q);
00502     cpl_polynomial_delete(corresp);
00503     if (shapes != NULL) {
00504         for (i = 0; i < nframes; i++) cpl_polynomial_delete(shapes[i]);
00505         cpl_free(shapes);
00506     }
00507     cpl_vector_delete(spec_pos);
00508     cpl_imagelist_delete(ilist);
00509     cpl_table_delete(out_tab);
00510 
00511     return cpl_error_get_code();
00512 }
00513 
00514 /*----------------------------------------------------------------------------*/
00522 /*----------------------------------------------------------------------------*/
00523 static cpl_size * isaac_spc_startrace_resol(cpl_frameset * spframes)
00524 {
00525     int                     nframes;
00526     cpl_size            *   labels;
00527     cpl_frame           *   cur_frame;
00528     cpl_propertylist    *   plist;
00529     const char          *   sval;
00530     int                     i;
00531 
00532     /* Test entries */
00533     if (spframes == NULL) return NULL;
00534 
00535     /* Initialise */
00536     nframes = cpl_frameset_get_size(spframes);
00537 
00538     /* Create output array */
00539     labels = (cpl_size*)cpl_malloc(nframes * sizeof(*labels));
00540 
00541     /* Loop on the frames */
00542     for (i=0; i<nframes; i++) {
00543         cur_frame = cpl_frameset_get_frame(spframes, i);
00544         plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0);
00545         /* Get the resolution */
00546         if ((sval = isaac_pfits_get_resolution(plist)) == NULL) {
00547             cpl_free(labels);
00548             cpl_msg_error(cpl_func,"cannot get the resolution");
00549             return NULL;
00550         }
00551         if (sval[0]=='L') labels[i] = 1;
00552         else if (sval[0]=='M') labels[i] = 2;
00553         else labels[i] = 0;
00554         cpl_propertylist_delete(plist);
00555     }
00556     return labels;
00557 }
00558    
00559 /*----------------------------------------------------------------------------*/
00566 /*----------------------------------------------------------------------------*/
00567 static cpl_matrix * isaac_spc_startrace_starpos(const cpl_frameset * imframes)
00568 {
00569     int                     nframes;
00570     cpl_matrix          *   ypositions;
00571     cpl_apertures       *   objects;
00572     double              *   ypos;
00573     cpl_imagelist       *   ilist;
00574     int                     i;
00575 
00576     /* Test entries */
00577     if (imframes == NULL) return NULL;
00578 
00579     /* Load the input images */
00580     if ((ilist = isaac_spc_startrace_load(imframes)) == NULL) return NULL;
00581 
00582     /* Initialise */
00583     nframes = cpl_frameset_get_size(imframes);
00584 
00585     /* Create bivector */
00586     ypositions = cpl_matrix_new(1, nframes);
00587     ypos = cpl_matrix_get_data(ypositions);
00588 
00589     /* Loop on the frames */
00590     for (i=0; i<nframes; i++) {
00591         double xpos;
00592         if ((objects = cpl_apertures_extract_sigma(cpl_imagelist_get(ilist, i),
00593                         2.0)) == NULL) {
00594             cpl_msg_error(cpl_func, "cannot detect any object");
00595             cpl_matrix_delete(ypositions);
00596             cpl_imagelist_delete(ilist);
00597             return NULL;
00598         }
00599         cpl_apertures_sort_by_flux(objects);
00600         xpos = cpl_apertures_get_centroid_x(objects, 1);
00601         ypos[i] = cpl_apertures_get_centroid_y(objects, 1);
00602         cpl_apertures_delete(objects);
00603         cpl_msg_info(cpl_func, "Image %d: Position (%g, %g)", i+1,xpos, ypos[i]);
00604     }
00605     cpl_imagelist_delete(ilist);
00606     return ypositions;
00607 }
00608  
00609 /*----------------------------------------------------------------------------*/
00616 /*----------------------------------------------------------------------------*/
00617 static cpl_imagelist * isaac_spc_startrace_load(const cpl_frameset * inframes)
00618 {
00619     cpl_imagelist       *   ilist;
00620     int                     nframes;
00621     cpl_image           *   tmp_im;
00622     int                     i;
00623 
00624     /* Test entries */
00625     if (inframes == NULL) return NULL;
00626 
00627     /* Initialise */
00628     nframes = cpl_frameset_get_size(inframes);
00629 
00630     /* Load the images */
00631     if ((ilist = cpl_imagelist_load_frameset(inframes, CPL_TYPE_FLOAT, 1, 
00632                     0)) == NULL) return NULL;
00633 
00634     /* In LW that's it */
00635     if (isaac_spc_startrace_config.arm == 2) return ilist; 
00636 
00637     /* In SW, the frames are subtracted to remove the background */
00638     tmp_im = cpl_image_duplicate(cpl_imagelist_get(ilist, 0));
00639     for (i=0; i<nframes-1; i++) {
00640         if (cpl_image_subtract(cpl_imagelist_get(ilist, i),
00641                 cpl_imagelist_get(ilist, i+1)) != CPL_ERROR_NONE) {
00642             cpl_msg_error(cpl_func, "cannot subtract images");
00643             cpl_imagelist_delete(ilist);
00644             cpl_image_delete(tmp_im);
00645             return NULL;
00646         }
00647     }
00648     /* Handle last frame */
00649     if (cpl_image_subtract(cpl_imagelist_get(ilist, nframes-1), 
00650             tmp_im) != CPL_ERROR_NONE) {
00651         cpl_msg_error(cpl_func, "cannot subtract images");
00652         cpl_imagelist_delete(ilist);
00653         cpl_image_delete(tmp_im);
00654         return NULL;
00655     }
00656     cpl_image_delete(tmp_im);
00657 
00658     /* Set negative pixels to 0  */
00659     cpl_imagelist_threshold(ilist, 0.0, DBL_MAX, 0.0, 0.0);
00660     
00661     return ilist;
00662 }
00663 
00664 /*----------------------------------------------------------------------------*/
00674 /*----------------------------------------------------------------------------*/
00675 static cpl_polynomial * isaac_spc_startrace_shape(
00676         cpl_image       *   in,
00677         double              ypos,
00678         char                resol,
00679         double          *   fit_quality)
00680 {
00681     int                     reject_left, reject_right;
00682     cpl_image           *   filtered;
00683     int                     low_side, up_side;
00684     cpl_mask            *   kernel;
00685     cpl_matrix          *   fit_x;
00686     cpl_vector          *   fit_y;
00687     double              *   pfit_x;
00688     double              *   pfit_y;
00689     cpl_polynomial      *   fitted;
00690     cpl_bivector        *   toplot;
00691     int                     i;
00692     int                     nsamples;
00693     const cpl_boolean       sampsym = CPL_TRUE; /* fit_x is symmetric */
00694 
00695     /* Check entries */
00696     if ((in == NULL) || (ypos < 0) || (fit_quality == NULL)) return NULL;
00697    
00698     /* Initialise */
00699     reject_left = isaac_spc_startrace_config.reject_left;
00700     reject_right = isaac_spc_startrace_config.reject_right;
00701     low_side = (int)(ypos - (isaac_spc_startrace_config.spec_width)/2);
00702     up_side = low_side + isaac_spc_startrace_config.spec_width;
00703 
00704     /* Test spectrum position */
00705     if ((low_side < 1) || (up_side > cpl_image_get_size_y(in))) {
00706         cpl_msg_error(cpl_func, "spectrum too close to the image border");
00707         return NULL;
00708     }
00709    
00710     /* Get rejection parameters */
00711     if (isaac_spc_startrace_config.arm == 1) {
00712         /* SW */
00713         if (reject_left < 0) {
00714             if (resol == 'M') reject_left = MR_LEFT_REJ;
00715             else if (resol == 'L') {
00716                 switch (isaac_spc_startrace_config.band) {
00717                     case ISAAC_BAND_Z:    reject_left = Z_LR_LEFT_REJ; break;
00718                     case ISAAC_BAND_SZ:   reject_left = SZ_LR_LEFT_REJ; break;
00719                     case ISAAC_BAND_JBLOCK:
00720                     case ISAAC_BAND_J:    reject_left = J_LR_LEFT_REJ; break;
00721                     case ISAAC_BAND_SH:   reject_left = SH_LR_LEFT_REJ; break;
00722                     case ISAAC_BAND_SK:   reject_left = SK_LR_LEFT_REJ; break;
00723                     default:
00724                         cpl_msg_warning(cpl_func, "unsupported filter");
00725                         reject_left = 0;
00726                         break;
00727                 }
00728             }
00729         }
00730         if (reject_right < 0) {
00731             if (resol == 'M') reject_right = MR_RIGHT_REJ;
00732             else if (resol == 'L') {
00733                 switch (isaac_spc_startrace_config.band) {
00734                     case ISAAC_BAND_Z:    reject_right = Z_LR_RIGHT_REJ; break;
00735                     case ISAAC_BAND_SZ:   reject_right = SZ_LR_RIGHT_REJ;break;
00736                     case ISAAC_BAND_JBLOCK:
00737                     case ISAAC_BAND_J:    reject_right = J_LR_RIGHT_REJ; break;
00738                     case ISAAC_BAND_SH:   reject_right = SH_LR_RIGHT_REJ;break;
00739                     case ISAAC_BAND_SK:   reject_right = SK_LR_RIGHT_REJ;break;
00740                     default:
00741                         cpl_msg_warning(cpl_func, "unsupported filter");
00742                         reject_right = 0;
00743                         break;
00744                 }
00745             }
00746         }
00747     } else if (isaac_spc_startrace_config.arm == 2) {
00748         /* LW */
00749         if (reject_left < 0) reject_left = 150;
00750         if (reject_right < 0) reject_right = 150;
00751     
00752     } else {
00753         cpl_msg_error(cpl_func, "Unrecognized mode - abort");
00754         return NULL;
00755     }
00756 
00757     /* Filter the image */
00758     kernel = cpl_mask_new(3, 3);
00759     cpl_mask_not(kernel);
00760     filtered = cpl_image_new(cpl_image_get_size_x(in), cpl_image_get_size_y(in),
00761                              cpl_image_get_type(in));
00762     if (cpl_image_filter_mask(filtered, in, kernel, CPL_FILTER_MEDIAN,
00763                               CPL_BORDER_FILTER)) {
00764         cpl_msg_error(cpl_func, "cannot filter the image");
00765         cpl_mask_delete(kernel);
00766         return NULL;
00767     }
00768     cpl_mask_delete(kernel);
00769 
00770     /* Fill the vector to fit */
00771     nsamples = cpl_image_get_size_x(in) - reject_right - reject_left;
00772     fit_x = cpl_matrix_new(1, nsamples);
00773     pfit_x = cpl_matrix_get_data(fit_x);
00774     fit_y = cpl_vector_new(nsamples);
00775     pfit_y = cpl_vector_get_data(fit_y);
00776     for (i=0; i < nsamples; i++) {
00777         pfit_x[i] = (double)(i+1+reject_left);
00778         pfit_y[i] = cpl_image_get_centroid_y_window(filtered, i+1+reject_left, 
00779                 low_side, i+1+reject_left, up_side);
00780     }
00781     cpl_image_delete(filtered);
00782     
00783     /* Apply the fit */
00784     fitted = cpl_polynomial_new(1);
00785     if (cpl_polynomial_fit(fitted, fit_x, &sampsym, fit_y, NULL, CPL_FALSE,
00786                            NULL, &(isaac_spc_startrace_config.degree))) {
00787         cpl_msg_error(cpl_func, "cannot fit the shape");
00788         cpl_polynomial_delete(fitted);
00789         cpl_matrix_delete(fit_x);
00790         cpl_vector_delete(fit_y);
00791         return NULL;
00792     }
00793 
00794     /* Display if requested */
00795     if (isaac_spc_startrace_config.display) {
00796         cpl_vector * vfit_x
00797             = cpl_vector_wrap(nsamples, pfit_x);
00798         toplot = cpl_bivector_wrap_vectors(vfit_x, fit_y);
00799         cpl_plot_bivector(NULL, NULL, NULL, toplot);
00800         cpl_bivector_unwrap_vectors(toplot);
00801         (void)cpl_vector_unwrap(vfit_x);
00802     }
00803 
00804     cpl_vector_fill_polynomial_fit_residual(fit_y, fit_y, NULL, fitted,
00805                                             fit_x, NULL);
00806     *fit_quality = cpl_vector_product(fit_y, fit_y) / nsamples;
00807 
00808     /* Display if requested */
00809     if (isaac_spc_startrace_config.display) {
00810         cpl_vector * vfit_x
00811             = cpl_vector_wrap(nsamples, pfit_x);
00812         toplot = cpl_bivector_wrap_vectors(vfit_x, fit_y);
00813         for (i=0; i<nsamples; i++) {
00814             pfit_y[i] = cpl_polynomial_eval_1d(fitted, pfit_x[i], NULL);
00815         }
00816         cpl_plot_bivector(NULL, NULL, NULL, toplot);
00817         cpl_bivector_unwrap_vectors(toplot);
00818         (void)cpl_vector_unwrap(vfit_x);
00819     }
00820 
00821     /* Free and return */
00822     cpl_matrix_delete(fit_x);
00823     cpl_vector_delete(fit_y);
00824     return fitted;
00825 }
00826 
00827 /*----------------------------------------------------------------------------*/
00837 /*----------------------------------------------------------------------------*/
00838 static cpl_polynomial * isaac_spc_startrace_distor(
00839         cpl_polynomial  **  shapes,
00840         cpl_vector      *   spec_pos,
00841         int                 nshapes,
00842         int                 nx)
00843 {
00844     cpl_polynomial      *   distor;
00845     cpl_matrix          *   xy_vec;
00846     double              *   x_data;
00847     double              *   y_data;
00848     cpl_vector          *   z_vec;
00849     double              *   z_data;
00850     int                     nb_xpoints, npoints;
00851     int                     pos;
00852     int                     i, j;
00853     const cpl_size          maxdeg = 2;
00854 
00855     /* Initialise */
00856     nb_xpoints = 20;
00857     npoints = nb_xpoints * nshapes;
00858 
00859     /* Prepare the surface */
00860     xy_vec = cpl_matrix_new(2, npoints);
00861     x_data = cpl_matrix_get_data(xy_vec);
00862     y_data = x_data + npoints;
00863     z_vec = cpl_vector_new(npoints);
00864     z_data = cpl_vector_get_data(z_vec);
00865     for (j=0; j<nshapes; j++) {
00866         for (i=0; i<nb_xpoints; i++) {
00867             pos = i + j*nb_xpoints;
00868             x_data[pos] = nx * (i+1) / nb_xpoints;
00869             y_data[pos] = cpl_vector_get(spec_pos, j);
00870             z_data[pos] = cpl_polynomial_eval_1d(shapes[j], x_data[pos], NULL);
00871         }
00872     }
00873     
00874     /* Apply the fit */
00875     distor = cpl_polynomial_new(2);
00876     if (cpl_polynomial_fit(distor, xy_vec, NULL, z_vec, NULL, CPL_FALSE, NULL,
00877                            &maxdeg)) {
00878         cpl_msg_error(cpl_func, "cannot fit the distortion");
00879         cpl_matrix_delete(xy_vec);
00880         cpl_vector_delete(z_vec);
00881         cpl_polynomial_delete(distor);
00882         return NULL;
00883     }
00884     cpl_matrix_delete(xy_vec);
00885     cpl_vector_delete(z_vec);
00886 
00887     return distor;
00888 }
00889 
00890 /*----------------------------------------------------------------------------*/
00904 /*----------------------------------------------------------------------------*/
00905 static
00906 cpl_error_code isaac_spc_startrace_save(cpl_frameset            * set_tot,
00907                                         const cpl_table         * tab,
00908                                         const cpl_matrix        * star_pos,
00909                                         const cpl_vector        * spec_pos,
00910                                         cpl_polynomial         ** shapes,
00911                                         const cpl_frameset      * set,
00912                                         char                      resol,
00913                                         const cpl_parameterlist * parlist)
00914 {
00915     cpl_propertylist    *   plist;
00916     cpl_propertylist    *   qclist;
00917     cpl_propertylist    *   paflist;
00918     const cpl_frame           *   ref_frame;
00919     char                    colname[128];
00920     cpl_table           *   shapes_table;
00921     cpl_table           *   pos_table;
00922     const char          *   procatt;
00923     const char          *   procat;
00924     char                *   filename;
00925     int                     i;
00926 
00927     /* Get the QC params in qclist */
00928     qclist = cpl_propertylist_new();
00929 
00930     /* Add QC parameters */
00931     cpl_propertylist_append_double(qclist, "ESO QC CORR_IS1",
00932             isaac_spc_startrace_config.corr_is1);
00933     cpl_propertylist_append_double(qclist, "ESO QC CORR_IS2",
00934             isaac_spc_startrace_config.corr_is2);
00935     cpl_propertylist_append_double(qclist, "ESO QC CORR_IS3",
00936             isaac_spc_startrace_config.corr_is3);
00937     cpl_propertylist_append_double(qclist, "ESO QC FITMSE",
00938             isaac_spc_startrace_config.shapes_fit_q);
00939     cpl_propertylist_append_double(qclist, "ESO QC DIST1",
00940             isaac_spc_startrace_config.dist1);
00941     cpl_propertylist_append_double(qclist, "ESO QC DISTX",
00942             isaac_spc_startrace_config.distx);
00943     cpl_propertylist_append_double(qclist, "ESO QC DISTY",
00944             isaac_spc_startrace_config.disty);
00945     cpl_propertylist_append_double(qclist, "ESO QC DISTXY",
00946             isaac_spc_startrace_config.distxy);
00947     cpl_propertylist_append_double(qclist, "ESO QC DISTXX",
00948             isaac_spc_startrace_config.distxx);
00949     cpl_propertylist_append_double(qclist, "ESO QC DISTYY",
00950             isaac_spc_startrace_config.distyy);
00951     
00952     /* Write the distortion table  */
00953     procatt = isaac_spc_startrace_config.arm == 1
00954         ? ISAAC_SPC_STARTRACE_SW_RES : ISAAC_SPC_STARTRACE_LW_RES;
00955     filename = cpl_sprintf("isaac_spc_startrace_2dpoly_%cR.fits", resol);
00956     irplib_dfs_save_table(set_tot,
00957             parlist,
00958             set,
00959             tab,
00960             NULL,
00961             "isaac_spc_startrace",
00962             procatt,
00963             qclist,
00964             NULL,
00965             PACKAGE "/" PACKAGE_VERSION,
00966             filename);
00967     cpl_free(filename);
00968 
00969     /* Save the positions table */
00970     pos_table = cpl_table_new(cpl_matrix_get_ncol(star_pos));
00971 
00972     /* star_pos is _not_ modified */
00973     cpl_table_wrap_double(pos_table, cpl_matrix_get_data((cpl_matrix*)star_pos),
00974                           "Star_positions");
00975     /* spec_pos is _not_ modified */
00976     cpl_table_wrap_double(pos_table, cpl_vector_get_data((cpl_vector*)spec_pos),
00977                           "Spec_positions");
00978 
00979     procat = isaac_spc_startrace_config.arm == 1
00980         ? ISAAC_SPC_STARTRACE_SW_POS : ISAAC_SPC_STARTRACE_LW_POS;
00981     filename = cpl_sprintf("isaac_spc_startrace_positions_%cR.fits", resol);
00982     irplib_dfs_save_table(set_tot,
00983             parlist,
00984             set,
00985             tab,
00986             NULL,
00987             "isaac_spc_startrace",
00988             procat,
00989             qclist,
00990             NULL,
00991             PACKAGE "/" PACKAGE_VERSION,
00992             filename);
00993     cpl_free(filename);
00994 
00995     (void)cpl_table_unwrap(pos_table, "Star_positions");
00996     (void)cpl_table_unwrap(pos_table, "Spec_positions");
00997     cpl_table_delete(pos_table);
00998 
00999     /* Save the shapes table */
01000     shapes_table = cpl_table_new(isaac_spc_startrace_config.degree + 1); 
01001     for (i=0; i<cpl_vector_get_size(spec_pos); i++) {
01002         sprintf(colname, "Spec_%d", i+1);
01003         cpl_table_new_column(shapes_table, colname, CPL_TYPE_DOUBLE);
01004     }
01005     for (i=0; i<cpl_vector_get_size(spec_pos); i++) {
01006         cpl_size j;
01007         sprintf(colname, "Spec_%d", i+1);
01008         for (j=0; j<isaac_spc_startrace_config.degree + 1; j++) {
01009             cpl_table_set_double(shapes_table, colname, j, 
01010                     cpl_polynomial_get_coeff(shapes[i], &j));
01011         }
01012     }
01013     procat = isaac_spc_startrace_config.arm == 1 ?
01014         ISAAC_SPC_STARTRACE_SW_SHAPE : ISAAC_SPC_STARTRACE_LW_SHAPE;
01015     filename = cpl_sprintf("isaac_spc_startrace_shapes_%cR.fits", resol);
01016     irplib_dfs_save_table(set_tot,
01017             parlist,
01018             set,
01019             tab,
01020             NULL,
01021             "isaac_spc_startrace",
01022             procat,
01023             qclist,
01024             NULL,
01025             PACKAGE "/" PACKAGE_VERSION,
01026             filename);
01027     cpl_free(filename);
01028     cpl_table_delete(shapes_table);
01029 
01030     /* Get the reference frame */
01031     ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
01032 
01033     /* Get FITS header from reference file */
01034     if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
01035                     0)) == NULL) {
01036         cpl_msg_error(cpl_func, "getting header from reference frame");
01037         cpl_propertylist_delete(qclist);
01038         return -1;
01039     }
01040    
01041     /* Get the keywords for the paf file */
01042     paflist = cpl_propertylist_new();
01043     cpl_propertylist_copy_property_regexp(paflist, plist, 
01044         "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
01045         "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
01046         "ESO OCS SELECT-ARM)$", 0);
01047     cpl_propertylist_delete(plist);
01048 
01049     /* Copy the QC in paflist */
01050     cpl_propertylist_copy_property_regexp(paflist, qclist, "", 0);
01051     cpl_propertylist_delete(qclist);
01052 
01053     /* PRO.CATG */
01054     cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG, procatt);
01055 
01056     /* Save the PAF file */
01057     filename = cpl_sprintf("isaac_spc_startrace_%cR.paf", resol);
01058     cpl_dfs_save_paf("ISAAC",
01059             "isaac_spc_startrace",
01060             paflist,
01061             filename);
01062     cpl_free(filename);
01063     cpl_propertylist_delete(paflist);
01064     return  0;
01065 }
01066 

Generated on Wed Mar 6 08:18:22 2013 for ISAAC Pipeline Reference Manual by  doxygen 1.5.8