SINFONI Pipeline Reference Manual  2.5.2
sinfo_new_find_distortions.c
1 /*
2  * This file is part of the ESO SINFONI Pipeline
3  * Copyright (C) 2004,2005 European Southern Observatory
4  *
5  * This program 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  File name : sinfo_find_distortions.c
22  Author : A. Modigliani
23  Created on : Aug 12, 2004
24  Description :
25 
26  ---------------------------------------------------------------------------*/
27 #ifdef HAVE_CONFIG_H
28 # include <config.h>
29 #endif
30 #include <sinfo_cpl_size.h>
31 
32 /*----------------------------------------------------------------------------
33  Includes
34  ---------------------------------------------------------------------------*/
35 
36 #include "sinfo_new_find_distortions.h"
37 #include "sinfo_pro_save.h"
38 #include "sinfo_pro_types.h"
39 #include "sinfo_finddist_ini_by_cpl.h"
40 #include "sinfo_wave_calibration.h"
41 #include "sinfo_cube_construct.h"
42 #include "sinfo_absolute.h"
43 #include "sinfo_distortion.h"
44 #include "sinfo_utilities.h"
45 #include "sinfo_recipes.h"
46 #include "sinfo_utils_wrappers.h"
47 #include "sinfo_error.h"
48 #include "sinfo_globals.h"
49 
50 /*----------------------------------------------------------------------------
51  Defines
52  ---------------------------------------------------------------------------*/
53 #define SINFO_ARC_SATURATION 100000
54 #define SINFO_ARC_MAX_WIDTH 64
55 
56 
65 /*----------------------------------------------------------------------------
66  Function Definitions
67  ---------------------------------------------------------------------------*/
68 
69 /*----------------------------------------------------------------------------
70  Function : sinfo_find_distortions()
71  In :
72  Out :
73  Job :
74 
75  ---------------------------------------------------------------------------*/
76 static double
77 new_compute_shift(double x,
78  double y,
79  double c00,
80  double c10,
81  double c01,
82  double c11,
83  double c20,
84  double c02,
85  double c21,
86  double c12,
87  double c30,
88  double c03);
89 
90 int
91 sinfo_new_find_distortions(const char* plugin_id,
92  cpl_parameterlist* config,
93  cpl_frameset* sof,
94  cpl_frameset* set_fibre_ns)
95 {
96 
97  finddist_config * cfg=NULL ;
98  cpl_image * imonind=NULL ;
99  cpl_image * impoly=NULL ;
100  cpl_image * im=NULL ;
101  cpl_image * map=NULL ;
102  cpl_image * mask=NULL ;
103 
104  int* degx=NULL;
105  int* degy=NULL;
106  int* n_found_lines=NULL;
107  int* sum_pointer=NULL;
108  int** row_clean=NULL;
109  int pdensity=0;
110 
111 
112  int x_l=SIZEX/4*1;
113  int x_u=SIZEX/4*3;
114  int y_l=SIZEY/4*1;
115  int y_u=SIZEY/4*3;
116  int x_c=SIZEX/4*2;
117  int y_c=SIZEY/4*2;
118  const int pdx=4;
119  const int pdy=4;
120  int check = 0;
121  int i = 0;
122  int lx=0;
123  //int ly=0;
124 
125 
126  int sum=0;
127  int n_lines=0;
128  int fit=0;
129  int n=0;
130  int j=0;
131  cpl_size coef_pow[2];
132  int arcs_window_size=0;
133 
134  float value=0;
135  float newval=0;
136  float total_dist=0;
137  float shift=0;
138 
139  float* distances=NULL;
140  float** wavelength_clean=NULL;
141  float** slit_pos=NULL;
142  float** acoefs=NULL;
143  float* wave=NULL;
144  float* intens=NULL;
145  float* first =NULL;
146 
147  double* coef=NULL;
148 
149  double xshift=0.;
150  double arcs_thres_factor=0;
151 
152  double arcs_min_arclen_factor=0;
153  double pcf[pdx][pdy];
154 
155 
156  char tbl_name[FILE_NAME_SZ];
157  char key_name[FILE_NAME_SZ];
158 
159  cpl_table* poly_tbl=NULL;
160  cpl_table* tbl_spos=NULL;
161  cpl_table* tbl_line_list=NULL;
162 
163  FitParams** par=NULL;
164 
165  cpl_frameset* stk=NULL;
166  cpl_table* qclog_tbl=NULL;
167 
168  cpl_polynomial* distor_poly=NULL;
169  cpl_apertures * arcs=NULL ;
170  cpl_parameter* p=NULL;
171  int smooth_rad=0;
172 
173 
174  check_nomsg(p=cpl_parameterlist_find(config,"sinfoni.product.density"));
175  check_nomsg(pdensity=cpl_parameter_get_int(p));
176 
177  /*
178  parse the file names and parameters to the finddist_config
179  data structure cfg
180  */
181  check_nomsg(stk=cpl_frameset_new());
182  cknull(cfg = sinfo_parse_cpl_input_finddist(config,sof,&stk),
183  "could not parse CPL input!");
184 
185  if(sinfo_is_fits_file (cfg->inFrame) != 1) {
186  sinfo_msg_error("Input file %s is not FITS",cfg->inFrame);
187  goto cleanup;
188  }
189 
190  /* load the emission line frame--- */
191  check(im = cpl_image_load(cfg->inFrame,CPL_TYPE_FLOAT,0,0),
192  "could not load arc image");
193 
194  /* load the fake on - fake off frame--- */
195  check(imonind = cpl_image_load(cfg->nsFrame,CPL_TYPE_FLOAT,0,0),
196  "could not load on-off fake image");
197 
198  check(impoly = cpl_image_load(cfg->nsFrame,CPL_TYPE_FLOAT,0,0),
199  "could not load on-off fake image");
200 
201  /* load the fake on - fake off frame--- */
202  check(mask = cpl_image_load(cfg->mask,CPL_TYPE_FLOAT,0,0),
203  "could not load mask image");
204 
205  check(cpl_image_multiply (im,mask),
206  "Failing to correct arc ima by bp mask");
207 
208  check(cpl_image_multiply (imonind,mask),
209  "Failing to correct on-off fake ima by bp mask");
210 
211  check(cpl_image_multiply(impoly,mask),
212  "Failing to correct on-off fake ima by bp mask");
213 
214  sinfo_free_image(&mask);
215 
216  check_nomsg(lx = cpl_image_get_size_x(im));
217  //check_nomsg(ly = cpl_image_get_size_y(im));
218  /* TO BE CHENGED THE FOLLOWING INPUT */
219  /* open the line list and read the number of lines */
220  check(tbl_line_list = cpl_table_load(cfg->lineList,1,0),
221  "problems loading table %s",cfg->lineList);
222 
223  check_nomsg(n_lines = cpl_table_get_nrow(tbl_line_list));
224  check_nomsg(wave=cpl_table_get_data_float(tbl_line_list,"wave"));
225  cpl_type type=cpl_table_get_column_type(tbl_line_list,"int");
226  if(type==CPL_TYPE_INT) {
227  check_nomsg(cpl_table_cast_column(tbl_line_list,"int", "fint",CPL_TYPE_FLOAT));
228  check_nomsg(intens = cpl_table_get_data_float(tbl_line_list,"fint"));
229  } else {
230  check_nomsg(intens = cpl_table_get_data_float(tbl_line_list,"int"));
231  }
232  /*
233  #---------------------------------------------------------------------
234  #---------------------------FINDLINES---------------------------------
235  #---------------------------------------------------------------------
236  */
237 
238  sinfo_msg("Find Lines");
239  /*
240  do the wavelength calibration, that means:
241  find the dispersion relation and parameterize its coefficients
242  */
243 
244  acoefs = sinfo_new_2Dfloatarray(cfg->nrDispCoefficients, lx);
245  /* allocate memory */
246  n_found_lines = sinfo_new_intarray(lx);
247  row_clean = sinfo_new_2Dintarray(lx, n_lines);
248  wavelength_clean = sinfo_new_2Dfloatarray(lx, n_lines);
249  sum_pointer = sinfo_new_intarray(1);
250 
251  /* find the emission lines in each image column */
252  sinfo_new_intarray_set_value(sum_pointer, 0, 0);
253 
254  ck0(check = sinfo_new_find_lines(im,
255  wave,
256  intens,
257  n_lines,
258  row_clean,
259  wavelength_clean,
260  cfg->guessBeginWavelength,
261  cfg->guessDispersion1,
262  cfg->guessDispersion2,
263  cfg->mindiff,
264  cfg->halfWidth,
265  n_found_lines,
266  cfg->sigma,
267  sum_pointer ),
268  "FindLines failed!");
269 
270  sinfo_free_table(&tbl_line_list);
271 
272  /*
273  #-------------------------------------------------------------------------
274  #---------------------------WAVECALIB-------------------------------------
275  #-------------------------------------------------------------------------
276  */
277  sinfo_msg("Do wave calib");
278  sum = sinfo_new_intarray_get_value(sum_pointer,0);
279 
280  /* #allocate memory for the fit parameters */
281  cknull(par = sinfo_new_fit_params( sum ),
282  "sinfo_new_fit_params failed!");
283 
284  /*
285  fit each line, make a polynomial fit and fit the resulting fit
286  coefficients across the columns of the slitlet
287  */
288  cknull(map = sinfo_new_wave_cal(im,
289  par,
290  acoefs,
291  cfg->nslitlets,
292  row_clean,
293  wavelength_clean,
294  n_found_lines,
295  cfg->guessDispersion1,
296  cfg->halfWidth,
297  cfg->minAmplitude,
298  cfg->maxResidual,
299  cfg->fwhm,
300  cfg->nrDispCoefficients,
301  cfg->nrCoefCoefficients,
302  cfg->sigmaFactor,
303  cfg->pixeldist,
304  cfg->pixel_tolerance),
305  "sinfo_waveCal failed!");
306  /* here mem leak */
307 
308  sinfo_msg("Check line positions");
309  shift = sinfo_new_check_line_positions (im, acoefs,
310  cfg->nrDispCoefficients,
311  cfg->guessDispersion1,par);
312 
313  if (FLAG == shift) {
314  sinfo_msg_error ( "checkForLinePositions failed!");
315  goto cleanup;
316  }
317  sinfo_free_image(&map);
318 
319 
320  /* free memory */
321  sinfo_new_destroy_2Dfloatarray ( &wavelength_clean, lx );
322  sinfo_new_destroy_2Dintarray (&row_clean, lx);
323  sinfo_new_destroy_intarray(&n_found_lines );
324  sinfo_new_destroy_intarray(&sum_pointer );
325  sinfo_new_destroy_2Dfloatarray ( &acoefs, cfg->nrDispCoefficients );
326  /*
327  sinfo_new_destroy_array (& wave );
328  sinfo_new_destroy_array (& intens );
329  */
330  /*
331  #----------------------------------------------------------------------------
332  #-------------------------SLITFITS-------------------------------------------
333  #----------------------------------------------------------------------------
334  #--fit the slitlet sinfo_edge positions if desired--
335  */
336 
337  sinfo_msg("Find slit pos");
338  /*allocate memory for the slitlet position array */
339  slit_pos = sinfo_new_2Dfloatarray(32,2);
340 
341  fit = sinfo_new_fit_slits_boltz( im, par, slit_pos, cfg->boxLength,
342  cfg->yBox, cfg->diffTol );
343 
344 
345  if (fit < 0) {
346  sinfo_msg_error( "sinfo_fitSlitsBoltz failed" );
347  goto cleanup;
348  }
349  sinfo_new_destroy_fit_params(&par);
350 
351  check_nomsg(tbl_spos=cpl_table_new(32));
352  check_nomsg(cpl_table_new_column(tbl_spos,"pos1", CPL_TYPE_DOUBLE));
353  check_nomsg(cpl_table_new_column(tbl_spos,"pos2", CPL_TYPE_DOUBLE));
354  check_nomsg(cpl_table_set_column_format(tbl_spos,"pos1", "15.9f"));
355  check_nomsg(cpl_table_set_column_format(tbl_spos,"pos2", "15.9f"));
356 
357  for (i =0; i< 32; i++) {
358  check_nomsg(cpl_table_set_double(tbl_spos,"pos1",i,
359  sinfo_new_array2D_get_value(slit_pos,i,0)));
360  check_nomsg(cpl_table_set_double(tbl_spos,"pos2",i,
361  sinfo_new_array2D_get_value(slit_pos,i,1)));
362 
363  }
364 
365  if(pdensity > 2) {
366  strcpy(tbl_name,"out_slitlets_pos_predist.fits");
367  ck0(sinfo_pro_save_tbl(tbl_spos,set_fibre_ns,sof,tbl_name,
368  PRO_SLITLETS_POS_PREDIST,NULL,plugin_id,config),
369  "cannot save tbl %s", tbl_name);
370  }
371  sinfo_free_table(&tbl_spos);
372 
373  /*
374  #---------------------------------------------------------
375  # do the north - south - test
376  #---------------------------------------------------------
377  */
378  sinfo_msg("Do north south test");
379  /*
380  sinfo_msg("cfg->nslits =%d\n", cfg->nslits);
381  sinfo_msg("cfg->nshalfWidth =%d\n", cfg->nshalfWidth);
382  sinfo_msg("cfg->nsfwhm=%f\n",cfg->nsfwhm );
383  sinfo_msg("cfg->minDiff=%f\n", cfg->minDiff);
384  sinfo_msg("cfg->estimated_dist=%f\n", cfg->estimated_dist);
385  sinfo_msg("cfg->devtol=%f\n", cfg->devtol);
386  sinfo_msg("cfg->loPos=%d\n", cfg->loPos);
387  sinfo_msg("cfg->hiPos=%d\n",cfg->hiPos);
388  */
389  cknull(distances = sinfo_north_south_test(imonind,
390  cfg->nslits,
391  cfg->nshalfWidth,
392  cfg->nsfwhm ,
393  cfg->minDiff,
394  cfg->estimated_dist,
395  cfg->devtol,
396  cfg->loPos,
397  cfg->hiPos),
398  "north_south_test failed");
399 
400  sinfo_free_image(&imonind);
401 
402  /*
403  #---------------------------------------------------------
404  # get firstcol
405  #---------------------------------------------------------
406  */
407  sinfo_msg("get first col");
408  first = sinfo_new_floatarray(61);
409  total_dist=0;
410  n=0;
411 
412  for (i=0; i< 31; i++) {
413  total_dist=total_dist+sinfo_new_array_get_value(distances,i);
414 
415  for (j=0; j< 2; j++) {
416  if (j == 0) {
417  if (i != 30) {
418  newval = sinfo_new_array2D_get_value(slit_pos,i+1,j) -
419  total_dist;
420  sinfo_new_array_set_value(first, newval, n);
421  n = n+1;
422  }
423  }
424  if (j == 1) {
425  newval = sinfo_new_array2D_get_value(slit_pos,i,j) - total_dist;
426  sinfo_new_array_set_value(first, newval, n);
427  n = n+1;
428  }
429  }
430  }
431  value = sinfo_new_f_median(first,61);
432  sinfo_msg("Firstcol =%f", value);
433  sinfo_new_destroy_array(&first);
434  sinfo_new_destroy_array(&distances);
435  sinfo_new_destroy_2Dfloatarray ( &slit_pos, 32 );
436 
437  /*
438  #---------------------------------------------------------
439  # Determine distortions
440  #---------------------------------------------------------
441  */
442  sinfo_msg("Determine distortions");
443  degx=cpl_calloc(8,sizeof(int));
444  degy=cpl_calloc(8,sizeof(int));
445  coef=cpl_calloc(8,sizeof(double));
446 
447  check_nomsg(p=cpl_parameterlist_find(config,
448  "sinfoni.distortion.arcs_thresh_factor"));
449  check_nomsg(arcs_thres_factor=cpl_parameter_get_double(p));
450 
451  check_nomsg(p=cpl_parameterlist_find(config,
452  "sinfoni.distortion.arcs_min_arclen_factor"));
453  check_nomsg(arcs_min_arclen_factor=cpl_parameter_get_double(p));
454 
455  check_nomsg(p=cpl_parameterlist_find(config,
456  "sinfoni.distortion.arcs_window_size"));
457  check_nomsg(arcs_window_size=cpl_parameter_get_int(p));
458 
459  check_nomsg(p=cpl_parameterlist_find(config,
460  "sinfoni.distortion.smooth_rad"));
461  check_nomsg(smooth_rad=cpl_parameter_get_int(p));
462 
463 
464  cknull(distor_poly=sinfo_distortion_estimate_new(impoly,
465  0,
466  0,
467  cpl_image_get_size_x(impoly),
468  cpl_image_get_size_y(impoly),
469  FALSE,
470  SINFO_ARC_SATURATION,
471  SINFO_ARC_MAX_WIDTH,
472  arcs_thres_factor,
473  arcs_min_arclen_factor,
474  arcs_window_size,
475  smooth_rad,
476  3,
477  (double)value,
478  &arcs),
479  "cannot estimage distortion") ;
480  /*AMo: additional mem leaks */
481 
482  sinfo_free_apertures(&arcs);
483  coef_pow[0]=0;
484  coef_pow[1]=0;
485  check_nomsg(pcf[0][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
486  sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",0,0,pcf[0][0]);
487  /*
488  pcf[0][0]+=value;
489  */
490  sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",0,0,pcf[0][0]);
491  check_nomsg(cpl_polynomial_set_coeff(distor_poly,coef_pow,pcf[0][0]));
492 
493  /* up to here ok */
494  /* To check mem leaks */
495  sinfo_free_image(&impoly);
496 
497  //sinfo_msg("Polynomial fit results: deg=%d",
498  // cpl_polynomial_get_degree(distor_poly));
499 
500 
501  coef_pow[0]=0;
502  coef_pow[1]=0;
503  check_nomsg(pcf[0][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
504  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",0,0,pcf[0][0]);
505 
506  coef_pow[0]=1;
507  coef_pow[1]=0;
508  check_nomsg(pcf[1][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
509  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",1,0,pcf[1][0]);
510 
511  coef_pow[0]=0;
512  coef_pow[1]=1;
513  check_nomsg(pcf[0][1]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
514  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",0,1,pcf[0][1]);
515 
516  coef_pow[0]=1;
517  coef_pow[1]=1;
518  check_nomsg(pcf[1][1]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
519  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",1,1,pcf[1][1]);
520 
521  coef_pow[0]=2;
522  coef_pow[1]=0;
523  check_nomsg(pcf[2][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
524  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",2,0,pcf[2][0]);
525 
526  coef_pow[0]=0;
527  coef_pow[1]=2;
528  check_nomsg(pcf[0][2]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
529  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",0,2,pcf[0][2]);
530 
531  coef_pow[0]=2;
532  coef_pow[1]=1;
533  check_nomsg(pcf[2][1]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
534  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",2,1,pcf[2][1]);
535 
536  coef_pow[0]=1;
537  coef_pow[1]=2;
538  check_nomsg(pcf[1][2]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
539  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",1,2,pcf[1][2]);
540 
541  coef_pow[0]=3;
542  coef_pow[1]=0;
543  check_nomsg(pcf[3][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
544  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",3,0,pcf[3][0]);
545 
546  coef_pow[0]=0;
547  coef_pow[1]=3;
548  check_nomsg(pcf[0][3]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
549  //sinfo_msg("Polynomial fit results: coeff[%d][%d]=%g",0,3,pcf[0][3]);
550 
551  sinfo_msg("Save results");
552 
553  check_nomsg(poly_tbl=cpl_table_new(10));
554  check_nomsg(cpl_table_new_column(poly_tbl,"degx", CPL_TYPE_INT));
555  check_nomsg(cpl_table_new_column(poly_tbl,"degy", CPL_TYPE_INT));
556  check_nomsg(cpl_table_new_column(poly_tbl,"coeff", CPL_TYPE_DOUBLE));
557  check_nomsg(cpl_table_set_int(poly_tbl,"degx",0,0));
558  check_nomsg(cpl_table_set_int(poly_tbl,"degx",1,1));
559  check_nomsg(cpl_table_set_int(poly_tbl,"degx",2,0));
560  check_nomsg(cpl_table_set_int(poly_tbl,"degx",3,1));
561  check_nomsg(cpl_table_set_int(poly_tbl,"degx",4,2));
562  check_nomsg(cpl_table_set_int(poly_tbl,"degx",5,0));
563  check_nomsg(cpl_table_set_int(poly_tbl,"degx",6,2));
564  check_nomsg(cpl_table_set_int(poly_tbl,"degx",7,1));
565  check_nomsg(cpl_table_set_int(poly_tbl,"degx",8,3));
566  check_nomsg(cpl_table_set_int(poly_tbl,"degx",9,0));
567 
568  check_nomsg(cpl_table_set_int(poly_tbl,"degy",0,0));
569  check_nomsg(cpl_table_set_int(poly_tbl,"degy",1,0));
570  check_nomsg(cpl_table_set_int(poly_tbl,"degy",2,1));
571  check_nomsg(cpl_table_set_int(poly_tbl,"degy",3,1));
572  check_nomsg(cpl_table_set_int(poly_tbl,"degy",4,0));
573  check_nomsg(cpl_table_set_int(poly_tbl,"degy",5,2));
574  check_nomsg(cpl_table_set_int(poly_tbl,"degy",6,1));
575  check_nomsg(cpl_table_set_int(poly_tbl,"degy",7,2));
576  check_nomsg(cpl_table_set_int(poly_tbl,"degy",8,0));
577  check_nomsg(cpl_table_set_int(poly_tbl,"degy",9,3));
578 
579  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",0,pcf[0][0]));
580  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",1,pcf[1][0]));
581  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",2,pcf[0][1]));
582  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",3,pcf[1][1]));
583  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",4,pcf[2][0]));
584  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",5,pcf[0][2]));
585  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",6,pcf[2][1]));
586  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",7,pcf[1][2]));
587  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",8,pcf[3][0]));
588  check_nomsg(cpl_table_set_double(poly_tbl,"coeff",9,pcf[0][3]));
589 
590  //sinfo_msg("Polynomial distortion coefficients \n");
591  //sinfo_msg("c= %g %g %g %g %g %g %g %g %g %g\n",
592  // pcf[0][0],pcf[1][0],pcf[0][1],pcf[1][1],
593  // pcf[2][0],pcf[0][2],pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
594 
595  /* QC LOG */
596  check_nomsg(qclog_tbl = sinfo_qclog_init());
597  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",0,0);
598  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[0][0],
599  "Polynomial distortion coefficient","%g"));
600 
601  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",1,0);
602  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[1][0],
603  "Polynomial distortion coefficient","%g"));
604 
605  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",0,1);
606  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[0][1],
607  "Polynomial distortion coefficient","%g"));
608 
609  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",1,1);
610  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[1][1],
611  "Polynomial distortion coefficient","%g"));
612 
613  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",2,0);
614  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[2][0],
615  "Polynomial distortion coefficient","%g"));
616 
617  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",0,2);
618  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[0][2],
619  "Polynomial distortion coefficient","%g"));
620 
621  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",2,1);
622  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[2][1],
623  "Polynomial distortion coefficient","%g"));
624 
625  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",1,2);
626  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[1][2],
627  "Polynomial distortion coefficient","%g"));
628 
629  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",3,0);
630  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[3][0],
631  "Polynomial distortion coefficient","%g"));
632 
633  snprintf(key_name,MAX_NAME_SIZE-1,"%s%d%d","QC COEFF",0,3);
634  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[0][3],
635  "Polynomial distortion coefficient","%g"));
636 
637  snprintf(key_name,MAX_NAME_SIZE-1,"%s","QC OFFSET");
638  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,value,
639  "Polynomial distortion coefficient","%g"));
640 
641  xshift=new_compute_shift(x_c,y_c,pcf[0][0],pcf[1][0],pcf[0][1],
642  pcf[1][1],pcf[2][0],pcf[0][2],
643  pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
644 
645  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC XSHIFT CC",xshift,
646  "X shift in x_c,y_c","%g"));
647 
648 
649  xshift=new_compute_shift(x_l,y_l,pcf[0][0],pcf[1][0],pcf[0][1],
650  pcf[1][1],pcf[2][0],pcf[0][2],
651  pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
652 
653  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC XSHIFT LL",xshift,
654  "X shift in x_l,y_l","%g"));
655 
656  xshift=new_compute_shift(x_l,y_u,pcf[0][0],pcf[1][0],pcf[0][1],
657  pcf[1][1],pcf[2][0],pcf[0][2],
658  pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
659 
660  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC XSHIFT UL",xshift,
661  "X shift in x_l,y_u","%g"));
662 
663  xshift=new_compute_shift(x_u,y_u,pcf[0][0],pcf[1][0],pcf[0][1],
664  pcf[1][1],pcf[2][0],pcf[0][2],
665  pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
666 
667  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC XSHIFT UR",xshift,
668  "X shift in x_u,y_u","%g"));
669 
670 
671  xshift=new_compute_shift(x_u,y_l,pcf[0][0],pcf[1][0],pcf[0][1],
672  pcf[1][1],pcf[2][0],pcf[0][2],
673  pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
674 
675  ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,"QC XSHIFT LR",xshift,
676  "X shift in x_u,y_l","%g"));
677 
678 
679  ck0(sinfo_pro_save_tbl(poly_tbl,set_fibre_ns,sof,cfg->outName,
680  PRO_DISTORTION,qclog_tbl,plugin_id,config),
681  "cannot dump tbl %s", cfg->outName);
682 
683  sinfo_free_table(&poly_tbl);
684  sinfo_free_table(&qclog_tbl);
685  sinfo_free_polynomial(&distor_poly);
686  sinfo_free_int(&degx);
687  sinfo_free_int(&degy);
688  sinfo_free_double(&coef);
689  sinfo_free_image(&im);
690  sinfo_free_frameset(&stk);
691  sinfo_finddist_free (&cfg);
692 
693  return 0;
694 
695  cleanup:
696  sinfo_free_table(&poly_tbl);
697  sinfo_free_table(&qclog_tbl);
698  sinfo_free_polynomial(&distor_poly);
699  sinfo_free_int(&degx);
700  sinfo_free_int(&degy);
701  sinfo_free_double(&coef);
702  sinfo_free_apertures(&arcs);
703 
704 
705 
706  /*if(wave != NULL) sinfo_new_destroy_array (& wave );*/
707  /*if(intens != NULL) sinfo_new_destroy_array (& intens );*/
708  if(first != NULL) sinfo_new_destroy_array(&first);
709  sinfo_free_table(&tbl_spos);
710  if(slit_pos != NULL) sinfo_new_destroy_2Dfloatarray (&slit_pos,32);
711  if(distances != NULL) sinfo_new_destroy_array(&distances);
712  if(par!=NULL) sinfo_new_destroy_fit_params(&par);
713  if(n_found_lines != NULL) sinfo_new_destroy_intarray(&n_found_lines );
714  if(row_clean != NULL) sinfo_new_destroy_2Dintarray(&row_clean, lx);
715  if(wavelength_clean != NULL) {
716  sinfo_new_destroy_2Dfloatarray(&wavelength_clean,lx);
717  }
718  if(sum_pointer != NULL) sinfo_new_destroy_intarray(&sum_pointer);
719  if(acoefs != NULL) {
720  sinfo_new_destroy_2Dfloatarray(&acoefs, cfg->nrDispCoefficients );
721  }
722  sinfo_free_table(&tbl_line_list);
723  sinfo_free_image(&mask);
724  sinfo_free_image(&impoly);
725  sinfo_free_image(&imonind);
726  sinfo_free_image(&map);
727  sinfo_free_image(&im);
728  sinfo_finddist_free (&cfg);
729  sinfo_free_frameset(&stk);
730  return -1;
731 
732 }
733 
734 
735 static double
736 new_compute_shift(double x,
737  double y,
738  double c00,
739  double c10,
740  double c01,
741  double c11,
742  double c20,
743  double c02,
744  double c21,
745  double c12,
746  double c30,
747  double c03)
748 {
749 
750  double x_shift=0;
751  double shift=0;
752  //sinfo_msg("c= %g %g %g %g %g %g %g %g %g %g\n",
753  // c00,c10,c01,c11,
754  // c20,c02,c21,c12,c30,c03);
755 
756  shift=c00+c10*x+c01*y+
757  c11*x*y+c20*x*x+c02*y*y+
758  c21*x*x*y+c12*x*y*y+c30*x*x*x+c03*y*y*y;
759  x_shift=x-shift;
760  return x_shift;
761 
762 
763 
764 }