SINFONI Pipeline Reference Manual  2.6.0
sinfo_coltilt.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  * E.S.O. - VLT project
21  *
22  *
23  *
24  * who when what
25  * -------- -------- ----------------------------------------------
26  * schreib 19/12/00 created
27  */
28 
29 /************************************************************************
30  * NAME
31  * sinfo_coltilt.c
32  *------------------------------------------------------------------------
33  */
34 #ifdef HAVE_CONFIG_H
35 # include <config.h>
36 #endif
37 
38 #define POSIX_SOURCE 1
39 #include "sinfo_vltPort.h"
40 
41 /*
42  * System Headers
43  */
44 
45 /*
46  * Local Headers
47  */
48 
49 #include "sinfo_coltilt.h"
50 #include "sinfo_new_resampling.h"
51 #include "sinfo_fit_curve.h"
52 #include "sinfo_functions.h"
60 /*----------------------------------------------------------------------------
61  * Function codes
62  *--------------------------------------------------------------------------*/
63 
87 float
88 sinfo_new_slope_of_spectrum( cpl_image * ns_image,
89  int box_length,
90  float fwhm,
91  float minDiff )
92 {
93  int i, k, row, col ;
94  int iters ;
95  int xdim, ndat, its, numpar ;
96  float maxval ;
97  float tol, lab ;
98  float* col_value=NULL ;
99  float* column_value=NULL ;
100  pixelvalue* col_position=NULL ;
101  int* column_position=NULL ;
102  float* x_position=NULL ;
103 
104 
105  int col_median ;
106 
107 
108  Vector * line ;
109  FitParams ** dec_par ;
110 
111 
112  float* x=NULL;
113  float* y=NULL;
114  float* sig=NULL ;
115 
116  int position ;
117  int ndata, mwt ;
118  float a, b, siga, sigb, chi2, q ;
119 
120  int lx=0;
121  int ly=0;
122  float* pdata=NULL;
123 
124  if ( ns_image == NULL )
125  {
126  sinfo_msg_error(" sorry, no image given") ;
127  return FLAG ;
128  }
129  lx=cpl_image_get_size_x(ns_image);
130  ly=cpl_image_get_size_x(ns_image);
131 
132 
133  if ( box_length <= 1 || box_length >= (int) sqrt(lx) )
134  {
135  sinfo_msg_error(" wrong box length given") ;
136  return FLAG ;
137  }
138  if ( fwhm < 1. || fwhm > 10. )
139  {
140  sinfo_msg_error("wrong full width at half maximum given") ;
141  return FLAG ;
142  }
143  if ( minDiff < 1. )
144  {
145  sinfo_msg_error("wrong amplitude threshold given") ;
146  return FLAG ;
147  }
148 
149 
150 
151  col_value=cpl_calloc(ly,sizeof(float)) ;
152  column_value=cpl_calloc(ly,sizeof(float)) ;
153  col_position=(pixelvalue*)cpl_calloc(ly,sizeof(pixelvalue)) ;
154  column_position=cpl_calloc(ly,sizeof(int)) ;
155  x_position=cpl_calloc(ly,sizeof(float)) ;
156 
157 
158 
159  x=cpl_calloc(lx,sizeof(float));
160  y=cpl_calloc(lx,sizeof(float));
161  sig=cpl_calloc(lx,sizeof(float)) ;
162  pdata=cpl_image_get_data_float(ns_image);
163  /* go through the image rows */
164  for ( row = 0 ; row < ly ; row++ )
165  {
166  col_value[row] = -FLT_MAX ;
167  col_position[row] = -1. ;
168  /* find the maximum value in each row and store the found column */
169  for ( col = 0 ; col < lx ; col++ )
170  {
171  if ( pdata[col+row*lx] > col_value[row] )
172  {
173  col_value[row] = pdata[col+row*lx] ;
174  col_position[row] = (pixelvalue)col ;
175  }
176  }
177  }
178 
179  /* now determine the sinfo_new_median of the found columns to be sure
180  to have the brightest spectrum */
181  col_median = (int)sinfo_new_median(col_position, ly) ;
182  sinfo_msg ("sinfo_new_median column position of brightest spectrum %d\n",
183  col_median) ;
184 
185  /* now find the peaks around col_median over the whole spectral range */
186  for ( row = 0 ; row < ly ; row++ )
187  {
188  x_position[row] = 0. ;
189  column_value[row] = -FLT_MAX ;
190  column_position[row] = -1 ;
191  for ( col = col_median - box_length ;
192  col <= col_median + box_length ; col++ )
193  {
194  if ( pdata[col+row*lx] > column_value[row] )
195  {
196  column_value[row] = pdata[col+row*lx] ;
197  column_position[row] = col ;
198  }
199  }
200 
201  /* allocate memory for the array where the line is fitted in */
202  if ( NULL == (line = sinfo_new_vector (2*box_length + 1)) )
203  {
204  sinfo_msg_error ("cannot allocate new Vector in row %d", row) ;
205  return FLAG ;
206  }
207 
208  /* allocate memory */
209  float* xdat = (float *) cpl_calloc( line -> n_elements, sizeof (float) ) ;
210  float* wdat = (float *) cpl_calloc( line -> n_elements, sizeof (float) ) ;
211  int* mpar = (int *) cpl_calloc( MAXPAR, sizeof (int) ) ;
212  dec_par = sinfo_new_fit_params(1) ;
213  FitParams * par = dec_par[0];
214 
215  int counter = 0 ;
216  int bad_ind = 0 ;
217  /* store the values to fit in a Vector object */
218  for ( col = column_position[row] - box_length ;
219  col <= column_position[row] + box_length ; col++ )
220  {
221  if ( col < 0 || col >= lx )
222  {
223  sinfo_msg_error ("wrong spectrum position or box_length "
224  "given in row: %d", row) ;
225  cpl_free (xdat) ;
226  cpl_free (wdat) ;
227  cpl_free (mpar) ;
228  sinfo_new_destroy_fit_params(&dec_par) ;
229  sinfo_new_destroy_vector( line ) ;
230  return FLAG ;
231  }
232  else if ( isnan(pdata[col+row*lx]) )
233  {
234  bad_ind = 1 ;
235  }
236  else
237  {
238  line -> data[counter] = pdata[col + row*lx] ;
239  counter++ ;
240  }
241  }
242 
243  /* go to the next row if a bad pixel is inside the box */
244  if ( bad_ind == 1 )
245  {
246  sinfo_msg_warning ("sorry, bad pixel inside fitting "
247  "box in row: %d", row) ;
248  cpl_free (xdat) ;
249  cpl_free (wdat) ;
250  cpl_free (mpar) ;
251  sinfo_new_destroy_fit_params(&dec_par) ;
252  sinfo_new_destroy_vector( line ) ;
253  continue ;
254  }
255 
256  /*--------------------------------------------------------------------
257  * go through the line sinfo_vector
258  * determine the maximum pixel value in the line sinfo_vector
259  */
260  maxval = -FLT_MAX ;
261  position = -INT32_MAX ;
262  for ( i = 0 ; i < counter ; i++ )
263  {
264  xdat[i] = i ;
265  wdat[i] = 1.0 ;
266  if ( line -> data[i] >= maxval )
267  {
268  maxval = line -> data[i] ;
269  position = i ;
270  }
271  }
272 
273  /* set initial values for the fitting routine */
274  xdim = XDIM ;
275  ndat = line -> n_elements ;
276  numpar = MAXPAR ;
277  tol = TOL ;
278  lab = LAB ;
279  its = ITS ;
280  (*par).fit_par[1] = fwhm ;
281  (*par).fit_par[2] = (float) position ;
282  (*par).fit_par[3] = (float) (line -> data[0] +
283  line -> data[line->n_elements - 1]) / 2.0 ;
284 
285  (*par).fit_par[0] = maxval - ((*par).fit_par[3]) ;
286  /* exclude negative peaks and low signal cases */
287  if ( (*par).fit_par[0] < minDiff )
288  {
289  sinfo_msg_warning ("sorry, negative peak or signal of line "
290  "too low to fit in row: %d", row) ;
291  cpl_free (xdat) ;
292  cpl_free (wdat) ;
293  cpl_free (mpar) ;
294  sinfo_new_destroy_fit_params(&dec_par) ;
295  sinfo_new_destroy_vector( line ) ;
296  continue ;
297  }
298 
299  for ( k = 0 ; k < MAXPAR ; k++ )
300  {
301  (*par).derv_par[k] = 0.0 ;
302  mpar[k] = 1 ;
303  }
304 
305  /* finally, do the least square fit using a sinfo_gaussian */
306  if ( 0 > ( iters = sinfo_new_lsqfit_c( xdat, &xdim,
307  line -> data, wdat,
308  &ndat, (*par).fit_par,
309  (*par).derv_par, mpar,
310  &numpar, &tol, &its, &lab )) )
311  {
312  sinfo_msg_warning ("sinfo_new_lsqfit_c: least squares fit "
313  "failed in row: %d, error no.: %d",row,iters) ;
314  cpl_free (xdat) ;
315  cpl_free (wdat) ;
316  cpl_free (mpar) ;
317  sinfo_new_destroy_fit_params(&dec_par) ;
318  sinfo_new_destroy_vector( line ) ;
319  continue ;
320  }
321 
322  /* check for negative fit results */
323  if ( (*par).fit_par[0] <= 0. || (*par).fit_par[1] <= 0. ||
324  (*par).fit_par[2] <= 0. )
325  {
326  sinfo_msg_warning ("negative parameters as fit result, "
327  "not used! in row: %d", row) ;
328  cpl_free (xdat) ;
329  cpl_free (wdat) ;
330  cpl_free (mpar) ;
331  sinfo_new_destroy_fit_params(&dec_par) ;
332  sinfo_new_destroy_vector( line ) ;
333  continue ;
334  }
335 
336  /* correct the fitted position for the given row of the line in
337  image coordinates */
338  x_position[row] = (float) (column_position[row] - box_length) +
339  (*par).fit_par[2] ;
340 
341  /* store the fit errors of the positions as weights for the later
342  linear fit */
343  sig[row] = (*par).derv_par[2] ;
344 
345  /* free memory */
346  sinfo_new_destroy_fit_params(&dec_par) ;
347  sinfo_new_destroy_vector ( line ) ;
348  cpl_free ( xdat ) ;
349  cpl_free ( wdat ) ;
350  cpl_free ( mpar ) ;
351  }
352 
353  /* -----------------------------------------------------------------------
354  * now that we have a sub-pixel resolved list of spectral maxima stored
355  * in x_position[row]
356  * We can fit a flux weighted straight line to the positions to determine
357  * the spectral column shifts.
358  */
359  ndata = 0 ;
360  for ( row = 0 ; row < lx ; row++ )
361  {
362  if ( x_position[row] == 0. || sig[row] == 0. )
363  {
364  continue ;
365  }
366  else
367  {
368  y[ndata] = x_position[row] ;
369  x[ndata] = (float)row ;
370  sig[ndata] = sig[row] ;
371  ndata++ ;
372  }
373  }
374  if ( ndata < 10 )
375  {
376  sinfo_msg_error("not enough positions to do the linear fit") ;
377  return FLAG ;
378  }
379 
380  /* now do the fit and return the slope of the straight line */
381  mwt = 0 ;
382  sinfo_my_fit(x, y, ndata, sig, mwt, &a, &b, &siga, &sigb, &chi2, &q) ;
383 
384  cpl_free(col_value) ;
385  cpl_free(column_value) ;
386  cpl_free(col_position) ;
387  cpl_free(column_position) ;
388  cpl_free(x_position) ;
389 
390  cpl_free(x);
391  cpl_free(y);
392  cpl_free(sig) ;
393 
394  return b ;
395 }
396 
413 cpl_image *
414 sinfo_new_shift_rows( cpl_image * image,
415  float slope,
416  int n_order )
417 {
418  cpl_image * returnImage=NULL ;
419 
420 
421 
422  float new_sum=0;
423 
424  float* xnum=NULL ;
425  float* row_data=NULL ;
426  float* corrected_row_data=NULL ;
427 
428  float eval=0 /*, dy*/ ;
429  float * imageptr=NULL ;
430  int col=0;
431  int row=0;
432  int firstpos=0;
433  int n_points=0;
434  int i=0;
435  int flag=0;
436  int ilx=0;
437  int ily=0;
438  /*
439  int olx=0;
440  int oly=0;
441  */
442  float* pidata=NULL;
443  float* podata=NULL;
444 
445  if ( image == NULL )
446  {
447  sinfo_msg_error("sorry, no image given") ;
448  return NULL ;
449  }
450 
451  if ( slope == 0. )
452  {
453  sinfo_msg_error("there is no need to shift the image rows!") ;
454  return NULL ;
455  }
456 
457  if ( n_order <= 0 )
458  {
459  sinfo_msg_error("wrong order of interpolation polynom given!") ;
460  return NULL ;
461  }
462 
463  returnImage = cpl_image_duplicate( image ) ;
464  ilx=cpl_image_get_size_x(image);
465  ily=cpl_image_get_size_y(image);
466  /*
467  olx=cpl_image_get_size_x(returnImage);
468  oly=cpl_image_get_size_y(returnImage);
469  */
470  pidata=cpl_image_get_data_float(image);
471  podata=cpl_image_get_data_float(returnImage);
472 
473 
474  n_points = n_order + 1 ;
475  if ( n_points % 2 == 0 )
476  {
477  firstpos = (int)(n_points/2) - 1 ;
478  }
479  else
480  {
481  firstpos = (int)(n_points/2) ;
482  }
483 
484 
485  xnum=cpl_calloc(n_order + 1,sizeof(float)) ;
486  row_data=cpl_calloc(ilx,sizeof(float)) ;
487  corrected_row_data=cpl_calloc(ilx,sizeof(float)) ;
488 
489  /* fill the xa[] array for the polint function */
490  for ( i = 0 ; i < n_points ; i++ )
491  {
492  xnum[i] = i ;
493  }
494 
495  /* go through the image rows */
496  for ( row = 0 ; row < ily ; row++ )
497  {
498  /* determine the shift for each row, the middle row is not shifted */
499  float xshift = slope * (float)( (ily / 2) - row ) ;
500 
501  int intshift = sinfo_new_nint(xshift) ;
502  xshift = xshift - (float)intshift ;
503 
504  for ( col = 0 ; col < ilx ; col++ )
505  {
506  corrected_row_data[col] = 0. ;
507  }
508  float sum = 0. ; /* initialize flux for later rescaling */
509  /* go through the image columns */
510  for ( col = 0 ; col < ilx ; col++ )
511  {
512  /* consider integer pixel shifts */
513  if ( intshift < 0 )
514  {
515  if ( col - intshift < ilx )
516  {
517  row_data[col] = pidata[col-intshift+row*ilx] ;
518  }
519  else
520  {
521  row_data[col] = 0. ;
522  }
523  }
524  else if ( intshift > 0 )
525  {
526  if ( col - intshift >= 0 )
527  {
528  row_data[col] = pidata[col-intshift+row*ilx] ;
529  }
530  else
531  {
532  row_data[col] = 0. ;
533  }
534  }
535  else
536  {
537  row_data[col] = pidata[col+row*ilx] ;
538  }
539 
540  /* don't consider the sinfo_edge pixels for flux calculation */
541  if ( col != 0 && col != ilx - 1 && !isnan(row_data[col]) )
542  {
543  sum += row_data[col] ;
544  }
545  if (isnan(row_data[col]))
546  {
547  row_data[col] = 0. ;
548  for (i = col - firstpos ; i < col - firstpos + n_points ; i++ )
549  {
550  if ( i < 0 ) continue ;
551  if ( i >= ilx) continue ;
552  corrected_row_data[i] = ZERO ;
553  }
554  }
555  }
556 
557 
558  /* --------------------------------------------------------------------
559  * now we do the polynomial interpolation to achieve the fractional
560  * shift that means call polint
561  */
562  new_sum = 0. ;
563  for ( col = 0 ; col < ilx ; col++ )
564  {
565  /* ---------------------------------------------------------------
566  * now determine the arrays of size n_points with which the
567  * polynom is determined and determine the position eval
568  * where the polynom is evaluated in polint of N.R..
569  * Take care of the points near the row edges!
570  */
571  if ( isnan(corrected_row_data[col]) )
572  {
573  continue ;
574  }
575  if ( col - firstpos < 0 )
576  {
577  imageptr = &row_data[0] ;
578  eval = (float)col - xshift ;
579  }
580  else if ( col - firstpos + n_points >= ilx )
581  {
582  imageptr = &row_data[ilx - n_points] ;
583  eval = (float)(col + n_points - ilx) - xshift ;
584  }
585  else
586  {
587  imageptr = &row_data[col-firstpos] ;
588  eval = (float)firstpos - xshift ;
589  }
590 
591  flag=0;
592  corrected_row_data[col]=sinfo_new_nev_ille(xnum,imageptr,
593  n_order,eval,&flag);
594  /*polint( xnum - 1, imageptr, n_points, eval,
595  &corrected_row_data[col], &dy ) ;*/
596 
597  /* don't take the sinfo_edge points to calculate
598  the scaling factor */
599  if (col != 0 && col != ilx - 1 && !isnan(corrected_row_data[col]) )
600  {
601  new_sum += corrected_row_data[col] ;
602  }
603  }
604 
605  if ( new_sum == 0. )
606  {
607  new_sum = 1. ;
608  }
609  for ( col = 0 ; col < ilx ; col++ )
610  {
611  if ( isnan(corrected_row_data[col]))
612  {
613  podata[col+row*ilx] = ZERO ;
614  }
615  else
616  {
617  /* rescale the row data and fill the returned image */
618  /* This gives sometimes inconsistent results if
619  bad pixels are around */
620  /* rescaling is commented out because it delivers wrong results
621  in case of appearance of blanks or bad pixels */
622  /* corrected_row_data[col] *= sum / new_sum ; */
623  podata[col+row*ilx] = corrected_row_data[col] ;
624  }
625  }
626  }
627 
628  cpl_free(xnum) ;
629  cpl_free(row_data) ;
630  cpl_free(corrected_row_data);
631 
632  return returnImage ;
633 }
634 
635 
648 void
649 sinfo_new_parameter_to_ascii ( float * parameter,
650  int n,
651  char * filename )
652 {
653  FILE * fp ;
654  int i=0 ;
655 
656  if ( parameter == NULL || filename == NULL || n <= 0 )
657  {
658  sinfo_msg_error ("input is missing or wrong!") ;
659  return ;
660  }
661 
662  if ( NULL == (fp = fopen ( filename, "w" ) ) )
663  {
664  sinfo_msg_error("cannot open %s", filename) ;
665  return ;
666  }
667 
668  for ( i = 0 ; i < n ; i++ )
669  {
670  fprintf (fp, "%le\n", parameter[i] ) ;
671  }
672  fclose (fp ) ;
673 }
674 
675 
703 double *
704 sinfo_new_curvature_of_spectrum( cpl_image * ns_image,
705  int order,
706  int box_length,
707  int left_pos,
708  int right_pos,
709  float fwhm,
710  float minDiff )
711 {
712  int i=0;
713  int k=0;
714  int row=0;
715  int col=0;
716 
717  int iters=0;
718  int xdim=0;
719  int ndat=0;
720  int its=0;
721  int numpar=0;
722  float maxval=0 ;
723  float tol=0;
724  float lab=0;
725 
726  float* col_value=NULL ;
727  float* column_value=NULL ;
728  pixelvalue* col_position=NULL ;
729  int* column_position=NULL ;
730  float* x_position=NULL ;
731 
732  int col_median=0;
733 
734 
735 
736  Vector * line=NULL;
737  FitParams ** dec_par=NULL ;
738 
739  int position=0 ;
740  int ndata=0 ;
741 
742  dpoint * list=NULL ;
743  double * coeffs=NULL ;
744  double offset=0 ;
745  int lx=0;
746  int ly=0;
747  float* pdata=NULL;
748 
749  if ( ns_image == NULL )
750  {
751  sinfo_msg_error("sorry, no image given") ;
752  return NULL ;
753  }
754  lx=cpl_image_get_size_x(ns_image);
755  ly=cpl_image_get_size_y(ns_image);
756 
757  if ( box_length <= 1 || box_length >= right_pos - left_pos )
758  {
759  sinfo_msg_error("wrong box length given") ;
760  return NULL ;
761  }
762  if ( fwhm < 1. || fwhm > 10. )
763  {
764  sinfo_msg_error("wrong full width at half maximum given") ;
765  return NULL ;
766  }
767  if ( left_pos < 0 || right_pos <= left_pos || right_pos > lx )
768  {
769  sinfo_msg_error("wrong left and right positions") ;
770  return NULL ;
771  }
772  if ( minDiff < 1. )
773  {
774  sinfo_msg_error("wrong amplitude threshold given!") ;
775  return NULL ;
776  }
777 
778 
779 
780  col_value=cpl_calloc(ly,sizeof(float)) ;
781  column_value=cpl_calloc(ly,sizeof(float)) ;
782  col_position=(pixelvalue*)cpl_calloc(ly,sizeof(pixelvalue)) ;
783  column_position=cpl_calloc(ly,sizeof(int)) ;
784  x_position=cpl_calloc(ly,sizeof(float)) ;
785  pdata=cpl_image_get_data_float(ns_image);
786  /* go through the image rows */
787  for ( row = 0 ; row < ly ; row++ )
788  {
789  col_value[row] = -FLT_MAX ;
790  col_position[row] = -1. ;
791  /* find the maximum value in each row and store the found column */
792  for ( col = left_pos ; col < right_pos ; col++ )
793  {
794  if ( pdata[col+row*lx] > col_value[row] )
795  {
796  col_value[row] = pdata[col+row*lx] ;
797  col_position[row] = (pixelvalue)col ;
798  }
799  }
800  }
801 
802  /* now determine the sinfo_new_median of the found columns to be sure
803  to have the brightest spectrum */
804  col_median = (int)sinfo_new_median(col_position, right_pos - left_pos) ;
805 
806  /* now find the peaks around col_median over the whole spectral range */
807  for ( row = 0 ; row < ly ; row++ )
808  {
809  x_position[row] = 0. ;
810  column_value[row] = -FLT_MAX ;
811  column_position[row] = -1 ;
812  for ( col = col_median - box_length ;
813  col <= col_median + box_length ; col++ )
814  {
815  if ( pdata[col+row*lx] > column_value[row] )
816  {
817  column_value[row] = pdata[col+row*lx] ;
818  column_position[row] = col ;
819  }
820  }
821 
822  /* allocate memory for the array where the line is fitted in */
823  if ( NULL == (line = sinfo_new_vector (2*box_length + 1)) )
824  {
825  sinfo_msg_error ("cannot allocate new Vector in row: %d", row) ;
826  return NULL ;
827  }
828 
829  /* allocate memory */
830  float* xdat = (float *) cpl_calloc( line -> n_elements, sizeof (float) ) ;
831  float* wdat = (float *) cpl_calloc( line -> n_elements, sizeof (float) ) ;
832  int* mpar = (int *) cpl_calloc( MAXPAR, sizeof (int) ) ;
833  dec_par = sinfo_new_fit_params(1) ;
834  FitParams * par = dec_par[0];
835 
836  int counter = 0 ;
837  int bad_ind = 0 ;
838  /* store the values to fit in a Vector object */
839  for ( col = column_position[row] - box_length ;
840  col <= column_position[row] + box_length ; col++ )
841  {
842  if ( col < 0 || col >= lx )
843  {
844  sinfo_msg_error ("wrong spectrum position or box_length "
845  "given in row: %d", row) ;
846  cpl_free (xdat) ;
847  cpl_free (wdat) ;
848  cpl_free (mpar) ;
849  sinfo_new_destroy_fit_params(&dec_par) ;
850  sinfo_new_destroy_vector( line ) ;
851  return NULL ;
852  }
853  else if ( isnan(pdata[col+row*lx]) )
854  {
855  bad_ind = 1 ;
856  }
857  else
858  {
859  line -> data[counter] = pdata[col + row*lx] ;
860  counter++ ;
861  }
862  }
863 
864  /* go to the next row if a bad pixel is inside the box */
865  if ( bad_ind == 1 )
866  {
867  sinfo_msg_warning ("sorry, bad pixel inside fitting box "
868  "in row: %d", row) ;
869  cpl_free (xdat) ;
870  cpl_free (wdat) ;
871  cpl_free (mpar) ;
872  sinfo_new_destroy_fit_params(&dec_par) ;
873  sinfo_new_destroy_vector( line ) ;
874  continue ;
875  }
876 
877  /*--------------------------------------------------------------------
878  * go through the line sinfo_vector
879  * determine the maximum pixel value in the line sinfo_vector
880  */
881  maxval = -FLT_MAX ;
882  position = -INT32_MAX ;
883  for ( i = 0 ; i < counter ; i++ )
884  {
885  xdat[i] = i ;
886  wdat[i] = 1.0 ;
887  if ( line -> data[i] >= maxval )
888  {
889  maxval = line -> data[i] ;
890  position = i ;
891  }
892  }
893 
894  /* set initial values for the fitting routine */
895  xdim = XDIM ;
896  ndat = line -> n_elements ;
897  numpar = MAXPAR ;
898  tol = TOL ;
899  lab = LAB ;
900  its = ITS ;
901  (*par).fit_par[1] = fwhm ;
902  (*par).fit_par[2] = (float) position ;
903  (*par).fit_par[3] = (float) (line -> data[0] +
904  line -> data[line->n_elements - 1]) / 2.0;
905 
906  (*par).fit_par[0] = maxval - ((*par).fit_par[3]) ;
907  /* exclude negative peaks and low signal cases */
908  if ( (*par).fit_par[0] < minDiff )
909  {
910  sinfo_msg_warning ("sorry, negative peak or signal of line "
911  "too low to fit in row: %d", row) ;
912  cpl_free (xdat) ;
913  cpl_free (wdat) ;
914  cpl_free (mpar) ;
915  sinfo_new_destroy_fit_params(&dec_par) ;
916  sinfo_new_destroy_vector( line ) ;
917  continue ;
918  }
919 
920  for ( k = 0 ; k < MAXPAR ; k++ )
921  {
922  (*par).derv_par[k] = 0.0 ;
923  mpar[k] = 1 ;
924  }
925 
926  /* finally, do the least square fit using a sinfo_gaussian */
927  if ( 0 > ( iters = sinfo_new_lsqfit_c( xdat, &xdim,
928  line -> data, wdat,
929  &ndat, (*par).fit_par,
930  (*par).derv_par, mpar,
931  &numpar, &tol, &its, &lab )) )
932  {
933  sinfo_msg_warning ("least squares fit failed in row: "
934  "%d, error no.: %d", row, iters) ;
935  cpl_free (xdat) ;
936  cpl_free (wdat) ;
937  cpl_free (mpar) ;
938  sinfo_new_destroy_fit_params(&dec_par) ;
939  sinfo_new_destroy_vector( line ) ;
940  continue ;
941  }
942 
943  /* check for negative fit results */
944  if ( (*par).fit_par[0] <= 0. || (*par).fit_par[1] <= 1. ||
945  (*par).fit_par[2] <= 0. )
946  {
947  sinfo_msg_warning ("negative parameters as fit result, "
948  "not used! in row: %d", row) ;
949  cpl_free (xdat) ;
950  cpl_free (wdat) ;
951  cpl_free (mpar) ;
952  sinfo_new_destroy_fit_params(&dec_par) ;
953  sinfo_new_destroy_vector( line ) ;
954  continue ;
955  }
956 
957  /* correct the fitted position for the given row of the line
958  in image coordinates */
959  x_position[row] = (float) (column_position[row] - box_length) +
960  (*par).fit_par[2] ;
961  printf("%d %f %f\n",row, (*par).fit_par[1], x_position[row] ) ;
962 
963  /* free memory */
964  sinfo_new_destroy_fit_params(&dec_par) ;
965  sinfo_new_destroy_vector ( line ) ;
966  cpl_free ( xdat ) ;
967  cpl_free ( wdat ) ;
968  cpl_free ( mpar ) ;
969  }
970  /* now allocate memory for the data to fit */
971  if ( NULL == ( list = (dpoint*) cpl_calloc (ly, sizeof (dpoint)) ) )
972  {
973  sinfo_msg_error("could not allocate memory!") ;
974  return NULL ;
975  }
976 
977  /* ------------------------------------------------------------------------
978  * now that we have a sub-pixel resolved list of spectral maxima stored
979  * in x_position[row] We can fit a flux weighted straight line to the
980  * positions to determine the spectral column shifts.
981  */
982  offset = (double) ly/2. ;
983  ndata = 0 ;
984  for ( row = 0 ; row < ly ; row++ )
985  {
986  if ( x_position[row] == 0. )
987  {
988  continue ;
989  }
990  else
991  {
992  list[ndata].y = (double)x_position[row] ;
993  list[ndata].x = (double)row - offset ;
994  ndata++ ;
995  }
996  }
997 
998 
999  if ( NULL == (coeffs = sinfo_fit_1d_poly(order, list, ndata, NULL)) )
1000  {
1001  sinfo_msg_error("eclipse function sinfo_fit_1d_poly() did not work!") ;
1002  return NULL ;
1003  }
1004  cpl_free ( list ) ;
1005 
1006 
1007 
1008  cpl_free(col_value) ;
1009  cpl_free(column_value) ;
1010  cpl_free(col_position) ;
1011  cpl_free(column_position) ;
1012  cpl_free(x_position) ;
1013 
1014  return coeffs ;
1015 }
1016 
1027 cpl_image *
1028 sinfo_new_image_warp_fits( cpl_image * image,
1029  char * kernel_type,
1030  char * poly_table )
1031 {
1032  cpl_image * warped=NULL;
1033  /* Following are for polynomial transforms */
1034  cpl_polynomial * poly_u=NULL; /* polynomial definition */
1035  cpl_polynomial * poly_v=NULL; /* polynomial definition */
1036 
1037  cpl_vector * profile=NULL ;
1038  cpl_size local_pow[2];
1039 
1040 
1041  /*fscanf(poly_in,"%s",poly_string);*/
1042  /* sinfo_msg("%s",poly_string); */
1043 
1044  poly_u = cpl_polynomial_new(2);
1045  if (poly_u == NULL) {
1046  sinfo_msg_error("cannot read 2D poly from arc table") ;
1047  return NULL ;
1048  }
1049 
1050  if (poly_u != NULL) {
1051  sinfo_msg_debug("Get the arc distortion from the file %s",
1052  poly_table);
1053  if(sinfo_is_fits_file(poly_table) != 1) {
1054  sinfo_msg_error("Input file %s is not FITS",poly_table);
1055  return NULL;
1056  }
1057  cpl_table* poly_tbl=NULL;
1058  if(NULL==(poly_tbl = cpl_table_load(poly_table,1,0))) {
1059  sinfo_msg_error("cannot load the arc table") ;
1060  cpl_polynomial_delete(poly_u) ;
1061  return NULL ;
1062  }
1063 
1064  for (int i=0 ; i<cpl_table_get_nrow(poly_tbl) ; i++) {
1065  local_pow[0] = cpl_table_get_int(poly_tbl, "degx", i, NULL) ;
1066  local_pow[1] = cpl_table_get_int(poly_tbl, "degy", i, NULL) ;
1067  cpl_polynomial_set_coeff(poly_u, local_pow,
1068  cpl_table_get_double(poly_tbl, "coeff", i, NULL)) ;
1069  }
1070 
1071  cpl_table_delete(poly_tbl) ;
1072  } else {
1073  sinfo_msg("Use the ID polynomial for the arc dist") ;
1074  local_pow[0] = 1 ;
1075  local_pow[1] = 0 ;
1076  cpl_polynomial_set_coeff(poly_u, local_pow, 1.0) ;
1077  }
1078 
1079  poly_v=cpl_polynomial_new(2);
1080  local_pow[0]=0;
1081  local_pow[1]=1;
1082 
1083  cpl_polynomial_set_coeff(poly_v,local_pow,1.0);
1084  profile = cpl_vector_new(CPL_KERNEL_DEF_SAMPLES) ;
1085  cpl_vector_fill_kernel_profile(profile, CPL_KERNEL_TANH,
1086  CPL_KERNEL_DEF_WIDTH) ;
1087  warped=sinfo_new_warp_image_generic(image,kernel_type,poly_u,poly_v);
1088  /* YVES WAY
1089  warped = cpl_image_new(cpl_image_get_size_x(image),
1090  cpl_image_get_size_y(image),
1091  CPL_TYPE_FLOAT);
1092 
1093  if (cpl_image_warp_polynomial(warped, image, poly_u, poly_v,
1094  profile,CPL_KERNEL_DEF_WIDTH,
1095  profile,CPL_KERNEL_DEF_WIDTH)
1096  != CPL_ERROR_NONE) {
1097  sinfo_msg_error("cannot correct the distortion") ;
1098  cpl_image_delete(warped) ;
1099  cpl_polynomial_delete(poly_u) ;
1100  cpl_polynomial_delete(poly_v) ;
1101  cpl_vector_delete(profile) ;
1102  return NULL;
1103  }
1104  */
1105 
1106  cpl_vector_delete(profile) ;
1107  if (poly_u!=NULL) cpl_polynomial_delete(poly_u);
1108  if (poly_v!=NULL) cpl_polynomial_delete(poly_v);
1109 
1110  return warped;
1111 }
1112 
#define sinfo_msg_debug(...)
Print a debug message.
Definition: sinfo_msg.h:103
#define sinfo_msg_error(...)
Print an error message.
Definition: sinfo_msg.h:69
#define sinfo_msg_warning(...)
Print an warning message.
Definition: sinfo_msg.h:93