SINFONI Pipeline Reference Manual  2.6.0
sinfo_spectrum_ops.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 25/05/00 created
27 */
28 
29 /************************************************************************
30 * NAME
31 * sinfo_spectrum_ops.c -
32 * some sinfo_vector procedures to operate on spectra
33 *
34 * SYNOPSIS
35 * #include "sinfo_spectrum_ops.h"
36 *
37 * 1) Vector * sinfo_new_vector( ulong32 n_elements )
38 * 2) void * sinfo_new_destroy_vector( Vector *sinfo_vector )
39 * 3) cpl_image * sinfo_new_vector_to_image( Vector * spectrum )
40 * 4) Vector * sinfo_new_image_to_vector( cpl_image * spectrum )
41 * 5) cpl_image *
42  sinfo_new_extract_spectrum_from_resampled_flat(cpl_image * resflat,
43 * float loreject,
44 * float hireject )
45 * 6) cpl_image * sinfo_new_multiply_image_with_spectrum(cpl_image * image,
46  cpl_image * spectrum)
47 * 7) cpl_image * sinfo_new_optimal_extraction_from_cube(cpl_imagelist * cube,
48 * int halfbox_x,
49 * int halfbox_y,
50 * float fwhm_factor,
51 * float backvariance,
52 * float sky,
53 * float gain,
54 * float exptime)
55 * 8) Vector * sinfo_new_extract_sky_from_cube( cpl_imagelist * cube,
56 * float loReject,
57 * float hiReject,
58 * int * position,
59 * int tolerance,
60 * int posindicator )
61 * 9) Vector * sinfo_new_sum_rectangle_of_cube_spectra( cpl_imagelist * cube,
62 * int llx,
63 * int lly,
64 * int urx,
65 * int ury )
66 * 10) Vector * sinfo_new_sum_circle_of_cube_spectra( cpl_imagelist * cube,
67 * int centerx,
68 * int centery,
69 * int radius )
70 * 11) Vector *
71  sinfo_new_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
72 * int llx,
73 * int lly,
74 * int urx,
75 * int ury )
76 * 12) Vector * sinfo_new_mean_circle_of_cube_spectra( cpl_imagelist * cube,
77 * int centerx,
78 * int centery,
79 * int radius )
80 * 13) Vector *
81  sinfo_new_blackbody_spectrum(char * templateSpec, double temp )
82 * 14) Vector *
83  sinfo_new_median_rectangle_of_cube_spectra(cpl_imagelist * cube,
84 * int llx,
85 * int lly,
86 * int urx,
87 * int ury )
88 * 15) Vector * sinfo_new_median_circle_of_cube_spectra( cpl_imagelist * cube,
89 * int centerx,
90 * int centery,
91 * int radius )
92 * 16) Vector *
93  sinfo_new_cleanmean_rectangle_of_cube_spectra(cpl_imagelist * cube,
94 * int llx,
95 * int lly,
96 * int urx,
97 * int ury,
98 * float lo_reject,
99 * float hi_reject )
100 * 17) Vector *
101  sinfo_new_cleanmean_circle_of_cube_spectra( cpl_imagelist * cube,
102 * int centerx,
103 * int centery,
104 * int radius,
105 * float lo_reject,
106 * float hi_reject )
107 * 18) float * sinfo_new_shift_array ( float * input,
108  int n_elements,
109  float shift,
110  double * ker )
111 *
112 * DESCRIPTION
113 * 1) allocates memory for a new sinfo_vector
114 * 2) frees memory of a sinfo_vector
115 * 3) converts a spectral sinfo_vector to a fits image
116 * remark: sinfo_vector object spectrum is destroyed
117 * 4) converts a fits image to a spectral sinfo_vector
118 * remark: input image is destroyed
119 * 5) builds one spectrum in a fits image out of a resampled
120 * flatfield frame by taking a clean mean along the spatial pixels
121 * 6) multiplys a resampled image with a resampled spectrum
122 * (calibrated halogen lamp spectrum) in the same spectral range
123 * that means all image columns are multiplied with the same spectrum
124 * 7) does the optimal extraction of a standard star spectrum
125 * according to the equation:
126 * S = sum { (P^2 / V) * (I - B) / P } / sum{ P^2 / V }
127 * S: spectral flux at a particular wavelength
128 * P: normalized PSF (determined by a 2D-Gaussian fit)
129 * I: pixel value
130 * B: background pixel value determined by the background parameter
131  of the 2D-Gaussian fit
132 * V: estimated variance of a pixel:
133  V = [R^2 + D + sky + I,c/exptime]/gain
134 * where R is the read noise, and D the sinfo_dark current variance.
135 * backvariance is R^2 + D in counts/sec.
136  I,c is the source intensity in counts
137 * Remember: sigma,e[e-] = gain[e/count] * sigma,c [counts] =
138  sqrt(I,e) = sqrt(gain*I,c)
139 * => V,c = sigma,c^2 = sigma,e^2/gain^2
140 * => sigma,c = sqrt(I,c/gain) => V,c = I,c/gain
141 * 8) extracts a sky spectrum from a reduced sky spider observation, that
142 * means from a data cube. Therefore, the position of the sky within the
143 * field of view must be first read from the fits header.
144  A pixel tolerance is subtracted.
145 * The found sky spectra are averaged by rejecting the extreme
146  high and low values.
147 * 9) summing routine for a reduced data to get a better spectral S/N
148 * only for a rectangular aperture.
149 * 10) summing routine for a reduced data to get a better spectral S/N
150 * only for a circular aperture.
151 * 11) averaging routine for a reduced data to get a better spectral S/N
152 * only for a rectangular aperture.
153 * 12) averaging routine for a reduced data to get a better spectral S/N
154 * only for a circular aperture.
155 * 13) computes a blackbody spectral intensity distribution
156 * (W/(m^2 lambda ster))
157 * 14) sinfo_median routine for a reduced data to get a better spectral S/N
158 * only for a rectangular aperture.
159 * 15) sinfo_median routine for a reduced data to get a better spectral S/N
160 * only for a circular aperture.
161 * 16) clean averaging routine for a reduced data to get a better spectral S/N
162 * only for a rectangular aperture.
163 * 17) clean averaging routine for a reduced data to get a better spectral S/N
164 * only for a circular aperture.
165 * 18) shifts an array by a sub-pixel shift value using a tanh
166 * interpolation kernel
167 *
168 * FILES
169 *
170 * ENVIRONMENT
171 *
172 * RETURN VALUES
173 *
174 * CAUTIONS
175 *
176 * EXAMPLES
177 *
178 * SEE ALSO
179 *
180 * BUGS
181 *
182 *------------------------------------------------------------------------
183 */
184 #ifdef HAVE_CONFIG_H
185 # include <config.h>
186 #endif
187 
188 #define POSIX_SOURCE 1
189 #include "sinfo_vltPort.h"
190 
191 /*
192  * System Headers
193  */
194 
195 /*
196  * Local Headers
197  */
198 #include "sinfo_pfits.h"
199 #include "sinfo_spectrum_ops.h"
200 #include "sinfo_resampling.h"
201 #include "sinfo_utilities.h"
202 #include "sinfo_utils_wrappers.h"
203 /*----------------------------------------------------------------------------
204  * Function codes
205  *--------------------------------------------------------------------------*/
206 
224 int sinfo_stectrum_ima2table(
225  const cpl_image* spc,
226  const char* filename,
227  cpl_table** tbl)
228 {
229  const float* pidata=NULL;
230  int nx=0;
231  int ny=0;
232  int nraw=0;
233  int i=0;
234  double wav=0;
235 
236  double step=0;
237  double ws=0;
238  double we=0;
239  double wc=0;
240  cpl_propertylist* plist=NULL;
241 
242  if(spc == NULL){
243  sinfo_msg_error("Input image is null");
244  return -1;
245  }
246 
247  pidata = cpl_image_get_data_const(spc);
248  nx=cpl_image_get_size_x(spc);
249  ny=cpl_image_get_size_y(spc);
250 
251  if((nx == 0) || (ny == 0)) {
252  sinfo_msg_error("Input image has improper size: nx=%d ny=%d",nx,ny);
253  return -1;
254  }
255  if((nx > 1) && (ny > 1)) {
256  sinfo_msg_error("Input image has improper size: nx=%d ny=%d",nx,ny);
257  return -1;
258  }
259 
260 
261  nraw=nx*ny;
262  *tbl = cpl_table_new(nraw);
263  cpl_table_new_column(*tbl,"WAVE",CPL_TYPE_DOUBLE);
264  cpl_table_new_column(*tbl,"INT",CPL_TYPE_DOUBLE);
265 
266 
267  if ((cpl_error_code)((plist = cpl_propertylist_load(filename, 0)) == NULL)) {
268  sinfo_msg_error( "getting header from reference frame %s",filename);
269  cpl_propertylist_delete(plist) ;
270  return -1 ;
271  }
272 
273 
274  if(nx>1) {
275  step=sinfo_pfits_get_cdelt1(plist);
276  wc=sinfo_pfits_get_crval1(plist);
277  } else {
278 
279  step=sinfo_pfits_get_cdelt2(plist);
280  wc=sinfo_pfits_get_crval2(plist);
281  }
282 
283  ws=wc-nraw*step/2;
284  we=wc+nraw*step/2;
285  wav=ws;
286  sinfo_msg("ws=%f we=%f step=%f",ws,we,step);
287  cpl_table_set_double(*tbl,"WAVE",0,wav);
288  cpl_table_set_double(*tbl,"INT",0,pidata[i]);
289 
290  for(i=1;i<nraw;i++) {
291  wav+=step;
292  double amp=(double)pidata[i];
293  cpl_table_set_double(*tbl,"WAVE",i,wav);
294  cpl_table_set_double(*tbl,"INT",i,amp);
295  }
296  cpl_propertylist_delete(plist);
297  return 0;
298 
299 
300 }
301 
302 
303 
313 Vector * sinfo_new_vector( ulong32 n_elements )
314 {
315  Vector * local_new_vector ;
316 
317  if ( n_elements <= 0 )
318  {
319  sinfo_msg_error (" wrong number of elements\n") ;
320  return NullVector ;
321  }
322 
323  /* allocate memory for a sinfo_vector with the given number of elements */
324  local_new_vector = (Vector *) cpl_malloc (sizeof (Vector)) ;
325  local_new_vector -> n_elements = n_elements ;
326  local_new_vector -> data = (pixelvalue *) cpl_calloc (n_elements,
327  sizeof (pixelvalue)) ;
328 
329  return local_new_vector ;
330 }
331 
339 void sinfo_free_svector( Vector **svector )
340 {
341  if ( *svector != NULL )
342  {
343 
344  if((*svector) -> data != NULL) {
345  cpl_free ( (*svector) -> data ) ;
346  (*svector)->data = NULL;
347  }
348  cpl_free ( *svector ) ;
349  *svector = NULL;
350  }
351  return ;
352 }
353 
361 void sinfo_new_destroy_vector( Vector *sinfo_vector )
362 {
363  if ( sinfo_vector == NULL )
364  {
365  sinfo_msg_error(" NULL Vector given!\n") ;
366  return ;
367  }
368 
369  cpl_free ( sinfo_vector -> data ) ;
370  cpl_free ( sinfo_vector ) ;
371 }
372 
381 cpl_image * sinfo_new_vector_to_image( Vector * spectrum )
382 {
383  cpl_image * returnIm ;
384  int i ;
385 
386  float* podata=NULL;
387 
388 
389  if ( spectrum == NULL )
390  {
391  sinfo_msg_error(" no spectrum given!\n") ;
392  return NULL ;
393  }
394 
395  /* allocate memory */
396  if ( NULL == (returnIm = cpl_image_new(1, spectrum->n_elements,
397  CPL_TYPE_FLOAT)) )
398  {
399  sinfo_msg_error(" no spectrum given!\n") ;
400  sinfo_new_destroy_vector(spectrum) ;
401  return NULL ;
402  }
403 
404  podata=cpl_image_get_data_float(returnIm);
405  for ( i = 0 ; i < spectrum->n_elements ; i++ )
406  {
407  podata[i] = spectrum -> data[i] ;
408  }
409 
410  sinfo_new_destroy_vector (spectrum) ;
411  return returnIm ;
412 }
413 
422 Vector * sinfo_new_image_to_vector( cpl_image * spectrum )
423 {
424  Vector * returnVector ;
425  int i ;
426  int ilx=0;
427  int ily=0;
428 
429  float* pidata=NULL;
430 
431  if ( spectrum == NULL )
432  {
433  sinfo_msg_error(" no spectrum given!") ;
434  return NULL ;
435  }
436  ilx=cpl_image_get_size_x(spectrum);
437  ily=cpl_image_get_size_y(spectrum);
438 
439  /* allocate memory */
440  if ( NULL == (returnVector = sinfo_new_vector(ilx*ily)) )
441  {
442  sinfo_msg_error(" cannot allocate memory!") ;
443  cpl_image_delete(spectrum) ;
444  return NULL ;
445  }
446 
447  pidata=cpl_image_get_data_float(spectrum);
448  for ( i = 0 ; i < (int) ilx*ily ; i++ )
449  {
450  returnVector -> data[i] = pidata[i] ;
451  }
452 
453  cpl_image_delete (spectrum) ;
454  return returnVector ;
455 }
456 
469 cpl_image *
470 sinfo_new_extract_spectrum_from_resampled_flat( cpl_image * resflat,
471  float loreject,
472  float hireject )
473 {
474  cpl_image * retIm ;
475  int col, row ;
476  float* array=NULL ;
477  float cleanMean ;
478  Vector * spectrum ;
479 
480  int ilx=0;
481  int ily=0;
482 
483  float* pidata=NULL;
484 
485  if ( resflat == NULL )
486  {
487  sinfo_msg_error(" no flatfield given!") ;
488  return NULL ;
489  }
490  ilx=cpl_image_get_size_x(resflat);
491  ily=cpl_image_get_size_y(resflat);
492 
493  /* allocate memory */
494  if ( NullVector == (spectrum = sinfo_new_vector(ily) ) )
495  {
496  sinfo_msg_error(" could not allocate memory!") ;
497  return NULL ;
498  }
499 
500  array=cpl_calloc(ily,sizeof(float)) ;
501 
502  pidata=cpl_image_get_data_float(resflat);
503  for ( row = 0 ; row < ily ; row++ )
504  {
505  int n = 0 ;
506  for ( col = 0 ; col < ilx ; col++ )
507  {
508  if ( !isnan(pidata[col + row*ilx]) )
509  {
510  array[n] = pidata[col+row*ilx] ;
511  n++ ;
512  }
513  }
514  if ( n == 0 )
515  {
516  sinfo_msg_warning(" only bad pixels in row: %d!", row) ;
517  cleanMean = ZERO ;
518  }
519  else
520  {
521  if ( FLT_MAX == (cleanMean = sinfo_new_clean_mean(array, n,
522  loreject,
523  hireject)) )
524  {
525  sinfo_msg_error(" could not do sinfo_clean_mean!") ;
526  sinfo_new_destroy_vector(spectrum) ;
527  return NULL ;
528  }
529  }
530  spectrum->data[row] = cleanMean ;
531  }
532  if ( NULL == ( retIm = sinfo_new_vector_to_image( spectrum ) ) )
533  {
534  sinfo_msg_error(" could not do sinfo_vectorToImage!") ;
535  sinfo_new_destroy_vector(spectrum) ;
536  return NULL ;
537  }
538  cpl_free(array) ;
539 
540  return retIm ;
541 }
542 
556 cpl_image *
557 sinfo_new_multiply_image_with_spectrum( cpl_image * image,
558  cpl_image * spectrum )
559 {
560  int col, row ;
561  cpl_image * retImage ;
562 
563 
564  int ilx=0;
565  int ily=0;
566  /* int slx=0; */
567  int sly=0;
568 
569  float* pidata=NULL;
570  float* psdata=NULL;
571  float* podata=NULL;
572 
573 
574  if ( image == NULL )
575  {
576  sinfo_msg_error(" no image given!") ;
577  return NULL ;
578  }
579  ilx=cpl_image_get_size_x(image);
580  ily=cpl_image_get_size_y(image);
581 
582  if ( spectrum == NULL )
583  {
584  sinfo_msg_error(" no spectrum image given!") ;
585  return NULL ;
586  }
587  /* slx=cpl_image_get_size_x(spectrum); */
588  sly=cpl_image_get_size_y(spectrum);
589 
590  if ( sly != ily )
591  {
592  sinfo_msg_error(" images are not compatible in pixel length!") ;
593  return NULL ;
594  }
595 
596  if ( NULL == (retImage = cpl_image_duplicate(image)) )
597  {
598  sinfo_msg_error(" could not copy original image!\n") ;
599  return NULL ;
600  }
601 
602  pidata=cpl_image_get_data_float(image);
603  psdata=cpl_image_get_data_float(spectrum);
604  podata=cpl_image_get_data_float(retImage);
605 
606  for ( col = 0 ; col < ilx ; col++ )
607  {
608  for ( row = 0 ; row < ily ; row++ )
609  {
610  if ( !isnan(pidata[col+row*ilx]) &&
611  !isnan(psdata[col+row*ilx]))
612  {
613  podata[col+row*ilx] = pidata[col+row*ilx] * psdata[row] ;
614 
615  }
616  }
617  }
618  return retImage ;
619 }
620 
659 cpl_image * sinfo_new_optimal_extraction_from_cube( cpl_imagelist * cube,
660  int llx,
661  int lly,
662  int halfbox_x,
663  int halfbox_y,
664  float fwhm_factor,
665  float backvariance,
666  float sky,
667  float gain,
668  float exptime,
669  const char* name,
670  cpl_table** spectrum,
671  int qc_info,
672  int* check2)
673 {
674  int col, row, z ;
675  cpl_image * averagedIm ;
676  cpl_image * retIm ;
677  double fit_par[7] ;
678  double derv_par[7] ;
679  int mpar[7] ;
680  double gfit_par[7] ;
681  double gderv_par[7] ;
682  int gmpar[7] ;
683  int fitInd ;
684  int i ;
685  double sum ;
686  double** weight=NULL ;
687  double** sinfo_psf=NULL ;
688 
689  double variance ;
690  double xdat[2] ;
691 
692  int first_col, last_col ;
693  int first_row, last_row ;
694  float norm ;
695  float sum_psf=0;
696  float sum_wgt=0;
697  float cenpix = 0;
698  float cenLambda = 0;
699  float dispersion = 0;
700  float lambda_start=0;
701 
702  int ilx=0;
703  int ily=0;
704  int inp=0;
705  float* padata=NULL;
706  float* podata=NULL;
707  float tmp_val=0;
708  cpl_propertylist* plist=NULL;
709 
710 
711  /* TODO: the sky here is not really used. We remove compilation warning */
712  sky=0;
713 
714  if ( NULL == cube )
715  {
716  sinfo_msg_error(" no cube given!\n") ;
717  return NULL ;
718  }
719 
720 
721  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
722  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
723  inp=cpl_imagelist_get_size(cube);
724 
725  if ( llx < 0 || llx + 2*halfbox_x >= ilx ||
726  lly < 0 || lly + 2*halfbox_y >= ily )
727  {
728  sinfo_msg("llx=%d, lly=%d, llx + 2*halfbox_x=%d, "
729  "lly + 2*halfbox_y=%d",
730  llx,lly,llx + 2*halfbox_x,lly + 2*halfbox_y);
731  sinfo_msg("tresh_min_x=%d, tresh_min_y=%d, "
732  "tresh_max_x=%d, tresh_max_y=%d",0,0,ilx,ily);
733  sinfo_msg_error(" lower left sinfo_edge points wrong position!") ;
734  return NULL ;
735  }
736  if ( halfbox_x <= 0 || halfbox_y <= 0 ||
737  2*halfbox_x > ilx || 2*halfbox_y > ily )
738  {
739  sinfo_msg_error(" wrong halfbox width given!") ;
740  return NULL ;
741  }
742  if ( fwhm_factor <= 0. )
743  {
744  sinfo_msg_error(" wrong fwhm_factor given!") ;
745  return NULL ;
746  }
747  if ( backvariance < 0. )
748  {
749  sinfo_msg_error(" wrong backvariance given!") ;
750  return NULL ;
751  }
752  if ( exptime <= 0. || exptime == FLAG )
753  {
754  sinfo_msg_error(" wrong exposure time given!") ;
755  return NULL ;
756  }
757 
758  /* allocate memory for spectrum */
759  if ( NULL == (retIm = cpl_image_new(1, inp,CPL_TYPE_FLOAT)) )
760  {
761  sinfo_msg_error(" memory allocation failed!\n") ;
762  return NULL ;
763  }
764  /* collapse the cube to be able to compute the weights
765  for optimal extraction */
766  if ( NULL == (averagedIm = sinfo_new_average_cube_to_image(cube)) )
767  {
768  sinfo_msg_error(" sinfo_averageCubeToImage failed!") ;
769  cpl_image_delete(retIm) ;
770  return NULL ;
771  }
772 
773  /* call the 2D-Gaussian fit routine */
774  for ( i = 0 ; i < 7 ; i++ )
775  {
776  mpar[i] = 1 ;
777  }
778 
779  if ( -1 == (fitInd = sinfo_new_fit_2d_gaussian(averagedIm,
780  fit_par,
781  derv_par,
782  mpar,
783  llx,
784  lly,
785  halfbox_x,
786  halfbox_y,
787  check2 )) )
788  {
789  sinfo_msg_warning("sinfo_fit2dGaussian failed!") ;
790  cpl_image_delete(retIm) ;
791  cpl_image_delete(averagedIm) ;
792  return NULL ;
793  }
794 
795  /* determine the PSF by using the found 2D-Gaussian */
796  sinfo_psf=sinfo_new_2Ddoublearray(ilx,ily) ;
797  sum = 0 ;
798  for ( row = 0 ; row < ily ; row++ )
799  {
800  for ( col = 0 ; col < ilx ; col++ )
801  {
802  xdat[0] = (double) col ;
803  xdat[1] = (double) row ;
804  sinfo_psf[col][row] = sinfo_new_gaussian_ellipse(xdat,fit_par) -
805  fit_par[3] ;
806  sum += sinfo_psf[col][row] ;
807  }
808  }
809  /* Scale the PSF and determine the pixel variances and the
810  normalization factor */
811  norm = 0. ;
812  variance = 0. ;
813  sum_psf=0;
814 
815  weight=sinfo_new_2Ddoublearray(ilx,ily) ;
816 
817  padata=cpl_image_get_data_float(averagedIm);
818  for ( row = 0 ; row < ily ; row++ )
819  {
820  for ( col = 0 ; col < ilx ; col++ )
821  {
822  sinfo_psf[col][row] /= sum ;
823  sum_psf += sinfo_psf[col][row];
824  if ( !isnan(padata[col+row*ilx]) )
825  {
826  /*
827  variance = (backvariance + sky + padata[col+row*ilx] /
828  exptime) / gain ;
829  */
830  variance = padata[col+row*ilx] / gain ;
831 
832  }
833  else
834  {
835  weight[col][row] = 0. ;
836  }
837  if (variance == 0.)
838  {
839  weight[col][row] = 0. ;
840  }
841  else
842  {
843 
844  weight[col][row] = sinfo_psf[col][row]/variance ;
845 
846  norm += weight[col][row] * weight[col][row] * variance ;
847 
848  }
849 
850  }
851  }
852 
853  sum_wgt=0;
854  for ( row = 0 ; row < ily ; row++ )
855  {
856  for ( col = 0 ; col < ilx ; col++ )
857  {
858  weight[col][row] /= norm;
859  sum_wgt += weight[col][row]*sinfo_psf[col][row];
860  }
861  }
862  sinfo_msg_debug("sum_psf=%f sum_wgt=%f norm=%f",sum_psf,sum_wgt,norm);
863  cpl_image_delete(averagedIm) ;
864  if ( norm == 0. )
865  {
866  sinfo_msg_error(" normalization sum is zero\n") ;
867  cpl_image_delete(retIm) ;
868  return NULL ;
869  }
870 
871  /* limit the extraction region to the Gaussian, center +- fwhmx/y *
872  cos(theta) */
873  /*
874  sinfo_msg("fit_par: %f %f %f %f %f %f %f",
875  fit_par[0],fit_par[1],fit_par[2],fit_par[3],
876  fit_par[4],fit_par[5],fit_par[6]);
877  sinfo_msg("fwhm_factor=%f",fwhm_factor);
878  */
879 
880  if(fabs(fit_par[6]) > PI_NUMB/4) {
881  fit_par[6]=0;
882  }
883  first_col = (int) (fit_par[0] -
884  fwhm_factor*fit_par[4]*cos((double)fit_par[6])) ;
885  first_col = (first_col > 2 ) ? first_col : 2;
886 
887  last_col = (int) (fit_par[0] +
888  fwhm_factor*fit_par[4]*cos((double)fit_par[6])) ;
889  last_col = (last_col < 63 ) ? last_col : 63;
890 
891  first_row = (int) (fit_par[1] -
892  fwhm_factor*fit_par[5]*cos((double)fit_par[6])) ;
893  first_row = (first_row > 2 ) ? first_row : 2;
894  last_row = (int) (fit_par[1] +
895  fwhm_factor*fit_par[5]*cos((double)fit_par[6])) ;
896  last_row = (last_row < 63 ) ? last_row : 63;
897 
898 
899  if(first_col > last_col) {
900  tmp_val=last_col;
901  last_col=first_col;
902  first_col=tmp_val;
903  }
904 
905  if(first_row > last_row) {
906  tmp_val=last_row;
907  last_col=first_row;
908  first_col=tmp_val;
909  }
910  if(abs(first_col- last_col) < 1) {
911  first_col -=1;
912  last_col +=1;
913  }
914  if(abs(first_row- last_row) < 1) {
915  first_row -=1;
916  last_row +=1;
917  }
918 
919  if ( first_col < 0 || first_row < 0 || last_col >= ilx || last_row >= ily )
920  {
921  sinfo_msg_error(" star badly centered in FOV!") ;
922  cpl_image_delete(retIm) ;
923  return NULL ;
924  }
925 
926 
927  cpl_table_new_column(*spectrum,"wavelength", CPL_TYPE_FLOAT);
928  /* cpl_table_new_column(*spectrum,"intensity" , CPL_TYPE_FLOAT); */
929  cpl_table_new_column(*spectrum,"counts_tot" , CPL_TYPE_FLOAT);
930  cpl_table_new_column(*spectrum,"counts_bkg" , CPL_TYPE_FLOAT);
931  cpl_table_new_column(*spectrum,"bkg_tot" , CPL_TYPE_FLOAT);
932 
933  if(qc_info==1) {
934  cpl_table_new_column(*spectrum,"AMP" , CPL_TYPE_FLOAT);
935  cpl_table_new_column(*spectrum,"XC" , CPL_TYPE_FLOAT);
936  cpl_table_new_column(*spectrum,"YC" , CPL_TYPE_FLOAT);
937  cpl_table_new_column(*spectrum,"BKG" , CPL_TYPE_FLOAT);
938  cpl_table_new_column(*spectrum,"FWHMX" , CPL_TYPE_FLOAT);
939  cpl_table_new_column(*spectrum,"FWHMY" , CPL_TYPE_FLOAT);
940  cpl_table_new_column(*spectrum,"ANGLE" , CPL_TYPE_FLOAT);
941  }
942  plist=cpl_propertylist_load(name,0);
943  cenpix = sinfo_pfits_get_crpix3(plist);
944  cenLambda = sinfo_pfits_get_crval3(plist);
945  dispersion = sinfo_pfits_get_cdelt3(plist);
946  cpl_propertylist_delete(plist);
947  lambda_start=cenLambda-cenpix*dispersion;
948 
949  sinfo_msg_debug("frow %d lrow %d fcol %d lcol %d",
950  first_row, last_row, first_col, last_col);
951  /* go through the planes */
952  podata=cpl_image_get_data_float(retIm);
953  for ( z = 0 ; z < inp ; z++ )
954  {
955  cpl_image* i_img=cpl_imagelist_get(cube,z);
956  float* pidata=cpl_image_get_data_float(i_img);
957  float weighted_sum = 0. ;
958  float counts_tot=0.;
959  float counts_bkg=0.;
960 
961  float bkg_tot=0.;
962 
963  if(qc_info==1) {
964  sinfo_new_fit_2d_gaussian(i_img,gfit_par,
965  gderv_par,gmpar,llx,lly,
966  halfbox_x,halfbox_y,check2);
967  }
968 
969  for ( row = first_row ; row <= last_row ; row++ )
970  {
971  for ( col = first_col ; col < last_col ; col++ )
972  {
973  if ( !isnan(pidata[col+row*ilx]) )
974  {
975 
976  weighted_sum += weight[col][row] * (pidata[col+row*ilx] -
977  fit_par[3]);
978 
979  counts_bkg += (pidata[col+row*ilx] - fit_par[3]);
980  counts_tot += (pidata[col+row*ilx]);
981  bkg_tot += fit_par[3];
982 
983  }
984  }
985  }
986 
987  if (weighted_sum == 0.)
988  {
989  weighted_sum = ZERO ;
990  counts_tot = ZERO;
991  counts_bkg = ZERO;
992  bkg_tot = ZERO;
993 
994  }
995  else
996  {
997  /*
998  weighted_sum /= norm ;
999  */
1000 
1001 
1002  }
1003 
1004  podata[z] = weighted_sum ;
1005  float lambda=lambda_start+z*dispersion;
1006  cpl_table_set_float(*spectrum,"wavelength" ,z,lambda);
1007  /* cpl_table_set_float(*spectrum,"intensity" ,z,weighted_sum); */
1008  cpl_table_set_float(*spectrum,"counts_tot" ,z,counts_tot);
1009  cpl_table_set_float(*spectrum,"counts_bkg" ,z,counts_bkg);
1010  cpl_table_set_float(*spectrum,"bkg_tot" ,z,bkg_tot);
1011  sinfo_msg_debug("w=%f I=%f b=%f a=%f",
1012  lambda,counts_tot,counts_bkg,bkg_tot);
1013  if(qc_info==1) {
1014  cpl_table_set_float(*spectrum,"AMP" ,z,gfit_par[0]);
1015  cpl_table_set_float(*spectrum,"XC" ,z,gfit_par[1]);
1016  cpl_table_set_float(*spectrum,"YC" ,z,gfit_par[2]);
1017  cpl_table_set_float(*spectrum,"BKG" ,z,gfit_par[3]);
1018  cpl_table_set_float(*spectrum,"FWHMX" ,z,gfit_par[4]);
1019  cpl_table_set_float(*spectrum,"FWHMY" ,z,gfit_par[5]);
1020  cpl_table_set_float(*spectrum,"ANGLE" ,z,gfit_par[6]);
1021  }
1022 
1023  }
1024 
1025  sinfo_new_destroy_2Ddoublearray(&sinfo_psf,ilx) ;
1026  sinfo_new_destroy_2Ddoublearray(&weight,ilx) ;
1027 
1028  return retIm ;
1029 }
1030 
1054 Vector * sinfo_new_extract_sky_from_cube( cpl_imagelist * cube,
1055  float loReject,
1056  float hiReject,
1057  int * position,
1058  int tolerance,
1059  int posindicator )
1060 {
1061  Vector * spectrum ;
1062  int x, y, z ;
1063  int n_sky ;
1064  int x_low , x_high ;
1065  int y_low , y_high ;
1066  int hi_x, lo_x ;
1067 
1068  int ilx=0;
1069  int ily=0;
1070  int inp=0;
1071  float* pidata=NULL;
1072 
1073  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1074  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1075  inp=cpl_imagelist_get_size(cube);
1076 
1077  if ( NULL == cube )
1078  {
1079  sinfo_msg_error(" no cube given!\n") ;
1080  return NullVector ;
1081  }
1082  if ( loReject < 0. || hiReject < 0. || loReject + hiReject >= 90. )
1083  {
1084  sinfo_msg_error("wrong or unrealistic loReject and hiReject values!") ;
1085  return NullVector ;
1086  }
1087  if ( position == NULL)
1088  {
1089  sinfo_msg_error(" no position array given!") ;
1090  return NullVector ;
1091  }
1092  if ( position[0] < 0 || position[1] < 0 ||
1093  position[0] > ilx || position[1] > ily )
1094  {
1095  sinfo_msg_error(" wrong position of sky spider!") ;
1096  return NullVector ;
1097  }
1098  if ( tolerance < 0 || tolerance >= ilx )
1099  {
1100  sinfo_msg_error(" wrong tolerance given!") ;
1101  return NullVector ;
1102  }
1103  if ( posindicator == 0 )
1104  {
1105  sinfo_msg_error(" no sinfo_edge indicator given!") ;
1106  return NullVector ;
1107  }
1108 
1109  /* determine the edge of the image where the sky spectra are placed */
1110  switch(posindicator)
1111  {
1112  /* lower right sinfo_edge */
1113  case 1:
1114  x_low = position[0] + tolerance ;
1115  x_high = ilx ;
1116  y_low = 0 ;
1117  y_high = position[1] - tolerance ;
1118  break ;
1119  /* upper right sinfo_edge */
1120  case 2:
1121  x_low = position[0] + tolerance ;
1122  x_high = ilx ;
1123  y_low = position[1] + tolerance ;
1124  y_high = ily ;
1125  break ;
1126  /* upper left sinfo_edge */
1127  case 3:
1128  x_low = 0 ;
1129  x_high = position[0] - tolerance ;
1130  y_low = position [1] + tolerance ;
1131  y_high = ily ;
1132  break ;
1133  default:
1134  sinfo_msg_error(" wrong position indicator index!") ;
1135  return NullVector ;
1136  break ;
1137  }
1138  if ( x_low >= ilx || x_high < 1 || y_low >= ily || y_high < 1 )
1139  {
1140  sinfo_msg_error(" tolerance too high!") ;
1141  return NullVector ;
1142  }
1143  if ( x_high - x_low != y_high - y_low )
1144  {
1145  sinfo_msg_error(" sky sinfo_edge is not a diagonal line!\n") ;
1146  return NullVector ;
1147  }
1148 
1149  /* determine the number of sky pixels in one image plane, take only
1150  the full sky pixels which are not cut by the diagonal line */
1151  n_sky = (x_high - x_low) * (x_high - x_low - 1) / 2 ;
1152  if ( n_sky <= 0 )
1153  {
1154  sinfo_msg_error(" no sky spectrum in found in cube!") ;
1155  return NullVector ;
1156  }
1157  if ( n_sky == 1 )
1158  {
1159  sinfo_msg_warning(" only one sky spectrum is taken, no averaging!") ;
1160  }
1161 
1162  /* allocate memory for the output spectrum */
1163  if ( NullVector == (spectrum = sinfo_new_vector(inp)) )
1164  {
1165  sinfo_msg_error(" could not allocate memory!") ;
1166  return NullVector ;
1167  }
1168 
1169  /* go through the image planes */
1170  for ( z = 0 ; z < inp ; z++ )
1171  {
1172  cpl_image* i_img=cpl_imagelist_get(cube,z);
1173  pidata=cpl_image_get_data_float(i_img);
1174  /* allocate memory for the sky pixels in one image plane */
1175  float* to_average=NULL;
1176  if (NULL == (to_average = (float*) cpl_calloc(n_sky, sizeof (float))))
1177  {
1178  sinfo_msg_error(" could not allocate memory!") ;
1179  sinfo_new_destroy_vector(spectrum) ;
1180  return NullVector ;
1181  }
1182  int n = 0 ;
1183  switch(posindicator)
1184  {
1185  /* lower right sinfo_edge */
1186  case 1:
1187  lo_x = x_low ;
1188  for ( y = y_low ; y < y_high - 1 ; y++ )
1189  {
1190  lo_x++ ;
1191  for ( x = lo_x ; x < x_high ; x++ )
1192  {
1193  to_average[n] = pidata[x+y*ilx] ;
1194  n++ ;
1195  }
1196  }
1197  break ;
1198  /* lower left sinfo_edge */
1199  case 2:
1200  hi_x = x_high ;
1201  for ( y = y_low ; y < y_high - 1 ; y++ )
1202  {
1203  hi_x-- ;
1204  for ( x = x_low ; x < hi_x ; x++ )
1205  {
1206  to_average[n] = pidata[x+y*ilx] ;
1207  n++ ;
1208  }
1209  }
1210  break ;
1211  /* upper right sinfo_edge */
1212  case 3:
1213  lo_x = x_high ;
1214  for ( y = y_low+1 ; y < y_high ; y++ )
1215  {
1216  lo_x-- ;
1217  for ( x = lo_x ; x < x_high ; x++ )
1218  {
1219  to_average[n] = pidata[x+y*ilx] ;
1220  n++ ;
1221  }
1222  }
1223  break ;
1224  /* upper left sinfo_edge */
1225  case 4:
1226  hi_x = x_low ;
1227  for ( y = y_low+1 ; y < y_high ; y++ )
1228  {
1229  hi_x++ ;
1230  for ( x = x_low ; x < hi_x ; x++ )
1231  {
1232  to_average[n] = pidata[x+y*ilx] ;
1233  n++ ;
1234  }
1235  }
1236  break ;
1237  default:
1238  sinfo_msg_error(" wrong position indicator index!\n") ;
1239  cpl_free(to_average) ;
1240  return NullVector ;
1241  break ;
1242  }
1243  if ( n != n_sky )
1244  {
1245  sinfo_msg_warning("number of stored sky image pixels does "
1246  "not equal number of computed sky pixels!") ;
1247  }
1248 
1249  /* now take a clean mean of the sky "image" */
1250  float cleanMean = sinfo_new_clean_mean (to_average, n, loReject, hiReject) ;
1251  if (cleanMean == FLT_MAX)
1252  {
1253  sinfo_msg_error(" could not take a clean mean!\n") ;
1254  sinfo_new_destroy_vector(spectrum) ;
1255  cpl_free(to_average) ;
1256  return NullVector ;
1257  }
1258  spectrum->data[z] = cleanMean ;
1259  cpl_free (to_average) ;
1260  }
1261 
1262  return spectrum ;
1263 }
1264 
1278 Vector * sinfo_new_sum_rectangle_of_cube_spectra( cpl_imagelist * cube,
1279  int llx,
1280  int lly,
1281  int urx,
1282  int ury )
1283 {
1284  Vector * sum ;
1285  int i, j, k, l ;
1286  int recsize ;
1287  int ilx=0;
1288  int ily=0;
1289  int inp=0;
1290 
1291 
1292 
1293 
1294  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1295  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1296  inp=cpl_imagelist_get_size(cube);
1297 
1298  if ( cube == NULL || inp < 1 )
1299  {
1300  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1301  return NullVector ;
1302  }
1303 
1304  if ((llx<0) || (llx>=ilx) ||
1305  (urx<0) || (urx>=ilx) ||
1306  (lly<0) || (lly>=ily) ||
1307  (ury<0) || (ury>=ily) ||
1308  (llx>=urx) || (lly>=ury))
1309  {
1310  sinfo_msg_error(" invalid rectangle coordinates:") ;
1311  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
1312  llx, lly, urx, ury) ;
1313  return NullVector ;
1314  }
1315 
1316  recsize = (urx - llx + 1) * (ury - lly + 1) ;
1317 
1318  /* allocate a new sinfo_vector to store the average spectral values */
1319  if (NULL == (sum = sinfo_new_vector (inp)) )
1320  {
1321  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
1322  return NullVector ;
1323  }
1324 
1325  /*------------------------------------------------------------------------
1326  * loop through the cube planes, through the x axis and the y-axis of the
1327  * plane rectangle and store pixel values in a buffer.
1328  */
1329  for ( i = 0 ; i < inp ; i++ )
1330  {
1331  cpl_image* i_img=cpl_imagelist_get(cube,i);
1332  float* pidata=cpl_image_get_data_float(i_img);
1333  int m = 0 ;
1334  pixelvalue* local_rectangle = (pixelvalue *) cpl_calloc (recsize,
1335  sizeof (pixelvalue*));
1336 
1337  for ( j = lly ; j <= ury ; j++ )
1338  {
1339  for ( k = llx ; k <= urx ; k++ )
1340  {
1341  local_rectangle[m] = pidata[k + j * ilx] ;
1342  m ++ ;
1343  }
1344  }
1345  for ( l = 0 ; l < recsize ; l++ )
1346  {
1347  if ( isnan(local_rectangle[l]) )
1348  {
1349  continue ;
1350  }
1351  sum -> data[i] += local_rectangle[l] ;
1352  }
1353  cpl_free ( local_rectangle ) ;
1354  }
1355  return sum ;
1356 }
1357 
1369 Vector * sinfo_new_sum_circle_of_cube_spectra( cpl_imagelist * cube,
1370  int centerx,
1371  int centery,
1372  int radius )
1373 {
1374  Vector * sum ;
1375  int i, j, k, l, n ;
1376  int circsize ;
1377  int ilx=0;
1378  int ily=0;
1379  int inp=0;
1380  float* pidata=NULL;
1381 
1382 
1383  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1384  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1385  inp=cpl_imagelist_get_size(cube);
1386 
1387  if ( cube == NULL || inp < 1 )
1388  {
1389  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1390  return NullVector ;
1391  }
1392 
1393  if ((centerx+radius>=ilx) ||
1394  (centery+radius>=ily) ||
1395  (centerx-radius<0) ||
1396  (centery-radius<0))
1397  {
1398  sinfo_msg_error(" invalid circular coordinates") ;
1399  return NullVector ;
1400  }
1401 
1402  n = 0 ;
1403  for ( j = centery - radius ; j <= centery + radius ; j++ )
1404  {
1405  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1406  {
1407  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1408  radius*radius )
1409  {
1410  n ++ ;
1411  }
1412  }
1413  }
1414  if (n == 0)
1415  {
1416  sinfo_msg_error (" no data points found!") ;
1417  return NullVector ;
1418  }
1419  circsize = n ;
1420 
1421  /* allocate a new sinfo_vector to store the average spectral values */
1422  if (NULL == (sum = sinfo_new_vector (inp)) )
1423  {
1424  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
1425  return NullVector ;
1426  }
1427 
1428  /*------------------------------------------------------------------------
1429  * loop through the cube planes, through the x axis and the y-axis of the
1430  * plane circle and store pixel values in a buffer.
1431  */
1432  for ( i = 0 ; i < inp ; i++ )
1433  {
1434  cpl_image* i_img=cpl_imagelist_get(cube,i);
1435  pidata=cpl_image_get_data_float(i_img);
1436  int m = 0 ;
1437  pixelvalue* circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
1438 
1439  for ( j = centery - radius ; j <= centery + radius ; j++ )
1440  {
1441  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1442  {
1443  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1444  radius*radius )
1445  {
1446  circle[m] = pidata[k + j * ilx] ;
1447  m ++ ;
1448  }
1449  }
1450  }
1451 
1452  for ( l = 0 ; l < circsize ; l++ )
1453  {
1454  if ( isnan(circle[l]) )
1455  {
1456  continue ;
1457  }
1458  sum -> data[i] += circle[l] ;
1459  }
1460  cpl_free (circle) ;
1461  }
1462  return sum ;
1463 }
1464 
1478 Vector * sinfo_new_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
1479  int llx,
1480  int lly,
1481  int urx,
1482  int ury )
1483 {
1484  Vector * mean ;
1485  int i, j, k, l ;
1486  int recsize ;
1487  int ilx=0;
1488  int ily=0;
1489  int inp=0;
1490  float* pidata=NULL;
1491 
1492  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1493  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1494  inp=cpl_imagelist_get_size(cube);
1495 
1496  if ( cube == NULL || inp < 1 )
1497  {
1498  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1499  return NullVector ;
1500  }
1501 
1502  if ((llx<0) || (llx>=ilx) ||
1503  (urx<0) || (urx>=ilx) ||
1504  (lly<0) || (lly>=ily) ||
1505  (ury<0) || (ury>=ily) ||
1506  (llx>=urx) || (lly>=ury))
1507  {
1508  sinfo_msg_error(" invalid rectangle coordinates:") ;
1509  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
1510  llx, lly, urx, ury) ;
1511  return NullVector ;
1512  }
1513 
1514  recsize = (urx - llx + 1) * (ury - lly + 1) ;
1515 
1516  /* allocate a new sinfo_vector to store the average spectral values */
1517  if (NULL == (mean = sinfo_new_vector (inp)) )
1518  {
1519  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
1520  return NullVector ;
1521  }
1522 
1523  /*------------------------------------------------------------------------
1524  * loop through the cube planes, through the x axis and the y-axis of the
1525  * plane rectangle and store pixel values in a buffer.
1526  */
1527  for ( i = 0 ; i < inp ; i++ )
1528  {
1529  cpl_image* i_img=cpl_imagelist_get(cube,i);
1530  pidata=cpl_image_get_data_float(i_img);
1531  int m = 0 ;
1532  pixelvalue* local_rectangle = (pixelvalue *) cpl_calloc (recsize,
1533  sizeof (pixelvalue*));
1534 
1535  for ( j = lly ; j <= ury ; j++ )
1536  {
1537  for ( k = llx ; k <= urx ; k++ )
1538  {
1539  local_rectangle[m] = pidata[k + j * ilx] ;
1540  m ++ ;
1541  }
1542  }
1543  int nv = 0 ;
1544  for ( l = 0 ; l < recsize ; l++ )
1545  {
1546  if ( isnan(local_rectangle[l]) )
1547  {
1548  continue ;
1549  }
1550  mean -> data[i] += local_rectangle[l] ;
1551  nv ++;
1552  }
1553  if ( nv == 0 )
1554  {
1555  mean -> data[i] = ZERO ;
1556  }
1557  else
1558  {
1559  mean -> data[i] /= nv ;
1560  }
1561  cpl_free ( local_rectangle ) ;
1562  }
1563  return mean ;
1564 }
1565 
1577 Vector *
1578 sinfo_new_mean_circle_of_cube_spectra( cpl_imagelist * cube,
1579  int centerx,
1580  int centery,
1581  int radius )
1582 {
1583  Vector * mean ;
1584  int i, j, k, l, n ;
1585  int circsize ;
1586  int ilx=0;
1587  int ily=0;
1588  int inp=0;
1589  float* pidata=NULL;
1590 
1591 
1592  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1593  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1594  inp=cpl_imagelist_get_size(cube);
1595 
1596  if ( cube == NULL || inp < 1 )
1597  {
1598  sinfo_msg_error ("no cube to take the mean of his spectra") ;
1599  return NullVector ;
1600  }
1601 
1602  if ((centerx+radius>=ilx) ||
1603  (centery+radius>=ily) ||
1604  (centerx-radius<0) ||
1605  (centery-radius<0))
1606  {
1607  sinfo_msg_error(" invalid circular coordinates") ;
1608  return NullVector ;
1609  }
1610 
1611  n = 0 ;
1612  for ( j = centery - radius ; j <= centery + radius ; j++ )
1613  {
1614  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1615  {
1616  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1617  radius*radius )
1618  {
1619  n ++ ;
1620  }
1621  }
1622  }
1623  if (n == 0)
1624  {
1625  sinfo_msg_error (" no data points found!\n") ;
1626  return NullVector ;
1627  }
1628  circsize = n ;
1629 
1630  /* allocate a new sinfo_vector to store the average spectral values */
1631  if (NULL == (mean = sinfo_new_vector (inp)) )
1632  {
1633  sinfo_msg_error (" cannot allocate a new sinfo_vector \n") ;
1634  return NullVector ;
1635  }
1636 
1637  /*------------------------------------------------------------------------
1638  * loop through the cube planes, through the x axis and the y-axis of the
1639  * plane circle and store pixel values in a buffer.
1640  */
1641  for ( i = 0 ; i < inp ; i++ )
1642  {
1643  cpl_image* i_img=cpl_imagelist_get(cube,i);
1644  pidata=cpl_image_get_data_float(i_img);
1645  int m = 0 ;
1646  pixelvalue* circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
1647 
1648  for ( j = centery - radius ; j <= centery + radius ; j++ )
1649  {
1650  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1651  {
1652  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1653  radius*radius )
1654  {
1655  circle[m] = pidata[k + j * ilx] ;
1656  m ++ ;
1657  }
1658  }
1659  }
1660 
1661  int nv = 0 ;
1662  for ( l = 0 ; l < circsize ; l++ )
1663  {
1664  if ( isnan(circle[l]) )
1665  {
1666  continue ;
1667  }
1668  mean -> data[i] += circle[l] ;
1669  nv ++;
1670  }
1671  if ( nv == 0 )
1672  {
1673  mean -> data[i] = ZERO ;
1674  }
1675  else
1676  {
1677  mean -> data[i] /= nv ;
1678  }
1679 
1680  cpl_free (circle) ;
1681  }
1682  return mean ;
1683 }
1684 
1694 Vector * sinfo_new_blackbody_spectrum( char * templateSpec, double temp )
1695 {
1696  Vector * retSpec ;
1697  int n ;
1698  double cenpix ;
1699  int npix ;
1700  double cenLambda ;
1701  double firstLambda ;
1702  double disp ;
1703  cpl_propertylist* plist=NULL;
1704 
1705  if ( NULL == templateSpec )
1706  {
1707  sinfo_msg_error (" now input image given!\n") ;
1708  return NULL ;
1709  }
1710  if ( temp < 0. )
1711  {
1712  sinfo_msg_error (" wrong temperature given!\n") ;
1713  return NULL ;
1714  }
1715  /* get the fits header information needed */
1716  if ((cpl_error_code)((plist=cpl_propertylist_load(templateSpec,0))==NULL)){
1717  sinfo_msg_error( "getting header from frame %s",templateSpec);
1718  cpl_propertylist_delete(plist) ;
1719  return NULL ;
1720  }
1721 
1722 
1723  cenpix = sinfo_pfits_get_crpix2(plist);
1724  if(cpl_error_get_code() != CPL_ERROR_NONE) {
1725  sinfo_msg_error (" cannot get CRPIX2\n") ;
1726  sinfo_free_propertylist(&plist) ;
1727  return NULL ;
1728  }
1729 
1730  cenLambda = sinfo_pfits_get_crval2(plist);
1731  if(cpl_error_get_code() != CPL_ERROR_NONE) {
1732  sinfo_msg_error (" cannot get CRVAL2\n") ;
1733  sinfo_free_propertylist(&plist) ;
1734  return NULL ;
1735  }
1736  disp = sinfo_pfits_get_cdelt2(plist);
1737  if(cpl_error_get_code() != CPL_ERROR_NONE) {
1738  sinfo_msg_error (" cannot get CDELT2\n") ;
1739  sinfo_free_propertylist(&plist) ;
1740  return NULL ;
1741  }
1742  npix = sinfo_pfits_get_naxis2(plist);
1743  if(cpl_error_get_code() != CPL_ERROR_NONE) {
1744  sinfo_msg_error (" cannot get NAXIS2\n") ;
1745  sinfo_free_propertylist(&plist) ;
1746  return NULL ;
1747  }
1748  sinfo_free_propertylist(&plist) ;
1749 
1750 
1751  if (NULL == (retSpec = sinfo_new_vector (npix)))
1752  {
1753  sinfo_msg_error (" could not allocate memory!\n") ;
1754  return NULL ;
1755  }
1756 
1757  /* shift from fits to image coordinates */
1758  cenpix-- ;
1759 
1760  firstLambda = cenLambda - cenpix * disp ;
1761  for ( n = 0 ; n < npix ; n++ )
1762  {
1763  double lambda = firstLambda + disp * (double)n ;
1764  /* convert from microns to m */
1765 
1766  lambda /= 1.0e6 ;
1767  /* replaced 1./(exp(PLANCK*SPEED_OF_LIGHT/(lambda*BOLTZMANN*temp)) - 1.)
1768  * by 1./(expm1(PLANCK*SPEED_OF_LIGHT/(lambda*BOLTZMANN*temp)))
1769  * for better accuracy if argument of exponential is small
1770  */
1771  double denom = 1./(expm1(PLANCK*SPEED_OF_LIGHT/(lambda*BOLTZMANN*temp))) ;
1772  double intens = 2.*PI_NUMB*PLANCK*SPEED_OF_LIGHT*SPEED_OF_LIGHT /
1773  pow(lambda, 5) * denom ;
1774  retSpec->data[n] = intens ;
1775  }
1776  double norm = retSpec->data[npix/2] ;
1777  for ( n = 0 ; n < npix ; n++ )
1778  {
1779  retSpec->data[n] /= norm ;
1780  }
1781 
1782  return retSpec ;
1783 }
1784 
1785 
1799 Vector * sinfo_new_median_rectangle_of_cube_spectra( cpl_imagelist * cube,
1800  int llx,
1801  int lly,
1802  int urx,
1803  int ury )
1804 {
1805  Vector * med ;
1806  int i, j, k ;
1807  int recsize ;
1808  int ilx=0;
1809  int ily=0;
1810  int inp=0;
1811  float* pidata=NULL;
1812 
1813  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1814  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1815  inp=cpl_imagelist_get_size(cube);
1816 
1817  if ( cube == NULL || inp < 1 )
1818  {
1819  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1820  return NullVector ;
1821  }
1822 
1823  if ((llx<0) || (llx>=ilx) ||
1824  (urx<0) || (urx>=ilx) ||
1825  (lly<0) || (lly>=ily) ||
1826  (ury<0) || (ury>=ily) ||
1827  (llx>=urx) || (lly>=ury))
1828  {
1829  sinfo_msg_error(" invalid rectangle coordinates:") ;
1830  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
1831  llx, lly, urx, ury) ;
1832  return NullVector ;
1833  }
1834 
1835  recsize = (urx - llx + 1) * (ury - lly + 1) ;
1836 
1837  /* allocate a new sinfo_vector to store the average spectral values */
1838  if (NULL == (med = sinfo_new_vector (inp)) )
1839  {
1840  sinfo_msg_error (" cannot allocate a new sinfo_vector \n") ;
1841  return NullVector ;
1842  }
1843 
1844  /*------------------------------------------------------------------------
1845  * loop through the cube planes, through the x axis and the y-axis of the
1846  * plane rectangle and store pixel values in a buffer.
1847  */
1848  for ( i = 0 ; i < inp ; i++ )
1849  {
1850 
1851  cpl_image* i_img=cpl_imagelist_get(cube,i);
1852  pidata=cpl_image_get_data_float(i_img);
1853  int m = 0 ;
1854  pixelvalue* local_rectangle=(pixelvalue *)cpl_calloc(recsize, sizeof (pixelvalue*));
1855 
1856  for ( j = lly ; j <= ury ; j++ )
1857  {
1858  for ( k = llx ; k <= urx ; k++ )
1859  {
1860  if ( isnan(pidata[k+j*ilx]) )
1861  {
1862  continue ;
1863  }
1864  else
1865  {
1866  local_rectangle[m] = pidata[k + j * ilx] ;
1867  m ++ ;
1868  }
1869  }
1870  }
1871  if ( m == 0 )
1872  {
1873  med->data[i] = 0. ;
1874  }
1875  else
1876  {
1877  med->data[i] = sinfo_new_median(local_rectangle, m) ;
1878  }
1879  cpl_free ( local_rectangle ) ;
1880  }
1881  return med ;
1882 }
1883 
1895 Vector * sinfo_new_median_circle_of_cube_spectra( cpl_imagelist * cube,
1896  int centerx,
1897  int centery,
1898  int radius )
1899 {
1900  Vector * med ;
1901  int i, j, k, l, n ;
1902  int circsize ;
1903  int ilx=0;
1904  int ily=0;
1905  int inp=0;
1906  float* pidata=NULL;
1907 
1908  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1909  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1910  inp=cpl_imagelist_get_size(cube);
1911 
1912  if ( cube == NULL || inp < 1 )
1913  {
1914  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1915  return NullVector ;
1916  }
1917 
1918  if ((centerx+radius>=ilx) ||
1919  (centery+radius>=ily) ||
1920  (centerx-radius<0) ||
1921  (centery-radius<0))
1922  {
1923  sinfo_msg_error(" invalid circular coordinates") ;
1924  return NullVector ;
1925  }
1926 
1927  n = 0 ;
1928  for ( j = centery - radius ; j <= centery + radius ; j++ )
1929  {
1930  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1931  {
1932  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1933  radius*radius )
1934  {
1935  n ++ ;
1936  }
1937  }
1938  }
1939  if (n == 0)
1940  {
1941  sinfo_msg_error (" no data points found!") ;
1942  return NullVector ;
1943  }
1944  circsize = n ;
1945 
1946  /* allocate a new sinfo_vector to store the average spectral values */
1947  if (NULL == (med = sinfo_new_vector (inp)) )
1948  {
1949  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
1950  return NullVector ;
1951  }
1952 
1953  /*------------------------------------------------------------------------
1954  * loop through the cube planes, through the x axis and the y-axis of the
1955  * plane circle and store pixel values in a buffer.
1956  */
1957  for ( i = 0 ; i < inp ; i++ )
1958  {
1959  cpl_image* i_img=cpl_imagelist_get(cube,i);
1960  pidata=cpl_image_get_data_float(i_img);
1961  int m = 0 ;
1962  pixelvalue* circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
1963 
1964  for ( j = centery - radius ; j <= centery + radius ; j++ )
1965  {
1966  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1967  {
1968  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1969  radius*radius )
1970  {
1971  circle[m] = pidata[k + j * ilx] ;
1972  m ++ ;
1973  }
1974  }
1975  }
1976 
1977  int nv = 0 ;
1978  for ( l = 0 ; l < circsize ; l++ )
1979  {
1980  if ( isnan(circle[l]) )
1981  {
1982  continue ;
1983  }
1984  med -> data[i] += circle[l] ;
1985  nv ++;
1986  }
1987  if ( nv == 0 )
1988  {
1989  med->data[i] = 0. ;
1990  }
1991  else
1992  {
1993  med->data[i] = sinfo_new_median(circle, nv) ;
1994  }
1995  cpl_free (circle) ;
1996  }
1997  return med ;
1998 }
1999 
2013 Vector *
2014 sinfo_new_cleanmean_rectangle_of_cube_spectra( cpl_imagelist * cube,
2015  int llx,
2016  int lly,
2017  int urx,
2018  int ury,
2019  float lo_reject,
2020  float hi_reject )
2021 {
2022  Vector * clean ;
2023  int i, j, k ;
2024  int recsize ;
2025  int ilx=0;
2026  int ily=0;
2027  int inp=0;
2028  float* pidata=NULL;
2029 
2030 
2031  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
2032  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
2033  inp=cpl_imagelist_get_size(cube);
2034 
2035  if ( cube == NULL || inp < 1 )
2036  {
2037  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
2038  return NullVector ;
2039  }
2040 
2041  if ((llx<0) || (llx>=ilx) ||
2042  (urx<0) || (urx>=ilx) ||
2043  (lly<0) || (lly>=ily) ||
2044  (ury<0) || (ury>=ily) ||
2045  (llx>=urx) || (lly>=ury))
2046  {
2047  sinfo_msg_error(" invalid rectangle coordinates:") ;
2048  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
2049  llx, lly, urx, ury) ;
2050  return NullVector ;
2051  }
2052 
2053  recsize = (urx - llx + 1) * (ury - lly + 1) ;
2054 
2055  /* allocate a new sinfo_vector to store the average spectral values */
2056  if (NULL == (clean = sinfo_new_vector (inp)) )
2057  {
2058  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
2059  return NullVector ;
2060  }
2061 
2062  /*------------------------------------------------------------------------
2063  * loop through the cube planes, through the x axis and the y-axis of the
2064  * plane rectangle and store pixel values in a buffer.
2065  */
2066  for ( i = 0 ; i < inp ; i++ )
2067  {
2068  cpl_image* i_img=cpl_imagelist_get(cube,i);
2069  pidata=cpl_image_get_data_float(i_img);
2070  int m = 0 ;
2071  pixelvalue* local_rectangle=(pixelvalue *) cpl_calloc(recsize, sizeof (pixelvalue*));
2072 
2073  for ( j = lly ; j <= ury ; j++ )
2074  {
2075  for ( k = llx ; k <= urx ; k++ )
2076  {
2077  if ( isnan(pidata[k+j*ilx]) )
2078  {
2079  continue ;
2080  }
2081  else
2082  {
2083  local_rectangle[m] = pidata[k + j * ilx] ;
2084  m ++ ;
2085  }
2086  }
2087  }
2088  if ( m == 0 )
2089  {
2090  clean->data[i] = 0. ;
2091  }
2092  else
2093  {
2094  clean->data[i] = sinfo_new_clean_mean(local_rectangle, m,
2095  lo_reject, hi_reject) ;
2096  }
2097  cpl_free ( local_rectangle ) ;
2098  }
2099  return clean ;
2100 }
2101 
2113 Vector *
2114 sinfo_new_cleanmean_circle_of_cube_spectra( cpl_imagelist * cube,
2115  int centerx,
2116  int centery,
2117  int radius,
2118  float lo_reject,
2119  float hi_reject )
2120 {
2121  Vector * clean ;
2122  int i, j, k, l, n ;
2123  int circsize ;
2124  int ilx=0;
2125  int ily=0;
2126  int inp=0;
2127  float* pidata=NULL;
2128 
2129  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
2130  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
2131  inp=cpl_imagelist_get_size(cube);
2132 
2133  if ( cube == NULL || inp < 1 )
2134  {
2135  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
2136  return NullVector ;
2137  }
2138 
2139  if ((centerx+radius>=ilx) ||
2140  (centery+radius>=ily) ||
2141  (centerx-radius<0) ||
2142  (centery-radius<0))
2143  {
2144  sinfo_msg_error(" invalid circular coordinates") ;
2145  return NullVector ;
2146  }
2147 
2148  n = 0 ;
2149  for ( j = centery - radius ; j <= centery + radius ; j++ )
2150  {
2151  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
2152  {
2153  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
2154  radius*radius )
2155  {
2156  n ++ ;
2157  }
2158  }
2159  }
2160  if (n == 0)
2161  {
2162  sinfo_msg_error (" no data points found!\n") ;
2163  return NullVector ;
2164  }
2165  circsize = n ;
2166 
2167  /* allocate a new sinfo_vector to store the average spectral values */
2168  if (NULL == (clean = sinfo_new_vector (inp)) )
2169  {
2170  sinfo_msg_error (" cannot allocate a new sinfo_vector \n") ;
2171  return NullVector ;
2172  }
2173 
2174  /*------------------------------------------------------------------------
2175  * loop through the cube planes, through the x axis and the y-axis of the
2176  * plane circle and store pixel values in a buffer.
2177  */
2178  for ( i = 0 ; i < inp ; i++ )
2179  {
2180  cpl_image* i_img=cpl_imagelist_get(cube,i);
2181  pidata=cpl_image_get_data_float(i_img);
2182  int m = 0 ;
2183  pixelvalue* circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
2184 
2185  for ( j = centery - radius ; j <= centery + radius ; j++ )
2186  {
2187  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
2188  {
2189  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
2190  radius*radius )
2191  {
2192  circle[m] = pidata[k + j * ilx] ;
2193  m ++ ;
2194  }
2195  }
2196  }
2197 
2198  int nv = 0 ;
2199  for ( l = 0 ; l < circsize ; l++ )
2200  {
2201  if ( isnan(circle[l]) )
2202  {
2203  continue ;
2204  }
2205  clean -> data[i] += circle[l] ;
2206  nv ++;
2207  }
2208  if ( nv == 0 )
2209  {
2210  clean->data[i] = 0. ;
2211  }
2212  else
2213  {
2214  clean->data[i] = sinfo_new_clean_mean(circle, nv,
2215  lo_reject, hi_reject) ;
2216  }
2217  cpl_free (circle) ;
2218  }
2219  return clean ;
2220 }
2221 
2233 float *
2234 sinfo_new_shift_array ( float * input, int n_elements,
2235  float shift, double * ker )
2236 {
2237  float * shifted ;
2238  int samples = KERNEL_SAMPLES ;
2239  int i ;
2240  int tabx ;
2241  float value ;
2242  /*size_t pos ;*/
2243  register float * pix ;
2244 
2245  /* error handling: test entries */
2246  if (input==NULL)
2247  {
2248  sinfo_msg_error(" no input array given!\n") ;
2249  return NULL ;
2250  }
2251  if (n_elements<=0)
2252  {
2253  sinfo_msg_error(" wrong number of elements in input array given!\n") ;
2254  return NULL ;
2255  }
2256 
2257  shifted = (float*) cpl_calloc(n_elements, sizeof(float)) ;
2258 
2259  /* Shifting by a zero offset returns a copy of the input image */
2260  if ((fabs(shift)<1e-2))
2261  {
2262  for (i = 0 ; i < n_elements ; i++ )
2263  {
2264  shifted[i] = input[i] ;
2265  }
2266  return shifted ;
2267  }
2268 
2269  int mid = (int)samples/(int)2 ;
2270 
2271  for (i=1 ; i< n_elements-2 ; i++)
2272  {
2273  float fx = (float)i+shift ;
2274  int px = sinfo_new_nint(fx) ;
2275  float rx = fx - (float)px ;
2276  pix = input ;
2277 
2278  if ((px>=1) && (px<(n_elements-2)))
2279  {
2280  tabx = (int)(fabs((float)mid * rx)) ;
2281  /* exclude blank (ZERO) pixels from interpolation */
2282  if (isnan(pix[i]))
2283  {
2284  value = ZERO ;
2285  }
2286  else
2287  {
2288  if (isnan(pix[i-1]))
2289  {
2290  pix[i-1] = 0. ;
2291  }
2292  if (isnan(pix[i+1]))
2293  {
2294  pix[i+1] = 0. ;
2295  }
2296  if (isnan(pix[i+2]))
2297  {
2298  pix[i+2] = 0. ;
2299  }
2300 
2301  /*
2302  * Sum up over 4 closest pixel values,
2303  * weighted by interpolation kernel values
2304  */
2305  value = pix[i-1] * ker[mid+tabx] +
2306  pix[i] * ker[tabx] +
2307  pix[i+1] * ker[mid-tabx] +
2308  pix[i+2] * ker[samples-tabx-1] ;
2309  /*
2310  * Also sum up interpolation kernel coefficients
2311  * for further normalization
2312  */
2313  float norm = ker[mid+tabx] +
2314  ker[tabx] +
2315  ker[mid-tabx] +
2316  ker[samples-tabx-1] ;
2317  if (fabs(norm) > 1e-4)
2318  {
2319  value /= norm ;
2320  }
2321  }
2322  }
2323  else
2324  {
2325  value = 0.0 ;
2326  }
2327  if ( isnan(value) )
2328  {
2329  shifted[i] = ZERO ;
2330  }
2331  else
2332  {
2333  shifted[i] = value ;
2334  }
2335  }
2336  return shifted ;
2337 }
2338 
2339 
2340 /*--------------------------------------------------------------------------*/
2341 
2353 cpl_image *
2354 sinfo_new_div_image_by_spectrum( cpl_image * image, cpl_image * spectrum )
2355 {
2356  int col, row ;
2357  cpl_image * retImage ;
2358  int ilx=0;
2359  int ily=0;
2360 
2361  /* int slx=0; */
2362  int sly=0;
2363 
2364  float* pidata=NULL;
2365  float* psdata=NULL;
2366  float* podata=NULL;
2367 
2368  if ( image == NULL )
2369  {
2370  sinfo_msg_error("no image given!") ;
2371  return NULL ;
2372  }
2373  ilx=cpl_image_get_size_x(image);
2374  ily=cpl_image_get_size_y(image);
2375 
2376 
2377  if ( spectrum == NULL )
2378  {
2379  sinfo_msg_error("no spectrum image given!") ;
2380  return NULL ;
2381  }
2382  /* slx=cpl_image_get_size_x(spectrum); */
2383  sly=cpl_image_get_size_y(spectrum);
2384 
2385  if ( sly != ily )
2386  {
2387  sinfo_msg_error("images are not compatible in pixel length!") ;
2388  return NULL ;
2389  }
2390  if ( NULL == (retImage = cpl_image_duplicate(image)) )
2391  {
2392  sinfo_msg_error("could not copy original image!") ;
2393  return NULL ;
2394  }
2395  pidata=cpl_image_get_data_float(image);
2396  psdata=cpl_image_get_data_float(spectrum);
2397  podata=cpl_image_get_data_float(retImage);
2398 
2399  for ( col = 0 ; col < ilx ; col++ )
2400  {
2401  for ( row = 0 ; row < ily ; row++ )
2402  {
2403  if ( !isnan(pidata[col+row*ilx]) &&
2404  !isnan(psdata[col+row*ilx]))
2405  {
2406  podata[col+row*ilx] = pidata[col+row*ilx] / psdata[row] ;
2407  }
2408  }
2409  }
2410  return retImage ;
2411 }
2412 
2413 /*---------------------------------------------------------------------------
2414  Function : sinfo_new_clean_mean_circle_of_cube_spectra()
2415  In : cube: 1 allocated cube,
2416  centerx, centery: center pixel of circular aperture
2417  in image coordinates
2418  radius: integer radius of circular aperture
2419  Out : result spectrum vector
2420  Job : clean averaging routine for a reduced data to get
2421  a better spectral S/N only for a circular aperture.
2422  ---------------------------------------------------------------------------*/
2423 
2424 Vector * sinfo_new_clean_mean_circle_of_cube_spectra(cpl_imagelist * cube,
2425  int centerx,
2426  int centery,
2427  int radius,
2428  float lo_reject,
2429  float hi_reject )
2430 {
2431  Vector * clean ;
2432  int i, j, k, l, n ;
2433  int circsize ;
2434  int lx=0;
2435  int ly=0;
2436  int lz=0;
2437  float* pidata=NULL;
2438  cpl_image* img=NULL;
2439 
2440  lz=cpl_imagelist_get_size(cube);
2441 
2442  if ( cube == NULL || lz < 1 )
2443  {
2444  sinfo_msg_error (" no cube to take the mean of his spectra") ;
2445  return NullVector ;
2446  }
2447  img=cpl_imagelist_get(cube,0);
2448  lx=cpl_image_get_size_x(img);
2449  ly=cpl_image_get_size_y(img);
2450 
2451  if ((centerx+radius>=lx) ||
2452  (centery+radius>=ly) ||
2453  (centerx-radius<0) ||
2454  (centery-radius<0))
2455  {
2456  sinfo_msg_error(" invalid circular coordinates") ;
2457  return NullVector ;
2458  }
2459 
2460  n = 0 ;
2461  for ( j = centery - radius ; j <= centery + radius ; j++ )
2462  {
2463  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
2464  {
2465  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
2466  radius*radius )
2467  {
2468  n ++ ;
2469  }
2470  }
2471  }
2472  if (n == 0)
2473  {
2474  sinfo_msg_error (" no data points found!") ;
2475  return NullVector ;
2476  }
2477  circsize = n ;
2478 
2479  /* allocate a new vector to store the average spectral values */
2480  if (NULL == (clean = sinfo_new_vector (lz)) )
2481  {
2482  sinfo_msg_error (" cannot allocate a new vector") ;
2483  return NullVector ;
2484  }
2485 
2486  /*------------------------------------------------------------------------
2487  * loop through the cube planes, through the x axis and the y-axis of the
2488  * plane circle and store pixel values in a buffer.
2489  */
2490  for ( i = 0 ; i < lz ; i++ )
2491  {
2492  img=cpl_imagelist_get(cube,i);
2493  pidata=cpl_image_get_data(img);
2494  int m = 0 ;
2495  pixelvalue* circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
2496 
2497  for ( j = centery - radius ; j <= centery + radius ; j++ )
2498  {
2499  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
2500  {
2501  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
2502  radius*radius )
2503  {
2504  circle[m] = pidata[k + j * lx] ;
2505  m ++ ;
2506  }
2507  }
2508  }
2509 
2510  int nv = 0 ;
2511  for ( l = 0 ; l < circsize ; l++ )
2512  {
2513  if ( isnan(circle[l]) )
2514  {
2515  continue ;
2516  }
2517  clean -> data[i] += circle[l] ;
2518  nv ++;
2519  }
2520  if ( nv == 0 )
2521  {
2522  clean->data[i] = 0. ;
2523  }
2524  else
2525  {
2526  clean->data[i] = sinfo_new_clean_mean(circle, nv,
2527  lo_reject, hi_reject) ;
2528  }
2529  cpl_free (circle) ;
2530  }
2531  return clean ;
2532 }
2533 
2534 
2535 
2536 /*---------------------------------------------------------------------------
2537  Function : sinfo_new_clean_mean_rectangle_of_cube_spectra()
2538  In : cube: 1 allocated cube,
2539  llx, lly, urx, ury: lower left and upper right
2540  position of rectangle in x-y plane ,
2541  image coordinates 0...
2542  Out : result spectrum vector
2543  Job : clean averaging routine for a reduced data to get a
2544  better spectral S/N only for a rectangular aperture.
2545  ---------------------------------------------------------------------------*/
2546 
2547 Vector * sinfo_new_clean_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
2548  int llx,
2549  int lly,
2550  int urx,
2551  int ury,
2552  float lo_reject,
2553  float hi_reject )
2554 {
2555  Vector * clean ;
2556  int i, j, k;
2557  int recsize ;
2558  int lx=0;
2559  int ly=0;
2560  int lz=0;
2561  float* pidata=0;
2562  cpl_image* img=NULL;
2563 
2564  lz=cpl_imagelist_get_size(cube);
2565 
2566  if ( cube == NULL || lz < 1 )
2567  {
2568  sinfo_msg_error (" no cube to take the mean of his spectra") ;
2569  return NullVector ;
2570  }
2571  img=cpl_imagelist_get(cube,0);
2572  lx=cpl_image_get_size_x(img);
2573  ly=cpl_image_get_size_y(img);
2574 
2575  if ((llx<0) || (llx>=lx) ||
2576  (urx<0) || (urx>=lx) ||
2577  (lly<0) || (lly>=ly) ||
2578  (ury<0) || (ury>=ly) ||
2579  (llx>=urx) || (lly>=ury))
2580  {
2581  sinfo_msg_error(" invalid rectangle coordinates:") ;
2582  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
2583  llx, lly, urx, ury) ;
2584  return NullVector ;
2585  }
2586 
2587  recsize = (urx - llx + 1) * (ury - lly + 1) ;
2588 
2589  /* allocate a new vector to store the average spectral values */
2590  if (NULL == (clean = sinfo_new_vector (lz)) )
2591  {
2592  sinfo_msg_error (" cannot allocate a new vector") ;
2593  return NullVector ;
2594  }
2595 
2596  /*------------------------------------------------------------------------
2597  * loop through the cube planes, through the x axis and the y-axis of the
2598  * plane rectangle and store pixel values in a buffer.
2599  */
2600  for ( i = 0 ; i < lz ; i++ )
2601  {
2602  int m = 0 ;
2603  pixelvalue* rectangle = (pixelvalue *) cpl_calloc (recsize, sizeof (pixelvalue*));
2604  img=cpl_imagelist_get(cube,i);
2605  pidata=cpl_image_get_data(img);
2606  for ( j = lly ; j <= ury ; j++ )
2607  {
2608  for ( k = llx ; k <= urx ; k++ )
2609  {
2610  if ( isnan(pidata[k+j*lx]) )
2611  {
2612  continue ;
2613  }
2614  else
2615  {
2616  rectangle[m] = pidata[k + j * lx] ;
2617  m ++ ;
2618  }
2619  }
2620  }
2621  if ( m == 0 )
2622  {
2623  clean->data[i] = 0. ;
2624  }
2625  else
2626  {
2627  clean->data[i] = sinfo_new_clean_mean(rectangle, m,
2628  lo_reject, hi_reject) ;
2629  }
2630  cpl_free ( rectangle ) ;
2631  }
2632  return clean ;
2633 }
2634 
2635 /*--------------------------------------------------------------------------*/
#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