uves_physmod_regress_echelle.c

00001 /*                                                                              *
00002  *   This file is part of the ESO UVES Pipeline                                 *
00003  *   Copyright (C) 2004,2005 European Southern Observatory                      *
00004  *                                                                              *
00005  *   This library is free software; you can redistribute it and/or modify       *
00006  *   it under the terms of the GNU General Public License as published by       *
00007  *   the Free Software Foundation; either version 2 of the License, or          *
00008  *   (at your option) any later version.                                        *
00009  *                                                                              *
00010  *   This program is distributed in the hope that it will be useful,            *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
00013  *   GNU General Public License for more details.                               *
00014  *                                                                              *
00015  *   You should have received a copy of the GNU General Public License          *
00016  *   along with this program; if not, write to the Free Software                *
00017  *   Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA       *
00018  *                                                                              */
00019 
00020 /*
00021  * $Author: amodigli $
00022  * $Date: 2007/06/06 08:17:33 $
00023  * $Revision: 1.13 $
00024  * $Name: uves-3_4_5 $
00025  * $Log: uves_physmod_regress_echelle.c,v $
00026  * Revision 1.13  2007/06/06 08:17:33  amodigli
00027  * replace tab with 4 spaces
00028  *
00029  * Revision 1.12  2007/04/24 12:50:29  jmlarsen
00030  * Replaced cpl_propertylist -> uves_propertylist which is much faster
00031  *
00032  * Revision 1.11  2007/04/10 07:08:50  jmlarsen
00033  * Changed interface of polynomial_regression_2d()
00034  *
00035  * Revision 1.10  2006/11/06 15:19:41  jmlarsen
00036  * Removed unused include directives
00037  *
00038  * Revision 1.9  2006/10/24 14:12:16  jmlarsen
00039  * Parametrized recipe id to support FLAMES recipe
00040  *
00041  * Revision 1.8  2006/10/05 13:07:51  jmlarsen
00042  * Declared parameter list const
00043  *
00044  * Revision 1.7  2006/08/24 06:35:11  amodigli
00045  * fixed doxygen warning
00046  *
00047  * Revision 1.6  2006/08/23 15:41:06  amodigli
00048  * removed warning from checks on line length
00049  *
00050  * Revision 1.5  2006/08/11 14:56:05  amodigli
00051  * removed Doxygen warnings
00052  *
00053  * Revision 1.4  2006/07/14 12:56:57  jmlarsen
00054  * Experimenting with table selection
00055  *
00056  * Revision 1.3  2006/06/20 10:56:56  amodigli
00057  * cleaned output, added units
00058  *
00059  * Revision 1.2  2006/04/06 08:43:31  jmlarsen
00060  * Removed != comparison of strings
00061  *
00062  * Revision 1.1  2006/02/03 07:46:30  jmlarsen
00063  * Moved recipe implementations to ./uves directory
00064  *
00065  * Revision 1.8  2006/01/19 08:47:24  jmlarsen
00066  * Inserted missing doxygen end tag
00067  *
00068  * Revision 1.7  2006/01/16 08:01:57  amodigli
00069  *
00070  * Added stability check
00071  *
00072  * Revision 1.6  2006/01/13 13:43:15  jmlarsen
00073  * Removed memory leak
00074  *
00075  * Revision 1.5  2006/01/09 14:05:42  amodigli
00076  * Fixed doxigen warnings
00077  *
00078  * Revision 1.4  2006/01/05 14:29:59  jmlarsen
00079  * Removed newline characters from output strings
00080  *
00081  * Revision 1.3  2005/12/20 08:11:44  jmlarsen
00082  * Added CVS  entry
00083  *
00084  */
00085 
00086 /*----------------------------------------------------------------------------*/
00090 /*----------------------------------------------------------------------------*/
00091 
00092 #ifdef HAVE_CONFIG_H
00093 #  include <config.h>
00094 #endif
00095 
00096 /*-----------------------------------------------------------------------------
00097                                 Includes
00098  -----------------------------------------------------------------------------*/
00099 #include <uves_physmod_regress_echelle.h>
00100 
00101 #include <uves_physmod_necregr.h>
00102 #include <uves_utils_polynomial.h>
00103 #include <uves_utils_wrappers.h>
00104 #include <uves_pfits.h>
00105 #include <uves_error.h>
00106 #include <uves_msg.h>
00107 
00108 #include <cpl.h>
00109 
00110 /*-----------------------------------------------------------------------------
00111                                 Defines
00112  -----------------------------------------------------------------------------*/
00113 #define SELECT_FUNC_DOUBLE cpl_table_and_selected_double
00114 #define SELECT_FUNC_INT    cpl_table_and_selected_int
00115 /* Selected rows are ignored by many CPL functions (unlike MIDAS)
00116 Therefore SELECT/TABLE t SELECT.and. ...... 
00117 has different effect from cpl_table_and_selected_double(t, ...)
00118 
00119 To remove selected rows (which is also not exactly what MIDAS does):
00120 #define SELECT_FUNC_DOUBLE uves_extract_table_rows_local
00121 #define SELECT_FUNC_INT    uves_extract_table_rows_local
00122 (but this did not really make a difference)
00123 */
00125 /*-----------------------------------------------------------------------------
00126                             Functions prototypes
00127  ----------------------------------------------------------------------------*/
00128 /*-----------------------------------------------------------------------------
00129                             Static variables
00130  -----------------------------------------------------------------------------*/
00131 
00132 /*-----------------------------------------------------------------------------
00133                             Functions code
00134  -----------------------------------------------------------------------------*/
00135 
00136 /*----------------------------------------------------------------------------*/
00155 /*----------------------------------------------------------------------------*/
00156 
00157 int uves_physmod_regress_echelle(const uves_propertylist *raw_header,
00158                  enum uves_chip chip,
00159                  const char *recipe_id,
00160                  const cpl_parameterlist* parameters,
00161                  cpl_table** o_tbl, 
00162                  int num_outliers, 
00163                  double tol, 
00164                  double kappa,
00165                  cpl_table** s_tbl,
00166                  cpl_table** w_tbl)
00167 {
00168 
00169 
00170   int  CNT =0;
00171   double THRESH=0.;
00172   int ORDER=0;
00173   float RMSMAX=0.;
00174   float RMS=0.;
00175   int REJECT[300];
00176   int NBREJ=0;
00177   double start1=0;
00178   double start2=0;
00179   double step1=0;
00180   double step2=0;
00181   int scan1=0;
00182   int scan2=0;
00183   int naxis1=0;
00184   int naxis2=0;
00185 
00186   int def_pol1=0;
00187   int def_pol2=0;
00188 
00189   double inpr1=0;
00190   double inpr2=0;
00191   double inpr3=0;
00192   char OUTMODE='V';
00193   int ECHORD_1=0;
00194   int INPUTI_1=0;
00195   int INPUTI_2=0;
00196   int imsize1=0;
00197   int nraw=0;
00198   int ord_min=0;
00199   int ord_max=0;
00200   int status=0;
00201   double mean_sq_err_y=0;
00202   double outputd[10][10];
00203   polynomial* poly2d_y=NULL;
00204 
00205   uves_propertylist* plist=NULL;
00206 
00207 
00208 
00209 
00210   check (start1 = uves_pfits_get_crval1(raw_header),
00211      "Could not read start factor from input header");
00212 
00213   check (start2 = uves_pfits_get_crval2(raw_header),
00214      "Could not read start factor from input header");
00215   
00216   check (step1 = uves_pfits_get_cdelt1(raw_header),
00217      "Could not read step factor from input header");
00218   check (step2 = uves_pfits_get_cdelt2(raw_header),
00219      "Could not read step factor from input header");
00220   
00221   /* AMO */
00222   /* here should be arm dependent */
00223   check (scan2 = uves_pfits_get_nx(raw_header,chip),
00224      "Could not read scan1 factor from input header");
00225   check (scan1 = uves_pfits_get_ny(raw_header,chip),
00226      "Could not read scan2 factor from input header");
00227   /*
00228   check (scan2 = uves_pfits_get_out1nx(raw_header), 
00229        "Could not read scan1 factor from input header");
00230 
00231   check (scan1 = uves_pfits_get_out1ny(raw_header), 
00232        "Could not read scan1 factor from input header");
00233   */
00234   /* scan1 is allways 1 */
00235   scan1=1;
00236   check (naxis1 = uves_pfits_get_naxis1(raw_header),
00237      "Could not read naxis1 from input header");
00238   check (naxis2 = uves_pfits_get_naxis2(raw_header),
00239      "Could not read naxis2 from input header");
00240 
00241   uves_msg_debug("start=%f %f step=%f %f naxis=%d %d",
00242           start1,start2,step1,step2,naxis1,naxis2);
00243 
00244   imsize1=naxis2;
00245 
00246 
00247   /* for some reason in MIDAS prg STEP=START */
00248   step1=start1;
00249   step2=start2;
00250 
00251 
00252   check( uves_get_parameter(parameters, NULL, recipe_id, 
00253            "def_pol1", CPL_TYPE_INT, &def_pol1 ),
00254        "Could not read parameter");
00255 
00256   check( uves_get_parameter(parameters, NULL, recipe_id, 
00257            "def_pol2", CPL_TYPE_INT, &def_pol2 ),
00258        "Could not read parameter");
00259 
00260   uves_msg_debug("Polynomial %d %d",def_pol1,def_pol2);
00261 
00262 
00263   uves_msg_debug("Display orders positions...");
00264 
00265   inpr1 = start1;
00266   inpr2 = start1+(imsize1-1)*step1;
00267  
00268 
00269 if (inpr2 < inpr1) { 
00270   inpr3 = inpr1;
00271   inpr1 = inpr2;
00272   inpr2 = inpr3;
00273 }
00274 
00275 
00276 /* select in the table values which are in the range covered by the
00277    actual formatcheck frame */
00278   uves_msg_debug("1st select: inputr=%f %f",inpr1,inpr2);
00279   uves_msg_debug("ord Xmin=%f Xmax=%f",
00280           cpl_table_get_column_min(*o_tbl,"X"),
00281       cpl_table_get_column_max(*o_tbl,"X"));
00282 
00283   check(nraw=SELECT_FUNC_DOUBLE(*o_tbl,"X",CPL_NOT_LESS_THAN,inpr1),"Selection on X failed");
00284 
00285   uves_msg_debug("nraw=%d",nraw);
00286 
00287   check(nraw=SELECT_FUNC_DOUBLE(*o_tbl,"X",CPL_NOT_GREATER_THAN,inpr2),"Selection on X failed");
00288   uves_msg_debug("nraw=%d",nraw);
00289 
00290   /* scan1=1, scan2=naxis2*/
00291   inpr1 = start2+(scan1-1)*step2;
00292   inpr2 = start2+(scan2-1)*step2;
00293 
00294   
00295   if (inpr2 < inpr1) {
00296     inpr3 = inpr1;
00297     inpr1 = inpr2;
00298     inpr2 = inpr3;
00299   }
00300 
00301   uves_msg_debug("2nd select: inputr=%f %f",inpr1,inpr2);
00302 
00303   check(nraw=SELECT_FUNC_DOUBLE(*o_tbl,"Y",CPL_NOT_LESS_THAN,inpr1),"Selection on Y failed");
00304   uves_msg_debug("nraw=%d",nraw);
00305 
00306   check(nraw=SELECT_FUNC_DOUBLE(*o_tbl,"Y",CPL_NOT_GREATER_THAN,inpr2),"Selection on Y failed");
00307   uves_msg_debug("nraw=%d",nraw);
00308 
00309   /* this table has slightly different values with respect to MIDAS */
00310   
00311   if(-1 == uves_physmod_necregr(o_tbl,w_tbl)) {
00312     uves_msg_error("Error using uves_necregr");
00313     return -1;
00314   }
00315 
00316 *s_tbl=cpl_table_duplicate(*w_tbl);
00317 
00318 
00319 /* we sort the table */
00320   plist=uves_propertylist_new();
00321   uves_propertylist_append_bool(plist,"RMS",0);  /* 0 for ascending order */
00322   uves_table_sort(*s_tbl,plist);
00323   uves_free_propertylist(&plist);
00324 
00325   ord_min=cpl_table_get_column_min(*o_tbl,"ORDER");
00326   ord_max=cpl_table_get_column_max(*o_tbl,"ORDER");
00327   ECHORD_1=(ord_max-ord_min+1);
00328   ORDER=(ord_max-ord_min+1)/2;
00329   ORDER=uves_max_int(1,ORDER);
00330 
00331 
00332 
00333   RMSMAX=cpl_table_get_double(*s_tbl,"RMS",ORDER,&status);
00334 
00335   RMSMAX=3.5*RMSMAX;
00336   uves_msg_debug("RMSMAX=%f",RMSMAX);
00337  if (RMSMAX < 0.05)  RMSMAX = 0.05;
00338   uves_msg_debug("RMSMAX=%f",RMSMAX);
00339  
00340 
00341 
00342 
00343 
00344 if( OUTMODE != 'S') {
00345   uves_msg("Maximum admissible rms: %f pixels",RMSMAX);
00346 }
00347 
00348  
00349  for (ORDER = 0; ORDER<ECHORD_1; ORDER++){
00350  RMS = cpl_table_get_double(*w_tbl,"RMS",ORDER,&status);
00351  /*
00352  uves_msg_debug("RMS=%f",RMS);
00353  */
00354  if (RMS > RMSMAX){ 
00355    if (OUTMODE != 'S') {
00356      uves_msg_warning("Rejected order number %d RMS = %f pixels",ORDER,RMS);
00357    }
00358    REJECT[NBREJ] = ORDER;
00359    NBREJ = NBREJ + 1;
00360  }
00361 
00362 }
00363 
00364 
00365    for(ORDER = 1; ORDER<NBREJ; ORDER++){
00366        check(SELECT_FUNC_INT(*o_tbl,"ORDER",
00367          CPL_NOT_EQUAL_TO,REJECT[NBREJ]),"Error1 selecting ORDER");
00368 
00369    }
00370   INPUTI_1 = def_pol2 + 1;      /* Degree Y + 1 */
00371   INPUTI_2 = ECHORD_1 - NBREJ;  /* Number of orders minus rejected orders */
00372 if (INPUTI_1 > INPUTI_2) {
00373   uves_msg("*****************************************************");
00374   uves_msg("**** Warning : Number of selected orders {INPUTI(2)}");
00375   uves_msg("**** is too small for the current value of echelle");
00376   uves_msg("**** parameter DEFPOL(2)=%d", def_pol2);
00377   uves_msg("*****************************************************");
00378 
00379 
00380 }
00381 
00382   check(poly2d_y=uves_polynomial_regression_2d(*o_tbl,"X","ORDER","Y",
00383                          NULL,def_pol1,def_pol2,"YFIT",
00384                                              NULL,NULL,
00385                          &mean_sq_err_y,NULL,NULL,-1,-1),
00386                                          "Fitting YFIT failed");
00387 
00388   outputd[0][0]=uves_polynomial_get_coeff_2d(poly2d_y,0,0);
00389   outputd[1][0]=uves_polynomial_get_coeff_2d(poly2d_y,1,0);
00390   outputd[0][1]=uves_polynomial_get_coeff_2d(poly2d_y,0,1);
00391   outputd[1][1]=uves_polynomial_get_coeff_2d(poly2d_y,1,1);
00392   outputd[2][0]=uves_polynomial_get_coeff_2d(poly2d_y,2,0);
00393   outputd[0][2]=uves_polynomial_get_coeff_2d(poly2d_y,0,2);
00394   outputd[1][2]=uves_polynomial_get_coeff_2d(poly2d_y,1,2);
00395   outputd[2][1]=uves_polynomial_get_coeff_2d(poly2d_y,2,1);
00396   outputd[2][2]=uves_polynomial_get_coeff_2d(poly2d_y,2,2);
00397 
00398   cpl_table_duplicate_column(*o_tbl,"RESIDUAL",*o_tbl,"Y");
00399   cpl_table_subtract_columns(*o_tbl,"RESIDUAL","YFIT");
00400 
00401    uves_msg_debug("Error %f",sqrt(mean_sq_err_y));
00402   THRESH = kappa * sqrt(mean_sq_err_y);
00403   if (THRESH > tol)   THRESH = tol;
00404 
00405   /* do a selection on the absolute value of RESIDUAL */
00406   check(SELECT_FUNC_DOUBLE(*o_tbl,"RESIDUAL",
00407          CPL_LESS_THAN,THRESH),"Error1 selecting RESIDUAL");
00408 
00409   check(SELECT_FUNC_DOUBLE(*o_tbl,"RESIDUAL",
00410          CPL_GREATER_THAN,-THRESH),"Error2 selecting RESIDUAL");
00411 
00412   if (num_outliers >= 1)
00413       {
00414   
00415       uves_msg_debug("Kappa-Sigma clipping...");
00416       for(CNT = 1; CNT<num_outliers; CNT++) {
00417       
00418           /*
00419         REGRE/POLY  {ORDTAB} :Y :X,:ORDER {DEFPOL(1)},{DEFPOL(2)}  KEYLONG 
00420         SAVE/REGR   {ORDTAB} COEFF   KEYLONG
00421         COMPUTE/REGR   {ORDTAB} :YFIT = COEFF 
00422         COMPUTE/TABLE    {ORDTAB} :RESIDUAL = :Y - :YFIT;
00423           */
00424           
00425           uves_polynomial_delete(&poly2d_y);
00426           check(poly2d_y=uves_polynomial_regression_2d(*o_tbl,"X","ORDER","Y",
00427                                NULL,def_pol1,def_pol2,"YFIT",
00428                                NULL,NULL,
00429                                &mean_sq_err_y,NULL,NULL,-1,-1),
00430             "Fitting YFIT failed");
00431           
00432           if (OUTMODE != 'S') {
00433           uves_msg_debug("Ndata = %d - Rms = %f pixels",
00434                cpl_table_get_nrow(*o_tbl),sqrt(mean_sq_err_y));
00435           }
00436           
00437           cpl_table_duplicate_column(*o_tbl,"RESIDUAL",*o_tbl,"Y");
00438           cpl_table_subtract_columns(*o_tbl,"RESIDUAL","YFIT");
00439           uves_msg_debug("error %f",sqrt(mean_sq_err_y));
00440           THRESH = kappa * sqrt(mean_sq_err_y);
00441           if (THRESH > tol)   THRESH = tol;
00442           /* do a selection on the absolute value of RESIDUAL */
00443           check(SELECT_FUNC_DOUBLE(*o_tbl,"RESIDUAL",
00444           CPL_LESS_THAN,THRESH),"Error3 selecting RESIDUAL");
00445           check(SELECT_FUNC_DOUBLE(*o_tbl,"RESIDUAL",
00446           CPL_GREATER_THAN,-THRESH),"Error4 selecting RESIDUAL");
00447           
00448       }
00449       }
00450 
00451 
00452   cleanup:
00453   uves_polynomial_delete(&poly2d_y);
00454   uves_free_propertylist(&plist);
00455   return 0;
00456 
00457 }

Generated on Thu Nov 15 14:32:29 2007 for UVES Pipeline Reference Manual by  doxygen 1.5.1