UVES Pipeline Reference Manual  5.4.6
uves_physmod_regress_echelle.c
1 /* *
2  * This file is part of the ESO UVES Pipeline *
3  * Copyright (C) 2004,2005 European Southern Observatory *
4  * *
5  * This library is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the Free Software *
17  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
18  * */
19 
20 /*
21  * $Author: amodigli $
22  * $Date: 2011-12-08 14:06:33 $
23  * $Revision: 1.18 $
24  * $Name: not supported by cvs2svn $
25  */
26 
27 /*----------------------------------------------------------------------------*/
31 /*----------------------------------------------------------------------------*/
32 
33 #ifdef HAVE_CONFIG_H
34 # include <config.h>
35 #endif
36 
37 /*-----------------------------------------------------------------------------
38  Includes
39  -----------------------------------------------------------------------------*/
40 #include <uves_physmod_regress_echelle.h>
41 
42 #include <uves_physmod_necregr.h>
43 #include <uves_utils_polynomial.h>
44 #include <uves_utils_wrappers.h>
45 #include <uves_pfits.h>
46 #include <uves_error.h>
47 #include <uves_msg.h>
48 
49 #include <cpl.h>
50 
51 /*-----------------------------------------------------------------------------
52  Defines
53  -----------------------------------------------------------------------------*/
54 #define SELECT_FUNC_DOUBLE cpl_table_and_selected_double
55 #define SELECT_FUNC_INT cpl_table_and_selected_int
56 /* Selected rows are ignored by many CPL functions (unlike MIDAS)
57 Therefore SELECT/TABLE t SELECT.and. ......
58 has different effect from cpl_table_and_selected_double(t, ...)
59 
60 To remove selected rows (which is also not exactly what MIDAS does):
61 #define SELECT_FUNC_DOUBLE uves_extract_table_rows_local
62 #define SELECT_FUNC_INT uves_extract_table_rows_local
63 (but this did not really make a difference)
64 */
66 /*-----------------------------------------------------------------------------
67  Functions prototypes
68  ----------------------------------------------------------------------------*/
69 /*-----------------------------------------------------------------------------
70  Static variables
71  -----------------------------------------------------------------------------*/
72 
73 /*-----------------------------------------------------------------------------
74  Functions code
75  -----------------------------------------------------------------------------*/
76 
77 /*----------------------------------------------------------------------------*/
96 /*----------------------------------------------------------------------------*/
97 
99  enum uves_chip chip,
100  const char *recipe_id,
101  const cpl_parameterlist* parameters,
102  cpl_table** o_tbl,
103  int num_outliers,
104  double tol,
105  double kappa,
106  cpl_table** s_tbl,
107  cpl_table** w_tbl)
108 {
109 
110 
111  int CNT =0;
112  double THRESH=0.;
113  int ORDER=0;
114  float RMSMAX=0.;
115  float RMS=0.;
116  int REJECT[300];
117  int NBREJ=0;
118  double start1=0;
119  double start2=0;
120  double step1=0;
121  double step2=0;
122  int scan1=0;
123  int scan2=0;
124  int naxis1=0;
125  int naxis2=0;
126 
127  int def_pol1=0;
128  int def_pol2=0;
129 
130  double inpr1=0;
131  double inpr2=0;
132  double inpr3=0;
133  char OUTMODE='V';
134  int ECHORD_1=0;
135  int INPUTI_1=0;
136  int INPUTI_2=0;
137  int imsize1=0;
138  int nraw=0;
139  int ord_min=0;
140  int ord_max=0;
141  int status=0;
142  double mean_sq_err_y=0;
143  double outputd[10][10];
144  polynomial* poly2d_y=NULL;
145 
146  uves_propertylist* plist=NULL;
147 
148 
149 
150 
151  check (start1 = uves_pfits_get_crval1(raw_header),
152  "Could not read start factor from input header");
153 
154  check (start2 = uves_pfits_get_crval2(raw_header),
155  "Could not read start factor from input header");
156 
157  check (step1 = uves_pfits_get_cdelt1(raw_header),
158  "Could not read step factor from input header");
159  check (step2 = uves_pfits_get_cdelt2(raw_header),
160  "Could not read step factor from input header");
161 
162  /* AMO */
163  /* here should be arm dependent */
164  check (scan2 = uves_pfits_get_nx(raw_header,chip),
165  "Could not read scan1 factor from input header");
166  check (scan1 = uves_pfits_get_ny(raw_header,chip),
167  "Could not read scan2 factor from input header");
168  /*
169  check (scan2 = uves_pfits_get_out1nx(raw_header),
170  "Could not read scan1 factor from input header");
171 
172  check (scan1 = uves_pfits_get_out1ny(raw_header),
173  "Could not read scan1 factor from input header");
174  */
175  /* scan1 is allways 1 */
176  scan1=1;
177  check (naxis1 = uves_pfits_get_naxis1(raw_header),
178  "Could not read naxis1 from input header");
179  check (naxis2 = uves_pfits_get_naxis2(raw_header),
180  "Could not read naxis2 from input header");
181 
182  uves_msg_debug("start=%f %f step=%f %f naxis=%d %d",
183  start1,start2,step1,step2,naxis1,naxis2);
184 
185  imsize1=naxis2;
186 
187 
188  /* for some reason in MIDAS prg STEP=START */
189  step1=start1;
190  step2=start2;
191 
192 
193  check( uves_get_parameter(parameters, NULL, recipe_id,
194  "def_pol1", CPL_TYPE_INT, &def_pol1 ),
195  "Could not read parameter");
196 
197  check( uves_get_parameter(parameters, NULL, recipe_id,
198  "def_pol2", CPL_TYPE_INT, &def_pol2 ),
199  "Could not read parameter");
200 
201  uves_msg_debug("Polynomial %d %d",def_pol1,def_pol2);
202 
203 
204  uves_msg_debug("Display orders positions...");
205 
206  inpr1 = start1;
207  inpr2 = start1+(imsize1-1)*step1;
208 
209 
210 if (inpr2 < inpr1) {
211  inpr3 = inpr1;
212  inpr1 = inpr2;
213  inpr2 = inpr3;
214 }
215 
216 
217 /* select in the table values which are in the range covered by the
218  actual formatcheck frame */
219  uves_msg_debug("1st select: inputr=%f %f",inpr1,inpr2);
220  uves_msg_debug("ord Xmin=%f Xmax=%f",
221  cpl_table_get_column_min(*o_tbl,"X"),
222  cpl_table_get_column_max(*o_tbl,"X"));
223 
224  check(nraw=SELECT_FUNC_DOUBLE(*o_tbl,"X",CPL_NOT_LESS_THAN,inpr1),"Selection on X failed");
225 
226  uves_msg_debug("nraw=%d",nraw);
227 
228  check(nraw=SELECT_FUNC_DOUBLE(*o_tbl,"X",CPL_NOT_GREATER_THAN,inpr2),"Selection on X failed");
229  uves_msg_debug("nraw=%d",nraw);
230 
231  /* scan1=1, scan2=naxis2*/
232  inpr1 = start2+(scan1-1)*step2;
233  inpr2 = start2+(scan2-1)*step2;
234 
235 
236  if (inpr2 < inpr1) {
237  inpr3 = inpr1;
238  inpr1 = inpr2;
239  inpr2 = inpr3;
240  }
241 
242  uves_msg_debug("2nd select: inputr=%f %f",inpr1,inpr2);
243 
244  check(nraw=SELECT_FUNC_DOUBLE(*o_tbl,"Y",CPL_NOT_LESS_THAN,inpr1),"Selection on Y failed");
245  uves_msg_debug("nraw=%d",nraw);
246 
247  check(nraw=SELECT_FUNC_DOUBLE(*o_tbl,"Y",CPL_NOT_GREATER_THAN,inpr2),"Selection on Y failed");
248  uves_msg_debug("nraw=%d",nraw);
249 
250  /* this table has slightly different values with respect to MIDAS */
251 
252  if(-1 == uves_physmod_necregr(o_tbl,w_tbl)) {
253  uves_msg_error("Error using uves_necregr");
254  return -1;
255  }
256 
257 *s_tbl=cpl_table_duplicate(*w_tbl);
258 
259 
260 /* we sort the table */
261  plist=uves_propertylist_new();
262  uves_propertylist_append_bool(plist,"RMS",0); /* 0 for ascending order */
263  uves_table_sort(*s_tbl,plist);
264  uves_free_propertylist(&plist);
265 
266  ord_min=cpl_table_get_column_min(*o_tbl,"ORDER");
267  ord_max=cpl_table_get_column_max(*o_tbl,"ORDER");
268  ECHORD_1=(ord_max-ord_min+1);
269  ORDER=(ord_max-ord_min+1)/2;
270  ORDER=uves_max_int(1,ORDER);
271 
272 
273 
274  RMSMAX=cpl_table_get_double(*s_tbl,"RMS",ORDER,&status);
275 
276  RMSMAX=3.5*RMSMAX;
277  uves_msg_debug("RMSMAX=%f",RMSMAX);
278  if (RMSMAX < 0.05) RMSMAX = 0.05;
279  uves_msg_debug("RMSMAX=%f",RMSMAX);
280 
281 
282 
283 
284 
285 if( OUTMODE != 'S') {
286  uves_msg("Maximum admissible rms: %f pixels",RMSMAX);
287 }
288 
289 
290  for (ORDER = 0; ORDER<ECHORD_1; ORDER++){
291  RMS = cpl_table_get_double(*w_tbl,"RMS",ORDER,&status);
292  /*
293  uves_msg_debug("RMS=%f",RMS);
294  */
295  if (RMS > RMSMAX){
296  if (OUTMODE != 'S') {
297  uves_msg_warning("Rejected order number %d RMS = %f pixels",ORDER,RMS);
298  }
299  REJECT[NBREJ] = ORDER;
300  NBREJ = NBREJ + 1;
301  }
302 
303 }
304 
305 
306  for(ORDER = 1; ORDER<NBREJ; ORDER++){
307  check(SELECT_FUNC_INT(*o_tbl,"ORDER",
308  CPL_NOT_EQUAL_TO,REJECT[NBREJ]),"Error1 selecting ORDER");
309 
310  }
311  INPUTI_1 = def_pol2 + 1; /* Degree Y + 1 */
312  INPUTI_2 = ECHORD_1 - NBREJ; /* Number of orders minus rejected orders */
313 if (INPUTI_1 > INPUTI_2) {
314  uves_msg("*****************************************************");
315  uves_msg("**** Warning : Number of selected orders {INPUTI(2)}");
316  uves_msg("**** is too small for the current value of echelle");
317  uves_msg("**** parameter DEFPOL(2)=%d", def_pol2);
318  uves_msg("*****************************************************");
319 
320 
321 }
322 
323  check(poly2d_y=uves_polynomial_regression_2d(*o_tbl,"X","ORDER","Y",
324  NULL,def_pol1,def_pol2,"YFIT",
325  NULL,NULL,
326  &mean_sq_err_y,NULL,NULL,-1,-1),
327  "Fitting YFIT failed");
328  cpl_table_set_column_unit(*o_tbl,"YFIT","pix");
329  cpl_table_set_column_unit(*o_tbl,"X","pix");
330  cpl_table_set_column_unit(*o_tbl,"Y","pix");
331 
332  outputd[0][0]=uves_polynomial_get_coeff_2d(poly2d_y,0,0);
333  outputd[1][0]=uves_polynomial_get_coeff_2d(poly2d_y,1,0);
334  outputd[0][1]=uves_polynomial_get_coeff_2d(poly2d_y,0,1);
335  outputd[1][1]=uves_polynomial_get_coeff_2d(poly2d_y,1,1);
336  outputd[2][0]=uves_polynomial_get_coeff_2d(poly2d_y,2,0);
337  outputd[0][2]=uves_polynomial_get_coeff_2d(poly2d_y,0,2);
338  outputd[1][2]=uves_polynomial_get_coeff_2d(poly2d_y,1,2);
339  outputd[2][1]=uves_polynomial_get_coeff_2d(poly2d_y,2,1);
340  outputd[2][2]=uves_polynomial_get_coeff_2d(poly2d_y,2,2);
341 
342  cpl_table_duplicate_column(*o_tbl,"RESIDUAL",*o_tbl,"Y");
343  cpl_table_subtract_columns(*o_tbl,"RESIDUAL","YFIT");
344  cpl_table_set_column_unit(*o_tbl,"RESIDUAL","pix");
345 
346  uves_msg_debug("Error %f",sqrt(mean_sq_err_y));
347  THRESH = kappa * sqrt(mean_sq_err_y);
348  if (THRESH > tol) THRESH = tol;
349 
350  /* do a selection on the absolute value of RESIDUAL */
351  check(SELECT_FUNC_DOUBLE(*o_tbl,"RESIDUAL",
352  CPL_LESS_THAN,THRESH),"Error1 selecting RESIDUAL");
353 
354  check(SELECT_FUNC_DOUBLE(*o_tbl,"RESIDUAL",
355  CPL_GREATER_THAN,-THRESH),"Error2 selecting RESIDUAL");
356 
357  if (num_outliers >= 1)
358  {
359 
360  uves_msg_debug("Kappa-Sigma clipping...");
361  for(CNT = 1; CNT<num_outliers; CNT++) {
362 
363  /*
364  REGRE/POLY {ORDTAB} :Y :X,:ORDER {DEFPOL(1)},{DEFPOL(2)} KEYLONG
365  SAVE/REGR {ORDTAB} COEFF KEYLONG
366  COMPUTE/REGR {ORDTAB} :YFIT = COEFF
367  COMPUTE/TABLE {ORDTAB} :RESIDUAL = :Y - :YFIT;
368  */
369 
370  uves_polynomial_delete(&poly2d_y);
371  check(poly2d_y=uves_polynomial_regression_2d(*o_tbl,"X","ORDER","Y",
372  NULL,def_pol1,def_pol2,"YFIT",
373  NULL,NULL,
374  &mean_sq_err_y,NULL,NULL,-1,-1),
375  "Fitting YFIT failed");
376 
377  if (OUTMODE != 'S') {
378  uves_msg_debug("Ndata = %" CPL_SIZE_FORMAT " - Rms = %f pixels",
379  cpl_table_get_nrow(*o_tbl),sqrt(mean_sq_err_y));
380  }
381 
382  cpl_table_duplicate_column(*o_tbl,"RESIDUAL",*o_tbl,"Y");
383  cpl_table_subtract_columns(*o_tbl,"RESIDUAL","YFIT");
384  uves_msg_debug("error %f",sqrt(mean_sq_err_y));
385  THRESH = kappa * sqrt(mean_sq_err_y);
386  if (THRESH > tol) THRESH = tol;
387  /* do a selection on the absolute value of RESIDUAL */
388  check(SELECT_FUNC_DOUBLE(*o_tbl,"RESIDUAL",
389  CPL_LESS_THAN,THRESH),"Error3 selecting RESIDUAL");
390  check(SELECT_FUNC_DOUBLE(*o_tbl,"RESIDUAL",
391  CPL_GREATER_THAN,-THRESH),"Error4 selecting RESIDUAL");
392 
393  }
394  }
395 
396 
397  cleanup:
398  uves_polynomial_delete(&poly2d_y);
399  uves_free_propertylist(&plist);
400  return 0;
401 
402 }
#define uves_msg_error(...)
Print an error message.
Definition: uves_msg.h:64
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
int uves_pfits_get_nx(const uves_propertylist *plist, enum uves_chip chip)
Find out the OUT1 NX or OUT4 NX.
Definition: uves_pfits.c:2126
#define uves_msg_warning(...)
Print an warning message.
Definition: uves_msg.h:87
int uves_pfits_get_ny(const uves_propertylist *plist, enum uves_chip chip)
Find out the OUT1 NY or OUT4 NY.
Definition: uves_pfits.c:2155
double uves_pfits_get_cdelt2(const uves_propertylist *plist)
Find out the cdelt2.
Definition: uves_pfits.c:2483
int uves_pfits_get_naxis2(const uves_propertylist *plist)
Find out the NAXIS2.
Definition: uves_pfits.c:2375
double uves_polynomial_get_coeff_2d(const polynomial *p, int degree1, int degree2)
Get a coefficient of a 2D polynomial.
uves_propertylist * uves_propertylist_new(void)
Create an empty property list.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
Definition: uves_msg.h:119
polynomial * uves_polynomial_regression_2d(cpl_table *t, const char *X1, const char *X2, const char *Y, const char *sigmaY, int degree1, int degree2, const char *polynomial_fit, const char *residual_square, const char *variance_fit, double *mse, double *red_chisq, polynomial **variance, double kappa, double min_reject)
Fit a 2d polynomial to three table columns.
Definition: uves_utils.c:2869
int uves_physmod_necregr(cpl_table **ord_tbl, cpl_table **reg_tbl)
This procedure does a linear fit of independent orders.
#define uves_msg_debug(...)
Print a debug message.
Definition: uves_msg.h:97
double uves_pfits_get_cdelt1(const uves_propertylist *plist)
Find out the cdelt1.
Definition: uves_pfits.c:2465
double uves_pfits_get_crval1(const uves_propertylist *plist)
Find out the crval1.
Definition: uves_pfits.c:2393
int uves_pfits_get_naxis1(const uves_propertylist *plist)
Find out the NAXIS1.
Definition: uves_pfits.c:2316
#define check(CMD,...)
Definition: uves_error.h:198
double uves_pfits_get_crval2(const uves_propertylist *plist)
Find out the crval2.
Definition: uves_pfits.c:2411
int uves_physmod_regress_echelle(const uves_propertylist *raw_header, enum uves_chip chip, const char *recipe_id, const cpl_parameterlist *parameters, cpl_table **o_tbl, int num_outliers, double tol, double kappa, cpl_table **s_tbl, cpl_table **w_tbl)
Fit mesured position of orders by a bivariate polynomial.