SINFONI Pipeline Reference Manual  2.5.2
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 amp=0;
235  double wav=0;
236 
237  double step=0;
238  double ws=0;
239  double we=0;
240  double wc=0;
241  cpl_propertylist* plist=NULL;
242 
243  if(spc == NULL){
244  sinfo_msg_error("Input image is null");
245  return -1;
246  }
247 
248  pidata = cpl_image_get_data_const(spc);
249  nx=cpl_image_get_size_x(spc);
250  ny=cpl_image_get_size_y(spc);
251 
252  if((nx == 0) || (ny == 0)) {
253  sinfo_msg_error("Input image has improper size: nx=%d ny=%d",nx,ny);
254  return -1;
255  }
256  if((nx > 1) && (ny > 1)) {
257  sinfo_msg_error("Input image has improper size: nx=%d ny=%d",nx,ny);
258  return -1;
259  }
260 
261 
262  nraw=nx*ny;
263  *tbl = cpl_table_new(nraw);
264  cpl_table_new_column(*tbl,"WAVE",CPL_TYPE_DOUBLE);
265  cpl_table_new_column(*tbl,"INT",CPL_TYPE_DOUBLE);
266 
267 
268  if ((cpl_error_code)((plist = cpl_propertylist_load(filename, 0)) == NULL)) {
269  sinfo_msg_error( "getting header from reference frame %s",filename);
270  cpl_propertylist_delete(plist) ;
271  return -1 ;
272  }
273 
274 
275  if(nx>1) {
276  step=sinfo_pfits_get_cdelt1(plist);
277  wc=sinfo_pfits_get_crval1(plist);
278  } else {
279 
280  step=sinfo_pfits_get_cdelt2(plist);
281  wc=sinfo_pfits_get_crval2(plist);
282  }
283 
284  ws=wc-nraw*step/2;
285  we=wc+nraw*step/2;
286  wav=ws;
287  sinfo_msg("ws=%f we=%f step=%f",ws,we,step);
288  cpl_table_set_double(*tbl,"WAVE",0,wav);
289  cpl_table_set_double(*tbl,"INT",0,pidata[i]);
290 
291  for(i=1;i<nraw;i++) {
292  wav+=step;
293  amp=(double)pidata[i];
294  cpl_table_set_double(*tbl,"WAVE",i,wav);
295  cpl_table_set_double(*tbl,"INT",i,amp);
296  }
297  cpl_propertylist_delete(plist);
298  return 0;
299 
300 
301 }
302 
303 
304 
314 Vector * sinfo_new_vector( ulong32 n_elements )
315 {
316  Vector * local_new_vector ;
317 
318  if ( n_elements <= 0 )
319  {
320  sinfo_msg_error (" wrong number of elements\n") ;
321  return NullVector ;
322  }
323 
324  /* allocate memory for a sinfo_vector with the given number of elements */
325  local_new_vector = (Vector *) cpl_malloc (sizeof (Vector)) ;
326  local_new_vector -> n_elements = n_elements ;
327  local_new_vector -> data = (pixelvalue *) cpl_calloc (n_elements,
328  sizeof (pixelvalue)) ;
329 
330  return local_new_vector ;
331 }
332 
340 void sinfo_free_svector( Vector **svector )
341 {
342  if ( *svector != NULL )
343  {
344 
345  if((*svector) -> data != NULL) {
346  cpl_free ( (*svector) -> data ) ;
347  (*svector)->data = NULL;
348  }
349  cpl_free ( *svector ) ;
350  *svector = NULL;
351  }
352  return ;
353 }
354 
362 void sinfo_new_destroy_vector( Vector *sinfo_vector )
363 {
364  if ( sinfo_vector == NULL )
365  {
366  sinfo_msg_error(" NULL Vector given!\n") ;
367  return ;
368  }
369 
370  cpl_free ( sinfo_vector -> data ) ;
371  cpl_free ( sinfo_vector ) ;
372 }
373 
382 cpl_image * sinfo_new_vector_to_image( Vector * spectrum )
383 {
384  cpl_image * returnIm ;
385  int i ;
386 
387  float* podata=NULL;
388 
389 
390  if ( spectrum == NULL )
391  {
392  sinfo_msg_error(" no spectrum given!\n") ;
393  return NULL ;
394  }
395 
396  /* allocate memory */
397  if ( NULL == (returnIm = cpl_image_new(1, spectrum->n_elements,
398  CPL_TYPE_FLOAT)) )
399  {
400  sinfo_msg_error(" no spectrum given!\n") ;
401  sinfo_new_destroy_vector(spectrum) ;
402  return NULL ;
403  }
404 
405  podata=cpl_image_get_data_float(returnIm);
406  for ( i = 0 ; i < spectrum->n_elements ; i++ )
407  {
408  podata[i] = spectrum -> data[i] ;
409  }
410 
411  sinfo_new_destroy_vector (spectrum) ;
412  return returnIm ;
413 }
414 
423 Vector * sinfo_new_image_to_vector( cpl_image * spectrum )
424 {
425  Vector * returnVector ;
426  int i ;
427  int ilx=0;
428  int ily=0;
429 
430  float* pidata=NULL;
431 
432  if ( spectrum == NULL )
433  {
434  sinfo_msg_error(" no spectrum given!") ;
435  return NULL ;
436  }
437  ilx=cpl_image_get_size_x(spectrum);
438  ily=cpl_image_get_size_y(spectrum);
439 
440  /* allocate memory */
441  if ( NULL == (returnVector = sinfo_new_vector(ilx*ily)) )
442  {
443  sinfo_msg_error(" cannot allocate memory!") ;
444  cpl_image_delete(spectrum) ;
445  return NULL ;
446  }
447 
448  pidata=cpl_image_get_data_float(spectrum);
449  for ( i = 0 ; i < (int) ilx*ily ; i++ )
450  {
451  returnVector -> data[i] = pidata[i] ;
452  }
453 
454  cpl_image_delete (spectrum) ;
455  return returnVector ;
456 }
457 
470 cpl_image *
471 sinfo_new_extract_spectrum_from_resampled_flat( cpl_image * resflat,
472  float loreject,
473  float hireject )
474 {
475  cpl_image * retIm ;
476  int col, row ;
477  int n ;
478  float* array=NULL ;
479  float cleanMean ;
480  Vector * spectrum ;
481 
482  int ilx=0;
483  int ily=0;
484 
485  float* pidata=NULL;
486 
487  if ( resflat == NULL )
488  {
489  sinfo_msg_error(" no flatfield given!") ;
490  return NULL ;
491  }
492  ilx=cpl_image_get_size_x(resflat);
493  ily=cpl_image_get_size_y(resflat);
494 
495  /* allocate memory */
496  if ( NullVector == (spectrum = sinfo_new_vector(ily) ) )
497  {
498  sinfo_msg_error(" could not allocate memory!") ;
499  return NULL ;
500  }
501 
502  array=cpl_calloc(ily,sizeof(float)) ;
503 
504  pidata=cpl_image_get_data_float(resflat);
505  for ( row = 0 ; row < ily ; row++ )
506  {
507  n = 0 ;
508  for ( col = 0 ; col < ilx ; col++ )
509  {
510  if ( !isnan(pidata[col + row*ilx]) )
511  {
512  array[n] = pidata[col+row*ilx] ;
513  n++ ;
514  }
515  }
516  if ( n == 0 )
517  {
518  sinfo_msg_warning(" only bad pixels in row: %d!", row) ;
519  cleanMean = ZERO ;
520  }
521  else
522  {
523  if ( FLT_MAX == (cleanMean = sinfo_new_clean_mean(array, n,
524  loreject,
525  hireject)) )
526  {
527  sinfo_msg_error(" could not do sinfo_clean_mean!") ;
528  sinfo_new_destroy_vector(spectrum) ;
529  return NULL ;
530  }
531  }
532  spectrum->data[row] = cleanMean ;
533  }
534  if ( NULL == ( retIm = sinfo_new_vector_to_image( spectrum ) ) )
535  {
536  sinfo_msg_error(" could not do sinfo_vectorToImage!") ;
537  sinfo_new_destroy_vector(spectrum) ;
538  return NULL ;
539  }
540  cpl_free(array) ;
541 
542  return retIm ;
543 }
544 
558 cpl_image *
559 sinfo_new_multiply_image_with_spectrum( cpl_image * image,
560  cpl_image * spectrum )
561 {
562  int col, row ;
563  cpl_image * retImage ;
564 
565 
566  int ilx=0;
567  int ily=0;
568  /* int slx=0; */
569  int sly=0;
570 
571  float* pidata=NULL;
572  float* psdata=NULL;
573  float* podata=NULL;
574 
575 
576  if ( image == NULL )
577  {
578  sinfo_msg_error(" no image given!") ;
579  return NULL ;
580  }
581  ilx=cpl_image_get_size_x(image);
582  ily=cpl_image_get_size_y(image);
583 
584  if ( spectrum == NULL )
585  {
586  sinfo_msg_error(" no spectrum image given!") ;
587  return NULL ;
588  }
589  /* slx=cpl_image_get_size_x(spectrum); */
590  sly=cpl_image_get_size_y(spectrum);
591 
592  if ( sly != ily )
593  {
594  sinfo_msg_error(" images are not compatible in pixel length!") ;
595  return NULL ;
596  }
597 
598  if ( NULL == (retImage = cpl_image_duplicate(image)) )
599  {
600  sinfo_msg_error(" could not copy original image!\n") ;
601  return NULL ;
602  }
603 
604  pidata=cpl_image_get_data_float(image);
605  psdata=cpl_image_get_data_float(spectrum);
606  podata=cpl_image_get_data_float(retImage);
607 
608  for ( col = 0 ; col < ilx ; col++ )
609  {
610  for ( row = 0 ; row < ily ; row++ )
611  {
612  if ( !isnan(pidata[col+row*ilx]) &&
613  !isnan(psdata[col+row*ilx]))
614  {
615  podata[col+row*ilx] = pidata[col+row*ilx] * psdata[row] ;
616 
617  }
618  }
619  }
620  return retImage ;
621 }
622 
661 cpl_image * sinfo_new_optimal_extraction_from_cube( cpl_imagelist * cube,
662  int llx,
663  int lly,
664  int halfbox_x,
665  int halfbox_y,
666  float fwhm_factor,
667  float backvariance,
668  float sky,
669  float gain,
670  float exptime,
671  const char* name,
672  cpl_table** spectrum,
673  int qc_info,
674  int* check2)
675 {
676  int col, row, z ;
677  cpl_image * averagedIm ;
678  cpl_image * retIm ;
679  double fit_par[7] ;
680  double derv_par[7] ;
681  int mpar[7] ;
682  double gfit_par[7] ;
683  double gderv_par[7] ;
684  int gmpar[7] ;
685  int fitInd ;
686  int i ;
687  double sum ;
688  double** weight=NULL ;
689  double** sinfo_psf=NULL ;
690 
691  double variance ;
692  double xdat[2] ;
693  float weighted_sum ;
694  float counts_tot ;
695  float counts_bkg ;
696  float bkg_tot ;
697 
698 
699  int first_col, last_col ;
700  int first_row, last_row ;
701  float norm ;
702  float sum_psf=0;
703  float sum_wgt=0;
704  float cenpix = 0;
705  float cenLambda = 0;
706  float dispersion = 0;
707  float lambda=0;
708  float lambda_start=0;
709 
710  int ilx=0;
711  int ily=0;
712  int inp=0;
713  float* pidata=NULL;
714  float* padata=NULL;
715  float* podata=NULL;
716  float tmp_val=0;
717  cpl_propertylist* plist=NULL;
718  cpl_image* i_img=NULL;
719 
720 
721  /* TODO: the sky here is not really used. We remove compilation warning */
722  sky=0;
723 
724  if ( NULL == cube )
725  {
726  sinfo_msg_error(" no cube given!\n") ;
727  return NULL ;
728  }
729 
730 
731  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
732  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
733  inp=cpl_imagelist_get_size(cube);
734 
735  if ( llx < 0 || llx + 2*halfbox_x >= ilx ||
736  lly < 0 || lly + 2*halfbox_y >= ily )
737  {
738  sinfo_msg("llx=%d, lly=%d, llx + 2*halfbox_x=%d, "
739  "lly + 2*halfbox_y=%d",
740  llx,lly,llx + 2*halfbox_x,lly + 2*halfbox_y);
741  sinfo_msg("tresh_min_x=%d, tresh_min_y=%d, "
742  "tresh_max_x=%d, tresh_max_y=%d",0,0,ilx,ily);
743  sinfo_msg_error(" lower left sinfo_edge points wrong position!") ;
744  return NULL ;
745  }
746  if ( halfbox_x <= 0 || halfbox_y <= 0 ||
747  2*halfbox_x > ilx || 2*halfbox_y > ily )
748  {
749  sinfo_msg_error(" wrong halfbox width given!") ;
750  return NULL ;
751  }
752  if ( fwhm_factor <= 0. )
753  {
754  sinfo_msg_error(" wrong fwhm_factor given!") ;
755  return NULL ;
756  }
757  if ( backvariance < 0. )
758  {
759  sinfo_msg_error(" wrong backvariance given!") ;
760  return NULL ;
761  }
762  if ( exptime <= 0. || exptime == FLAG )
763  {
764  sinfo_msg_error(" wrong exposure time given!") ;
765  return NULL ;
766  }
767 
768  /* allocate memory for spectrum */
769  if ( NULL == (retIm = cpl_image_new(1, inp,CPL_TYPE_FLOAT)) )
770  {
771  sinfo_msg_error(" memory allocation failed!\n") ;
772  return NULL ;
773  }
774  /* collapse the cube to be able to compute the weights
775  for optimal extraction */
776  if ( NULL == (averagedIm = sinfo_new_average_cube_to_image(cube)) )
777  {
778  sinfo_msg_error(" sinfo_averageCubeToImage failed!") ;
779  cpl_image_delete(retIm) ;
780  return NULL ;
781  }
782 
783  /* call the 2D-Gaussian fit routine */
784  for ( i = 0 ; i < 7 ; i++ )
785  {
786  mpar[i] = 1 ;
787  }
788 
789  if ( -1 == (fitInd = sinfo_new_fit_2d_gaussian(averagedIm,
790  fit_par,
791  derv_par,
792  mpar,
793  llx,
794  lly,
795  halfbox_x,
796  halfbox_y,
797  check2 )) )
798  {
799  sinfo_msg_warning("sinfo_fit2dGaussian failed!") ;
800  cpl_image_delete(retIm) ;
801  cpl_image_delete(averagedIm) ;
802  return NULL ;
803  }
804 
805  /* determine the PSF by using the found 2D-Gaussian */
806  sinfo_psf=sinfo_new_2Ddoublearray(ilx,ily) ;
807  sum = 0 ;
808  for ( row = 0 ; row < ily ; row++ )
809  {
810  for ( col = 0 ; col < ilx ; col++ )
811  {
812  xdat[0] = (double) col ;
813  xdat[1] = (double) row ;
814  sinfo_psf[col][row] = sinfo_new_gaussian_ellipse(xdat,fit_par) -
815  fit_par[3] ;
816  sum += sinfo_psf[col][row] ;
817  }
818  }
819  /* Scale the PSF and determine the pixel variances and the
820  normalization factor */
821  norm = 0. ;
822  variance = 0. ;
823  sum_psf=0;
824 
825  weight=sinfo_new_2Ddoublearray(ilx,ily) ;
826 
827  padata=cpl_image_get_data_float(averagedIm);
828  for ( row = 0 ; row < ily ; row++ )
829  {
830  for ( col = 0 ; col < ilx ; col++ )
831  {
832  sinfo_psf[col][row] /= sum ;
833  sum_psf += sinfo_psf[col][row];
834  if ( !isnan(padata[col+row*ilx]) )
835  {
836  /*
837  variance = (backvariance + sky + padata[col+row*ilx] /
838  exptime) / gain ;
839  */
840  variance = padata[col+row*ilx] / gain ;
841 
842  }
843  else
844  {
845  weight[col][row] = 0. ;
846  }
847  if (variance == 0.)
848  {
849  weight[col][row] = 0. ;
850  }
851  else
852  {
853 
854  weight[col][row] = sinfo_psf[col][row]/variance ;
855 
856  norm += weight[col][row] * weight[col][row] * variance ;
857 
858  }
859 
860  }
861  }
862 
863  sum_wgt=0;
864  for ( row = 0 ; row < ily ; row++ )
865  {
866  for ( col = 0 ; col < ilx ; col++ )
867  {
868  weight[col][row] /= norm;
869  sum_wgt += weight[col][row]*sinfo_psf[col][row];
870  }
871  }
872  sinfo_msg_debug("sum_psf=%f sum_wgt=%f norm=%f",sum_psf,sum_wgt,norm);
873  cpl_image_delete(averagedIm) ;
874  if ( norm == 0. )
875  {
876  sinfo_msg_error(" normalization sum is zero\n") ;
877  cpl_image_delete(retIm) ;
878  return NULL ;
879  }
880 
881  /* limit the extraction region to the Gaussian, center +- fwhmx/y *
882  cos(theta) */
883  /*
884  sinfo_msg("fit_par: %f %f %f %f %f %f %f",
885  fit_par[0],fit_par[1],fit_par[2],fit_par[3],
886  fit_par[4],fit_par[5],fit_par[6]);
887  sinfo_msg("fwhm_factor=%f",fwhm_factor);
888  */
889 
890  if(fabs(fit_par[6]) > PI_NUMB/4) {
891  fit_par[6]=0;
892  }
893  first_col = (int) (fit_par[0] -
894  fwhm_factor*fit_par[4]*cos((double)fit_par[6])) ;
895  first_col = (first_col > 2 ) ? first_col : 2;
896 
897  last_col = (int) (fit_par[0] +
898  fwhm_factor*fit_par[4]*cos((double)fit_par[6])) ;
899  last_col = (last_col < 63 ) ? last_col : 63;
900 
901  first_row = (int) (fit_par[1] -
902  fwhm_factor*fit_par[5]*cos((double)fit_par[6])) ;
903  first_row = (first_row > 2 ) ? first_row : 2;
904  last_row = (int) (fit_par[1] +
905  fwhm_factor*fit_par[5]*cos((double)fit_par[6])) ;
906  last_row = (last_row < 63 ) ? last_row : 63;
907 
908 
909  if(first_col > last_col) {
910  tmp_val=last_col;
911  last_col=first_col;
912  first_col=tmp_val;
913  }
914 
915  if(first_row > last_row) {
916  tmp_val=last_row;
917  last_col=first_row;
918  first_col=tmp_val;
919  }
920  if(abs(first_col- last_col) < 1) {
921  first_col -=1;
922  last_col +=1;
923  }
924  if(abs(first_row- last_row) < 1) {
925  first_row -=1;
926  last_row +=1;
927  }
928 
929  if ( first_col < 0 || first_row < 0 || last_col >= ilx || last_row >= ily )
930  {
931  sinfo_msg_error(" star badly centered in FOV!") ;
932  cpl_image_delete(retIm) ;
933  return NULL ;
934  }
935 
936 
937  cpl_table_new_column(*spectrum,"wavelength", CPL_TYPE_FLOAT);
938  /* cpl_table_new_column(*spectrum,"intensity" , CPL_TYPE_FLOAT); */
939  cpl_table_new_column(*spectrum,"counts_tot" , CPL_TYPE_FLOAT);
940  cpl_table_new_column(*spectrum,"counts_bkg" , CPL_TYPE_FLOAT);
941  cpl_table_new_column(*spectrum,"bkg_tot" , CPL_TYPE_FLOAT);
942 
943  if(qc_info==1) {
944  cpl_table_new_column(*spectrum,"AMP" , CPL_TYPE_FLOAT);
945  cpl_table_new_column(*spectrum,"XC" , CPL_TYPE_FLOAT);
946  cpl_table_new_column(*spectrum,"YC" , CPL_TYPE_FLOAT);
947  cpl_table_new_column(*spectrum,"BKG" , CPL_TYPE_FLOAT);
948  cpl_table_new_column(*spectrum,"FWHMX" , CPL_TYPE_FLOAT);
949  cpl_table_new_column(*spectrum,"FWHMY" , CPL_TYPE_FLOAT);
950  cpl_table_new_column(*spectrum,"ANGLE" , CPL_TYPE_FLOAT);
951  }
952  plist=cpl_propertylist_load(name,0);
953  cenpix = sinfo_pfits_get_crpix3(plist);
954  cenLambda = sinfo_pfits_get_crval3(plist);
955  dispersion = sinfo_pfits_get_cdelt3(plist);
956  cpl_propertylist_delete(plist);
957  lambda_start=cenLambda-cenpix*dispersion;
958 
959  sinfo_msg_debug("frow %d lrow %d fcol %d lcol %d",
960  first_row, last_row, first_col, last_col);
961  /* go through the planes */
962  podata=cpl_image_get_data_float(retIm);
963  for ( z = 0 ; z < inp ; z++ )
964  {
965  i_img=cpl_imagelist_get(cube,z);
966  pidata=cpl_image_get_data_float(i_img);
967  weighted_sum = 0. ;
968  counts_tot=0.;
969  counts_bkg=0.;
970 
971  bkg_tot=0.;
972 
973  if(qc_info==1) {
974  sinfo_new_fit_2d_gaussian(i_img,gfit_par,
975  gderv_par,gmpar,llx,lly,
976  halfbox_x,halfbox_y,check2);
977  }
978 
979  for ( row = first_row ; row <= last_row ; row++ )
980  {
981  for ( col = first_col ; col < last_col ; col++ )
982  {
983  if ( !isnan(pidata[col+row*ilx]) )
984  {
985 
986  weighted_sum += weight[col][row] * (pidata[col+row*ilx] -
987  fit_par[3]);
988 
989  counts_bkg += (pidata[col+row*ilx] - fit_par[3]);
990  counts_tot += (pidata[col+row*ilx]);
991  bkg_tot += fit_par[3];
992 
993  }
994  }
995  }
996 
997  if (weighted_sum == 0.)
998  {
999  weighted_sum = ZERO ;
1000  counts_tot = ZERO;
1001  counts_bkg = ZERO;
1002  bkg_tot = ZERO;
1003 
1004  }
1005  else
1006  {
1007  /*
1008  weighted_sum /= norm ;
1009  */
1010 
1011 
1012  }
1013 
1014  podata[z] = weighted_sum ;
1015  lambda=lambda_start+z*dispersion;
1016  cpl_table_set_float(*spectrum,"wavelength" ,z,lambda);
1017  /* cpl_table_set_float(*spectrum,"intensity" ,z,weighted_sum); */
1018  cpl_table_set_float(*spectrum,"counts_tot" ,z,counts_tot);
1019  cpl_table_set_float(*spectrum,"counts_bkg" ,z,counts_bkg);
1020  cpl_table_set_float(*spectrum,"bkg_tot" ,z,bkg_tot);
1021  sinfo_msg_debug("w=%f I=%f b=%f a=%f",
1022  lambda,counts_tot,counts_bkg,bkg_tot);
1023  if(qc_info==1) {
1024  cpl_table_set_float(*spectrum,"AMP" ,z,gfit_par[0]);
1025  cpl_table_set_float(*spectrum,"XC" ,z,gfit_par[1]);
1026  cpl_table_set_float(*spectrum,"YC" ,z,gfit_par[2]);
1027  cpl_table_set_float(*spectrum,"BKG" ,z,gfit_par[3]);
1028  cpl_table_set_float(*spectrum,"FWHMX" ,z,gfit_par[4]);
1029  cpl_table_set_float(*spectrum,"FWHMY" ,z,gfit_par[5]);
1030  cpl_table_set_float(*spectrum,"ANGLE" ,z,gfit_par[6]);
1031  }
1032 
1033  }
1034 
1035  sinfo_new_destroy_2Ddoublearray(&sinfo_psf,ilx) ;
1036  sinfo_new_destroy_2Ddoublearray(&weight,ilx) ;
1037 
1038  return retIm ;
1039 }
1040 
1064 Vector * sinfo_new_extract_sky_from_cube( cpl_imagelist * cube,
1065  float loReject,
1066  float hiReject,
1067  int * position,
1068  int tolerance,
1069  int posindicator )
1070 {
1071  Vector * spectrum ;
1072  int x, y, z ;
1073  int n ;
1074  int n_sky ;
1075  int x_low , x_high ;
1076  int y_low , y_high ;
1077  int hi_x, lo_x ;
1078  float * to_average ;
1079  float cleanMean ;
1080 
1081  int ilx=0;
1082  int ily=0;
1083  int inp=0;
1084  float* pidata=NULL;
1085  cpl_image* i_img=NULL;
1086 
1087 
1088  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1089  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1090  inp=cpl_imagelist_get_size(cube);
1091 
1092  if ( NULL == cube )
1093  {
1094  sinfo_msg_error(" no cube given!\n") ;
1095  return NullVector ;
1096  }
1097  if ( loReject < 0. || hiReject < 0. || loReject + hiReject >= 90. )
1098  {
1099  sinfo_msg_error("wrong or unrealistic loReject and hiReject values!") ;
1100  return NullVector ;
1101  }
1102  if ( position == NULL)
1103  {
1104  sinfo_msg_error(" no position array given!") ;
1105  return NullVector ;
1106  }
1107  if ( position[0] < 0 || position[1] < 0 ||
1108  position[0] > ilx || position[1] > ily )
1109  {
1110  sinfo_msg_error(" wrong position of sky spider!") ;
1111  return NullVector ;
1112  }
1113  if ( tolerance < 0 || tolerance >= ilx )
1114  {
1115  sinfo_msg_error(" wrong tolerance given!") ;
1116  return NullVector ;
1117  }
1118  if ( posindicator == 0 )
1119  {
1120  sinfo_msg_error(" no sinfo_edge indicator given!") ;
1121  return NullVector ;
1122  }
1123 
1124  /* determine the edge of the image where the sky spectra are placed */
1125  switch(posindicator)
1126  {
1127  /* lower right sinfo_edge */
1128  case 1:
1129  x_low = position[0] + tolerance ;
1130  x_high = ilx ;
1131  y_low = 0 ;
1132  y_high = position[1] - tolerance ;
1133  break ;
1134  /* upper right sinfo_edge */
1135  case 2:
1136  x_low = position[0] + tolerance ;
1137  x_high = ilx ;
1138  y_low = position[1] + tolerance ;
1139  y_high = ily ;
1140  break ;
1141  /* upper left sinfo_edge */
1142  case 3:
1143  x_low = 0 ;
1144  x_high = position[0] - tolerance ;
1145  y_low = position [1] + tolerance ;
1146  y_high = ily ;
1147  break ;
1148  default:
1149  sinfo_msg_error(" wrong position indicator index!") ;
1150  return NullVector ;
1151  break ;
1152  }
1153  if ( x_low >= ilx || x_high < 1 || y_low >= ily || y_high < 1 )
1154  {
1155  sinfo_msg_error(" tolerance too high!") ;
1156  return NullVector ;
1157  }
1158  if ( x_high - x_low != y_high - y_low )
1159  {
1160  sinfo_msg_error(" sky sinfo_edge is not a diagonal line!\n") ;
1161  return NullVector ;
1162  }
1163 
1164  /* determine the number of sky pixels in one image plane, take only
1165  the full sky pixels which are not cut by the diagonal line */
1166  n_sky = (x_high - x_low) * (x_high - x_low - 1) / 2 ;
1167  if ( n_sky <= 0 )
1168  {
1169  sinfo_msg_error(" no sky spectrum in found in cube!") ;
1170  return NullVector ;
1171  }
1172  if ( n_sky == 1 )
1173  {
1174  sinfo_msg_warning(" only one sky spectrum is taken, no averaging!") ;
1175  }
1176 
1177  /* allocate memory for the output spectrum */
1178  if ( NullVector == (spectrum = sinfo_new_vector(inp)) )
1179  {
1180  sinfo_msg_error(" could not allocate memory!") ;
1181  return NullVector ;
1182  }
1183 
1184  /* go through the image planes */
1185  for ( z = 0 ; z < inp ; z++ )
1186  {
1187  i_img=cpl_imagelist_get(cube,z);
1188  pidata=cpl_image_get_data_float(i_img);
1189  /* allocate memory for the sky pixels in one image plane */
1190  if (NULL == (to_average = (float*) cpl_calloc(n_sky, sizeof (float))))
1191  {
1192  sinfo_msg_error(" could not allocate memory!") ;
1193  sinfo_new_destroy_vector(spectrum) ;
1194  return NullVector ;
1195  }
1196  n = 0 ;
1197  switch(posindicator)
1198  {
1199  /* lower right sinfo_edge */
1200  case 1:
1201  lo_x = x_low ;
1202  for ( y = y_low ; y < y_high - 1 ; y++ )
1203  {
1204  lo_x++ ;
1205  for ( x = lo_x ; x < x_high ; x++ )
1206  {
1207  to_average[n] = pidata[x+y*ilx] ;
1208  n++ ;
1209  }
1210  }
1211  break ;
1212  /* lower left sinfo_edge */
1213  case 2:
1214  hi_x = x_high ;
1215  for ( y = y_low ; y < y_high - 1 ; y++ )
1216  {
1217  hi_x-- ;
1218  for ( x = x_low ; x < hi_x ; x++ )
1219  {
1220  to_average[n] = pidata[x+y*ilx] ;
1221  n++ ;
1222  }
1223  }
1224  break ;
1225  /* upper right sinfo_edge */
1226  case 3:
1227  lo_x = x_high ;
1228  for ( y = y_low+1 ; y < y_high ; y++ )
1229  {
1230  lo_x-- ;
1231  for ( x = lo_x ; x < x_high ; x++ )
1232  {
1233  to_average[n] = pidata[x+y*ilx] ;
1234  n++ ;
1235  }
1236  }
1237  break ;
1238  /* upper left sinfo_edge */
1239  case 4:
1240  hi_x = x_low ;
1241  for ( y = y_low+1 ; y < y_high ; y++ )
1242  {
1243  hi_x++ ;
1244  for ( x = x_low ; x < hi_x ; x++ )
1245  {
1246  to_average[n] = pidata[x+y*ilx] ;
1247  n++ ;
1248  }
1249  }
1250  break ;
1251  default:
1252  sinfo_msg_error(" wrong position indicator index!\n") ;
1253  return NullVector ;
1254  break ;
1255  }
1256  if ( n != n_sky )
1257  {
1258  sinfo_msg_warning("number of stored sky image pixels does "
1259  "not equal number of computed sky pixels!") ;
1260  }
1261 
1262  /* now take a clean mean of the sky "image" */
1263  cleanMean = sinfo_new_clean_mean (to_average, n, loReject, hiReject) ;
1264  if (cleanMean == FLT_MAX)
1265  {
1266  sinfo_msg_error(" could not take a clean mean!\n") ;
1267  sinfo_new_destroy_vector(spectrum) ;
1268  cpl_free(to_average) ;
1269  return NullVector ;
1270  }
1271  spectrum->data[z] = cleanMean ;
1272  cpl_free (to_average) ;
1273  }
1274 
1275  return spectrum ;
1276 }
1277 
1291 Vector * sinfo_new_sum_rectangle_of_cube_spectra( cpl_imagelist * cube,
1292  int llx,
1293  int lly,
1294  int urx,
1295  int ury )
1296 {
1297  Vector * sum ;
1298  pixelvalue *local_rectangle ;
1299  int i, j, k, l, m ;
1300  int recsize ;
1301  int ilx=0;
1302  int ily=0;
1303  int inp=0;
1304  float* pidata=NULL;
1305  cpl_image* i_img=NULL;
1306 
1307 
1308  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1309  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1310  inp=cpl_imagelist_get_size(cube);
1311 
1312  if ( cube == NULL || inp < 1 )
1313  {
1314  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1315  return NullVector ;
1316  }
1317 
1318  if ((llx<0) || (llx>=ilx) ||
1319  (urx<0) || (urx>=ilx) ||
1320  (lly<0) || (lly>=ily) ||
1321  (ury<0) || (ury>=ily) ||
1322  (llx>=urx) || (lly>=ury))
1323  {
1324  sinfo_msg_error(" invalid rectangle coordinates:") ;
1325  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
1326  llx, lly, urx, ury) ;
1327  return NullVector ;
1328  }
1329 
1330  recsize = (urx - llx + 1) * (ury - lly + 1) ;
1331 
1332  /* allocate a new sinfo_vector to store the average spectral values */
1333  if (NULL == (sum = sinfo_new_vector (inp)) )
1334  {
1335  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
1336  return NullVector ;
1337  }
1338 
1339  /*------------------------------------------------------------------------
1340  * loop through the cube planes, through the x axis and the y-axis of the
1341  * plane rectangle and store pixel values in a buffer.
1342  */
1343  for ( i = 0 ; i < inp ; i++ )
1344  {
1345  i_img=cpl_imagelist_get(cube,i);
1346  pidata=cpl_image_get_data_float(i_img);
1347  m = 0 ;
1348  local_rectangle = (pixelvalue *) cpl_calloc (recsize,
1349  sizeof (pixelvalue*));
1350 
1351  for ( j = lly ; j <= ury ; j++ )
1352  {
1353  for ( k = llx ; k <= urx ; k++ )
1354  {
1355  local_rectangle[m] = pidata[k + j * ilx] ;
1356  m ++ ;
1357  }
1358  }
1359  for ( l = 0 ; l < recsize ; l++ )
1360  {
1361  if ( isnan(local_rectangle[l]) )
1362  {
1363  continue ;
1364  }
1365  sum -> data[i] += local_rectangle[l] ;
1366  }
1367  cpl_free ( local_rectangle ) ;
1368  }
1369  return sum ;
1370 }
1371 
1383 Vector * sinfo_new_sum_circle_of_cube_spectra( cpl_imagelist * cube,
1384  int centerx,
1385  int centery,
1386  int radius )
1387 {
1388  Vector * sum ;
1389  pixelvalue * circle ;
1390  int i, j, k, l, m, n ;
1391  int circsize ;
1392  int ilx=0;
1393  int ily=0;
1394  int inp=0;
1395  float* pidata=NULL;
1396  cpl_image* i_img=NULL;
1397 
1398 
1399  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1400  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1401  inp=cpl_imagelist_get_size(cube);
1402 
1403  if ( cube == NULL || inp < 1 )
1404  {
1405  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1406  return NullVector ;
1407  }
1408 
1409  if ((centerx+radius>=ilx) ||
1410  (centery+radius>=ily) ||
1411  (centerx-radius<0) ||
1412  (centery-radius<0))
1413  {
1414  sinfo_msg_error(" invalid circular coordinates") ;
1415  return NullVector ;
1416  }
1417 
1418  n = 0 ;
1419  for ( j = centery - radius ; j <= centery + radius ; j++ )
1420  {
1421  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1422  {
1423  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1424  radius*radius )
1425  {
1426  n ++ ;
1427  }
1428  }
1429  }
1430  if (n == 0)
1431  {
1432  sinfo_msg_error (" no data points found!") ;
1433  return NullVector ;
1434  }
1435  circsize = n ;
1436 
1437  /* allocate a new sinfo_vector to store the average spectral values */
1438  if (NULL == (sum = sinfo_new_vector (inp)) )
1439  {
1440  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
1441  return NullVector ;
1442  }
1443 
1444  /*------------------------------------------------------------------------
1445  * loop through the cube planes, through the x axis and the y-axis of the
1446  * plane circle and store pixel values in a buffer.
1447  */
1448  for ( i = 0 ; i < inp ; i++ )
1449  {
1450  i_img=cpl_imagelist_get(cube,i);
1451  pidata=cpl_image_get_data_float(i_img);
1452  m = 0 ;
1453  circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
1454 
1455  for ( j = centery - radius ; j <= centery + radius ; j++ )
1456  {
1457  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1458  {
1459  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1460  radius*radius )
1461  {
1462  circle[m] = pidata[k + j * ilx] ;
1463  m ++ ;
1464  }
1465  }
1466  }
1467 
1468  for ( l = 0 ; l < circsize ; l++ )
1469  {
1470  if ( isnan(circle[l]) )
1471  {
1472  continue ;
1473  }
1474  sum -> data[i] += circle[l] ;
1475  }
1476  cpl_free (circle) ;
1477  }
1478  return sum ;
1479 }
1480 
1494 Vector * sinfo_new_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
1495  int llx,
1496  int lly,
1497  int urx,
1498  int ury )
1499 {
1500  Vector * mean ;
1501  pixelvalue *local_rectangle ;
1502  int i, j, k, l, m ;
1503  int recsize, nv ;
1504  int ilx=0;
1505  int ily=0;
1506  int inp=0;
1507  float* pidata=NULL;
1508  cpl_image* i_img=NULL;
1509 
1510 
1511  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1512  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1513  inp=cpl_imagelist_get_size(cube);
1514 
1515  if ( cube == NULL || inp < 1 )
1516  {
1517  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1518  return NullVector ;
1519  }
1520 
1521  if ((llx<0) || (llx>=ilx) ||
1522  (urx<0) || (urx>=ilx) ||
1523  (lly<0) || (lly>=ily) ||
1524  (ury<0) || (ury>=ily) ||
1525  (llx>=urx) || (lly>=ury))
1526  {
1527  sinfo_msg_error(" invalid rectangle coordinates:") ;
1528  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
1529  llx, lly, urx, ury) ;
1530  return NullVector ;
1531  }
1532 
1533  recsize = (urx - llx + 1) * (ury - lly + 1) ;
1534 
1535  /* allocate a new sinfo_vector to store the average spectral values */
1536  if (NULL == (mean = sinfo_new_vector (inp)) )
1537  {
1538  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
1539  return NullVector ;
1540  }
1541 
1542  /*------------------------------------------------------------------------
1543  * loop through the cube planes, through the x axis and the y-axis of the
1544  * plane rectangle and store pixel values in a buffer.
1545  */
1546  for ( i = 0 ; i < inp ; i++ )
1547  {
1548  i_img=cpl_imagelist_get(cube,i);
1549  pidata=cpl_image_get_data_float(i_img);
1550  m = 0 ;
1551  local_rectangle = (pixelvalue *) cpl_calloc (recsize,
1552  sizeof (pixelvalue*));
1553 
1554  for ( j = lly ; j <= ury ; j++ )
1555  {
1556  for ( k = llx ; k <= urx ; k++ )
1557  {
1558  local_rectangle[m] = pidata[k + j * ilx] ;
1559  m ++ ;
1560  }
1561  }
1562  nv = 0 ;
1563  for ( l = 0 ; l < recsize ; l++ )
1564  {
1565  if ( isnan(local_rectangle[l]) )
1566  {
1567  continue ;
1568  }
1569  mean -> data[i] += local_rectangle[l] ;
1570  nv ++;
1571  }
1572  if ( nv == 0 )
1573  {
1574  mean -> data[i] = ZERO ;
1575  }
1576  else
1577  {
1578  mean -> data[i] /= nv ;
1579  }
1580  cpl_free ( local_rectangle ) ;
1581  }
1582  return mean ;
1583 }
1584 
1596 Vector *
1597 sinfo_new_mean_circle_of_cube_spectra( cpl_imagelist * cube,
1598  int centerx,
1599  int centery,
1600  int radius )
1601 {
1602  Vector * mean ;
1603  pixelvalue * circle ;
1604  int i, j, k, l, m, n ;
1605  int circsize, nv ;
1606  int ilx=0;
1607  int ily=0;
1608  int inp=0;
1609  float* pidata=NULL;
1610  cpl_image* i_img=NULL;
1611 
1612 
1613  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1614  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1615  inp=cpl_imagelist_get_size(cube);
1616 
1617  if ( cube == NULL || inp < 1 )
1618  {
1619  sinfo_msg_error ("no cube to take the mean of his spectra") ;
1620  return NullVector ;
1621  }
1622 
1623  if ((centerx+radius>=ilx) ||
1624  (centery+radius>=ily) ||
1625  (centerx-radius<0) ||
1626  (centery-radius<0))
1627  {
1628  sinfo_msg_error(" invalid circular coordinates") ;
1629  return NullVector ;
1630  }
1631 
1632  n = 0 ;
1633  for ( j = centery - radius ; j <= centery + radius ; j++ )
1634  {
1635  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1636  {
1637  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1638  radius*radius )
1639  {
1640  n ++ ;
1641  }
1642  }
1643  }
1644  if (n == 0)
1645  {
1646  sinfo_msg_error (" no data points found!\n") ;
1647  return NullVector ;
1648  }
1649  circsize = n ;
1650 
1651  /* allocate a new sinfo_vector to store the average spectral values */
1652  if (NULL == (mean = sinfo_new_vector (inp)) )
1653  {
1654  sinfo_msg_error (" cannot allocate a new sinfo_vector \n") ;
1655  return NullVector ;
1656  }
1657 
1658  /*------------------------------------------------------------------------
1659  * loop through the cube planes, through the x axis and the y-axis of the
1660  * plane circle and store pixel values in a buffer.
1661  */
1662  for ( i = 0 ; i < inp ; i++ )
1663  {
1664  i_img=cpl_imagelist_get(cube,i);
1665  pidata=cpl_image_get_data_float(i_img);
1666  m = 0 ;
1667  circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
1668 
1669  for ( j = centery - radius ; j <= centery + radius ; j++ )
1670  {
1671  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1672  {
1673  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1674  radius*radius )
1675  {
1676  circle[m] = pidata[k + j * ilx] ;
1677  m ++ ;
1678  }
1679  }
1680  }
1681 
1682  nv = 0 ;
1683  for ( l = 0 ; l < circsize ; l++ )
1684  {
1685  if ( isnan(circle[l]) )
1686  {
1687  continue ;
1688  }
1689  mean -> data[i] += circle[l] ;
1690  nv ++;
1691  }
1692  if ( nv == 0 )
1693  {
1694  mean -> data[i] = ZERO ;
1695  }
1696  else
1697  {
1698  mean -> data[i] /= nv ;
1699  }
1700 
1701  cpl_free (circle) ;
1702  }
1703  return mean ;
1704 }
1705 
1715 Vector * sinfo_new_blackbody_spectrum( char * templateSpec, double temp )
1716 {
1717  Vector * retSpec ;
1718  int n ;
1719  double cenpix ;
1720  int npix ;
1721  double cenLambda ;
1722  double firstLambda ;
1723  double disp ;
1724  double lambda ;
1725  double intens ;
1726  double denom ;
1727  double norm ;
1728  cpl_propertylist* plist=NULL;
1729 
1730  if ( NULL == templateSpec )
1731  {
1732  sinfo_msg_error (" now input image given!\n") ;
1733  return NULL ;
1734  }
1735  if ( temp < 0. )
1736  {
1737  sinfo_msg_error (" wrong temperature given!\n") ;
1738  return NULL ;
1739  }
1740  /* get the fits header information needed */
1741  if ((cpl_error_code)((plist=cpl_propertylist_load(templateSpec,0))==NULL)){
1742  sinfo_msg_error( "getting header from frame %s",templateSpec);
1743  cpl_propertylist_delete(plist) ;
1744  return NULL ;
1745  }
1746 
1747 
1748  cenpix = sinfo_pfits_get_crpix2(plist);
1749  if(cpl_error_get_code() != CPL_ERROR_NONE) {
1750  sinfo_msg_error (" cannot get CRPIX2\n") ;
1751  sinfo_free_propertylist(&plist) ;
1752  return NULL ;
1753  }
1754 
1755  cenLambda = sinfo_pfits_get_crval2(plist);
1756  if(cpl_error_get_code() != CPL_ERROR_NONE) {
1757  sinfo_msg_error (" cannot get CRVAL2\n") ;
1758  sinfo_free_propertylist(&plist) ;
1759  return NULL ;
1760  }
1761  disp = sinfo_pfits_get_cdelt2(plist);
1762  if(cpl_error_get_code() != CPL_ERROR_NONE) {
1763  sinfo_msg_error (" cannot get CDELT2\n") ;
1764  sinfo_free_propertylist(&plist) ;
1765  return NULL ;
1766  }
1767  npix = sinfo_pfits_get_naxis2(plist);
1768  if(cpl_error_get_code() != CPL_ERROR_NONE) {
1769  sinfo_msg_error (" cannot get NAXIS2\n") ;
1770  sinfo_free_propertylist(&plist) ;
1771  return NULL ;
1772  }
1773  sinfo_free_propertylist(&plist) ;
1774 
1775 
1776  if (NULL == (retSpec = sinfo_new_vector (npix)))
1777  {
1778  sinfo_msg_error (" could not allocate memory!\n") ;
1779  return NULL ;
1780  }
1781 
1782  /* shift from fits to image coordinates */
1783  cenpix-- ;
1784 
1785  firstLambda = cenLambda - cenpix * disp ;
1786  for ( n = 0 ; n < npix ; n++ )
1787  {
1788  lambda = firstLambda + disp * (double)n ;
1789  /* convert from microns to m */
1790 
1791  lambda /= 1.0e6 ;
1792  /* replaced 1./(exp(PLANCK*SPEED_OF_LIGHT/(lambda*BOLTZMANN*temp)) - 1.)
1793  * by 1./(expm1(PLANCK*SPEED_OF_LIGHT/(lambda*BOLTZMANN*temp)))
1794  * for better accuracy if argument of exponential is small
1795  */
1796  denom = 1./(expm1(PLANCK*SPEED_OF_LIGHT/(lambda*BOLTZMANN*temp))) ;
1797  intens = 2.*PI_NUMB*PLANCK*SPEED_OF_LIGHT*SPEED_OF_LIGHT /
1798  pow(lambda, 5) * denom ;
1799  retSpec->data[n] = intens ;
1800  }
1801  norm = retSpec->data[npix/2] ;
1802  for ( n = 0 ; n < npix ; n++ )
1803  {
1804  retSpec->data[n] /= norm ;
1805  }
1806 
1807  return retSpec ;
1808 }
1809 
1810 
1824 Vector * sinfo_new_median_rectangle_of_cube_spectra( cpl_imagelist * cube,
1825  int llx,
1826  int lly,
1827  int urx,
1828  int ury )
1829 {
1830  Vector * med ;
1831  pixelvalue *local_rectangle ;
1832  int i, j, k, m ;
1833  int recsize ;
1834  int ilx=0;
1835  int ily=0;
1836  int inp=0;
1837  float* pidata=NULL;
1838  cpl_image* i_img=NULL;
1839 
1840 
1841  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1842  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1843  inp=cpl_imagelist_get_size(cube);
1844 
1845  if ( cube == NULL || inp < 1 )
1846  {
1847  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1848  return NullVector ;
1849  }
1850 
1851  if ((llx<0) || (llx>=ilx) ||
1852  (urx<0) || (urx>=ilx) ||
1853  (lly<0) || (lly>=ily) ||
1854  (ury<0) || (ury>=ily) ||
1855  (llx>=urx) || (lly>=ury))
1856  {
1857  sinfo_msg_error(" invalid rectangle coordinates:") ;
1858  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
1859  llx, lly, urx, ury) ;
1860  return NullVector ;
1861  }
1862 
1863  recsize = (urx - llx + 1) * (ury - lly + 1) ;
1864 
1865  /* allocate a new sinfo_vector to store the average spectral values */
1866  if (NULL == (med = sinfo_new_vector (inp)) )
1867  {
1868  sinfo_msg_error (" cannot allocate a new sinfo_vector \n") ;
1869  return NullVector ;
1870  }
1871 
1872  /*------------------------------------------------------------------------
1873  * loop through the cube planes, through the x axis and the y-axis of the
1874  * plane rectangle and store pixel values in a buffer.
1875  */
1876  for ( i = 0 ; i < inp ; i++ )
1877  {
1878 
1879  i_img=cpl_imagelist_get(cube,i);
1880  pidata=cpl_image_get_data_float(i_img);
1881  m = 0 ;
1882  local_rectangle=(pixelvalue *)cpl_calloc(recsize, sizeof (pixelvalue*));
1883 
1884  for ( j = lly ; j <= ury ; j++ )
1885  {
1886  for ( k = llx ; k <= urx ; k++ )
1887  {
1888  if ( isnan(pidata[k+j*ilx]) )
1889  {
1890  continue ;
1891  }
1892  else
1893  {
1894  local_rectangle[m] = pidata[k + j * ilx] ;
1895  m ++ ;
1896  }
1897  }
1898  }
1899  if ( m == 0 )
1900  {
1901  med->data[i] = 0. ;
1902  }
1903  else
1904  {
1905  med->data[i] = sinfo_new_median(local_rectangle, m) ;
1906  }
1907  cpl_free ( local_rectangle ) ;
1908  }
1909  return med ;
1910 }
1911 
1923 Vector * sinfo_new_median_circle_of_cube_spectra( cpl_imagelist * cube,
1924  int centerx,
1925  int centery,
1926  int radius )
1927 {
1928  Vector * med ;
1929  pixelvalue * circle ;
1930  int i, j, k, l, m, n ;
1931  int circsize, nv ;
1932  int ilx=0;
1933  int ily=0;
1934  int inp=0;
1935  float* pidata=NULL;
1936  cpl_image* i_img=NULL;
1937 
1938 
1939  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
1940  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
1941  inp=cpl_imagelist_get_size(cube);
1942 
1943  if ( cube == NULL || inp < 1 )
1944  {
1945  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
1946  return NullVector ;
1947  }
1948 
1949  if ((centerx+radius>=ilx) ||
1950  (centery+radius>=ily) ||
1951  (centerx-radius<0) ||
1952  (centery-radius<0))
1953  {
1954  sinfo_msg_error(" invalid circular coordinates") ;
1955  return NullVector ;
1956  }
1957 
1958  n = 0 ;
1959  for ( j = centery - radius ; j <= centery + radius ; j++ )
1960  {
1961  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1962  {
1963  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
1964  radius*radius )
1965  {
1966  n ++ ;
1967  }
1968  }
1969  }
1970  if (n == 0)
1971  {
1972  sinfo_msg_error (" no data points found!") ;
1973  return NullVector ;
1974  }
1975  circsize = n ;
1976 
1977  /* allocate a new sinfo_vector to store the average spectral values */
1978  if (NULL == (med = sinfo_new_vector (inp)) )
1979  {
1980  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
1981  return NullVector ;
1982  }
1983 
1984  /*------------------------------------------------------------------------
1985  * loop through the cube planes, through the x axis and the y-axis of the
1986  * plane circle and store pixel values in a buffer.
1987  */
1988  for ( i = 0 ; i < inp ; i++ )
1989  {
1990  i_img=cpl_imagelist_get(cube,i);
1991  pidata=cpl_image_get_data_float(i_img);
1992  m = 0 ;
1993  circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
1994 
1995  for ( j = centery - radius ; j <= centery + radius ; j++ )
1996  {
1997  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
1998  {
1999  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
2000  radius*radius )
2001  {
2002  circle[m] = pidata[k + j * ilx] ;
2003  m ++ ;
2004  }
2005  }
2006  }
2007 
2008  nv = 0 ;
2009  for ( l = 0 ; l < circsize ; l++ )
2010  {
2011  if ( isnan(circle[l]) )
2012  {
2013  continue ;
2014  }
2015  med -> data[i] += circle[l] ;
2016  nv ++;
2017  }
2018  if ( nv == 0 )
2019  {
2020  med->data[i] = 0. ;
2021  }
2022  else
2023  {
2024  med->data[i] = sinfo_new_median(circle, nv) ;
2025  }
2026  cpl_free (circle) ;
2027  }
2028  return med ;
2029 }
2030 
2044 Vector *
2045 sinfo_new_cleanmean_rectangle_of_cube_spectra( cpl_imagelist * cube,
2046  int llx,
2047  int lly,
2048  int urx,
2049  int ury,
2050  float lo_reject,
2051  float hi_reject )
2052 {
2053  Vector * clean ;
2054  pixelvalue *local_rectangle ;
2055  int i, j, k, m ;
2056  int recsize ;
2057  int ilx=0;
2058  int ily=0;
2059  int inp=0;
2060  float* pidata=NULL;
2061  cpl_image* i_img=NULL;
2062 
2063 
2064  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
2065  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
2066  inp=cpl_imagelist_get_size(cube);
2067 
2068  if ( cube == NULL || inp < 1 )
2069  {
2070  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
2071  return NullVector ;
2072  }
2073 
2074  if ((llx<0) || (llx>=ilx) ||
2075  (urx<0) || (urx>=ilx) ||
2076  (lly<0) || (lly>=ily) ||
2077  (ury<0) || (ury>=ily) ||
2078  (llx>=urx) || (lly>=ury))
2079  {
2080  sinfo_msg_error(" invalid rectangle coordinates:") ;
2081  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
2082  llx, lly, urx, ury) ;
2083  return NullVector ;
2084  }
2085 
2086  recsize = (urx - llx + 1) * (ury - lly + 1) ;
2087 
2088  /* allocate a new sinfo_vector to store the average spectral values */
2089  if (NULL == (clean = sinfo_new_vector (inp)) )
2090  {
2091  sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
2092  return NullVector ;
2093  }
2094 
2095  /*------------------------------------------------------------------------
2096  * loop through the cube planes, through the x axis and the y-axis of the
2097  * plane rectangle and store pixel values in a buffer.
2098  */
2099  for ( i = 0 ; i < inp ; i++ )
2100  {
2101  i_img=cpl_imagelist_get(cube,i);
2102  pidata=cpl_image_get_data_float(i_img);
2103  m = 0 ;
2104  local_rectangle=(pixelvalue *) cpl_calloc(recsize, sizeof (pixelvalue*));
2105 
2106  for ( j = lly ; j <= ury ; j++ )
2107  {
2108  for ( k = llx ; k <= urx ; k++ )
2109  {
2110  if ( isnan(pidata[k+j*ilx]) )
2111  {
2112  continue ;
2113  }
2114  else
2115  {
2116  local_rectangle[m] = pidata[k + j * ilx] ;
2117  m ++ ;
2118  }
2119  }
2120  }
2121  if ( m == 0 )
2122  {
2123  clean->data[i] = 0. ;
2124  }
2125  else
2126  {
2127  clean->data[i] = sinfo_new_clean_mean(local_rectangle, m,
2128  lo_reject, hi_reject) ;
2129  }
2130  cpl_free ( local_rectangle ) ;
2131  }
2132  return clean ;
2133 }
2134 
2146 Vector *
2147 sinfo_new_cleanmean_circle_of_cube_spectra( cpl_imagelist * cube,
2148  int centerx,
2149  int centery,
2150  int radius,
2151  float lo_reject,
2152  float hi_reject )
2153 {
2154  Vector * clean ;
2155  pixelvalue * circle ;
2156  int i, j, k, l, m, n ;
2157  int circsize, nv ;
2158  int ilx=0;
2159  int ily=0;
2160  int inp=0;
2161  float* pidata=NULL;
2162  cpl_image* i_img=NULL;
2163 
2164  ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
2165  ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
2166  inp=cpl_imagelist_get_size(cube);
2167 
2168  if ( cube == NULL || inp < 1 )
2169  {
2170  sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
2171  return NullVector ;
2172  }
2173 
2174  if ((centerx+radius>=ilx) ||
2175  (centery+radius>=ily) ||
2176  (centerx-radius<0) ||
2177  (centery-radius<0))
2178  {
2179  sinfo_msg_error(" invalid circular coordinates") ;
2180  return NullVector ;
2181  }
2182 
2183  n = 0 ;
2184  for ( j = centery - radius ; j <= centery + radius ; j++ )
2185  {
2186  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
2187  {
2188  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
2189  radius*radius )
2190  {
2191  n ++ ;
2192  }
2193  }
2194  }
2195  if (n == 0)
2196  {
2197  sinfo_msg_error (" no data points found!\n") ;
2198  return NullVector ;
2199  }
2200  circsize = n ;
2201 
2202  /* allocate a new sinfo_vector to store the average spectral values */
2203  if (NULL == (clean = sinfo_new_vector (inp)) )
2204  {
2205  sinfo_msg_error (" cannot allocate a new sinfo_vector \n") ;
2206  return NullVector ;
2207  }
2208 
2209  /*------------------------------------------------------------------------
2210  * loop through the cube planes, through the x axis and the y-axis of the
2211  * plane circle and store pixel values in a buffer.
2212  */
2213  for ( i = 0 ; i < inp ; i++ )
2214  {
2215  i_img=cpl_imagelist_get(cube,i);
2216  pidata=cpl_image_get_data_float(i_img);
2217  m = 0 ;
2218  circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
2219 
2220  for ( j = centery - radius ; j <= centery + radius ; j++ )
2221  {
2222  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
2223  {
2224  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
2225  radius*radius )
2226  {
2227  circle[m] = pidata[k + j * ilx] ;
2228  m ++ ;
2229  }
2230  }
2231  }
2232 
2233  nv = 0 ;
2234  for ( l = 0 ; l < circsize ; l++ )
2235  {
2236  if ( isnan(circle[l]) )
2237  {
2238  continue ;
2239  }
2240  clean -> data[i] += circle[l] ;
2241  nv ++;
2242  }
2243  if ( nv == 0 )
2244  {
2245  clean->data[i] = 0. ;
2246  }
2247  else
2248  {
2249  clean->data[i] = sinfo_new_clean_mean(circle, nv,
2250  lo_reject, hi_reject) ;
2251  }
2252  cpl_free (circle) ;
2253  }
2254  return clean ;
2255 }
2256 
2268 float *
2269 sinfo_new_shift_array ( float * input, int n_elements,
2270  float shift, double * ker )
2271 {
2272  float * shifted ;
2273  int samples = KERNEL_SAMPLES ;
2274  int i ;
2275  float fx ;
2276  float rx ;
2277  int px ;
2278  int tabx ;
2279  float value ;
2280  /*size_t pos ;*/
2281  register float * pix ;
2282  int mid;
2283  float norm ;
2284 
2285  /* error handling: test entries */
2286  if (input==NULL)
2287  {
2288  sinfo_msg_error(" no input array given!\n") ;
2289  return NULL ;
2290  }
2291  if (n_elements<=0)
2292  {
2293  sinfo_msg_error(" wrong number of elements in input array given!\n") ;
2294  return NULL ;
2295  }
2296 
2297  shifted = (float*) cpl_calloc(n_elements, sizeof(float)) ;
2298 
2299  /* Shifting by a zero offset returns a copy of the input image */
2300  if ((fabs(shift)<1e-2))
2301  {
2302  for (i = 0 ; i < n_elements ; i++ )
2303  {
2304  shifted[i] = input[i] ;
2305  }
2306  return shifted ;
2307  }
2308 
2309  mid = (int)samples/(int)2 ;
2310 
2311  for (i=1 ; i< n_elements-2 ; i++)
2312  {
2313  fx = (float)i+shift ;
2314  px = sinfo_new_nint(fx) ;
2315  rx = fx - (float)px ;
2316  pix = input ;
2317 
2318  if ((px>=1) && (px<(n_elements-2)))
2319  {
2320  tabx = (int)(fabs((float)mid * rx)) ;
2321  /* exclude blank (ZERO) pixels from interpolation */
2322  if (isnan(pix[i]))
2323  {
2324  value = ZERO ;
2325  }
2326  else
2327  {
2328  if (isnan(pix[i-1]))
2329  {
2330  pix[i-1] = 0. ;
2331  }
2332  if (isnan(pix[i+1]))
2333  {
2334  pix[i+1] = 0. ;
2335  }
2336  if (isnan(pix[i+2]))
2337  {
2338  pix[i+2] = 0. ;
2339  }
2340 
2341  /*
2342  * Sum up over 4 closest pixel values,
2343  * weighted by interpolation kernel values
2344  */
2345  value = pix[i-1] * ker[mid+tabx] +
2346  pix[i] * ker[tabx] +
2347  pix[i+1] * ker[mid-tabx] +
2348  pix[i+2] * ker[samples-tabx-1] ;
2349  /*
2350  * Also sum up interpolation kernel coefficients
2351  * for further normalization
2352  */
2353  norm = ker[mid+tabx] +
2354  ker[tabx] +
2355  ker[mid-tabx] +
2356  ker[samples-tabx-1] ;
2357  if (fabs(norm) > 1e-4)
2358  {
2359  value /= norm ;
2360  }
2361  }
2362  }
2363  else
2364  {
2365  value = 0.0 ;
2366  }
2367  if ( isnan(value) )
2368  {
2369  shifted[i] = ZERO ;
2370  }
2371  else
2372  {
2373  shifted[i] = value ;
2374  }
2375  }
2376  return shifted ;
2377 }
2378 
2379 
2380 /*--------------------------------------------------------------------------*/
2381 
2393 cpl_image *
2394 sinfo_new_div_image_by_spectrum( cpl_image * image, cpl_image * spectrum )
2395 {
2396  int col, row ;
2397  cpl_image * retImage ;
2398  int ilx=0;
2399  int ily=0;
2400 
2401  /* int slx=0; */
2402  int sly=0;
2403 
2404  float* pidata=NULL;
2405  float* psdata=NULL;
2406  float* podata=NULL;
2407 
2408  if ( image == NULL )
2409  {
2410  sinfo_msg_error("no image given!") ;
2411  return NULL ;
2412  }
2413  ilx=cpl_image_get_size_x(image);
2414  ily=cpl_image_get_size_y(image);
2415 
2416 
2417  if ( spectrum == NULL )
2418  {
2419  sinfo_msg_error("no spectrum image given!") ;
2420  return NULL ;
2421  }
2422  /* slx=cpl_image_get_size_x(spectrum); */
2423  sly=cpl_image_get_size_y(spectrum);
2424 
2425  if ( sly != ily )
2426  {
2427  sinfo_msg_error("images are not compatible in pixel length!") ;
2428  return NULL ;
2429  }
2430  if ( NULL == (retImage = cpl_image_duplicate(image)) )
2431  {
2432  sinfo_msg_error("could not copy original image!") ;
2433  return NULL ;
2434  }
2435  pidata=cpl_image_get_data_float(image);
2436  psdata=cpl_image_get_data_float(spectrum);
2437  podata=cpl_image_get_data_float(retImage);
2438 
2439  for ( col = 0 ; col < ilx ; col++ )
2440  {
2441  for ( row = 0 ; row < ily ; row++ )
2442  {
2443  if ( !isnan(pidata[col+row*ilx]) &&
2444  !isnan(psdata[col+row*ilx]))
2445  {
2446  podata[col+row*ilx] = pidata[col+row*ilx] / psdata[row] ;
2447  }
2448  }
2449  }
2450  return retImage ;
2451 }
2452 
2453 /*---------------------------------------------------------------------------
2454  Function : sinfo_new_clean_mean_circle_of_cube_spectra()
2455  In : cube: 1 allocated cube,
2456  centerx, centery: center pixel of circular aperture
2457  in image coordinates
2458  radius: integer radius of circular aperture
2459  Out : result spectrum vector
2460  Job : clean averaging routine for a reduced data to get
2461  a better spectral S/N only for a circular aperture.
2462  ---------------------------------------------------------------------------*/
2463 
2464 Vector * sinfo_new_clean_mean_circle_of_cube_spectra(cpl_imagelist * cube,
2465  int centerx,
2466  int centery,
2467  int radius,
2468  float lo_reject,
2469  float hi_reject )
2470 {
2471  Vector * clean ;
2472  pixelvalue * circle ;
2473  int i, j, k, l, m, n ;
2474  int circsize, nv ;
2475  int lx=0;
2476  int ly=0;
2477  int lz=0;
2478  float* pidata=NULL;
2479  cpl_image* img=NULL;
2480 
2481  lz=cpl_imagelist_get_size(cube);
2482 
2483  if ( cube == NULL || lz < 1 )
2484  {
2485  sinfo_msg_error (" no cube to take the mean of his spectra") ;
2486  return NullVector ;
2487  }
2488  img=cpl_imagelist_get(cube,0);
2489  lx=cpl_image_get_size_x(img);
2490  ly=cpl_image_get_size_y(img);
2491 
2492  if ((centerx+radius>=lx) ||
2493  (centery+radius>=ly) ||
2494  (centerx-radius<0) ||
2495  (centery-radius<0))
2496  {
2497  sinfo_msg_error(" invalid circular coordinates") ;
2498  return NullVector ;
2499  }
2500 
2501  n = 0 ;
2502  for ( j = centery - radius ; j <= centery + radius ; j++ )
2503  {
2504  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
2505  {
2506  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
2507  radius*radius )
2508  {
2509  n ++ ;
2510  }
2511  }
2512  }
2513  if (n == 0)
2514  {
2515  sinfo_msg_error (" no data points found!") ;
2516  return NullVector ;
2517  }
2518  circsize = n ;
2519 
2520  /* allocate a new vector to store the average spectral values */
2521  if (NULL == (clean = sinfo_new_vector (lz)) )
2522  {
2523  sinfo_msg_error (" cannot allocate a new vector") ;
2524  return NullVector ;
2525  }
2526 
2527  /*------------------------------------------------------------------------
2528  * loop through the cube planes, through the x axis and the y-axis of the
2529  * plane circle and store pixel values in a buffer.
2530  */
2531  for ( i = 0 ; i < lz ; i++ )
2532  {
2533  img=cpl_imagelist_get(cube,i);
2534  pidata=cpl_image_get_data(img);
2535  m = 0 ;
2536  circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
2537 
2538  for ( j = centery - radius ; j <= centery + radius ; j++ )
2539  {
2540  for ( k = centerx - radius ; k <= centerx + radius ; k++ )
2541  {
2542  if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <=
2543  radius*radius )
2544  {
2545  circle[m] = pidata[k + j * lx] ;
2546  m ++ ;
2547  }
2548  }
2549  }
2550 
2551  nv = 0 ;
2552  for ( l = 0 ; l < circsize ; l++ )
2553  {
2554  if ( isnan(circle[l]) )
2555  {
2556  continue ;
2557  }
2558  clean -> data[i] += circle[l] ;
2559  nv ++;
2560  }
2561  if ( nv == 0 )
2562  {
2563  clean->data[i] = 0. ;
2564  }
2565  else
2566  {
2567  clean->data[i] = sinfo_new_clean_mean(circle, nv,
2568  lo_reject, hi_reject) ;
2569  }
2570  cpl_free (circle) ;
2571  }
2572  return clean ;
2573 }
2574 
2575 
2576 
2577 /*---------------------------------------------------------------------------
2578  Function : sinfo_new_clean_mean_rectangle_of_cube_spectra()
2579  In : cube: 1 allocated cube,
2580  llx, lly, urx, ury: lower left and upper right
2581  position of rectangle in x-y plane ,
2582  image coordinates 0...
2583  Out : result spectrum vector
2584  Job : clean averaging routine for a reduced data to get a
2585  better spectral S/N only for a rectangular aperture.
2586  ---------------------------------------------------------------------------*/
2587 
2588 Vector * sinfo_new_clean_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
2589  int llx,
2590  int lly,
2591  int urx,
2592  int ury,
2593  float lo_reject,
2594  float hi_reject )
2595 {
2596  Vector * clean ;
2597  pixelvalue *rectangle ;
2598  int i, j, k, m ;
2599  int recsize ;
2600  int lx=0;
2601  int ly=0;
2602  int lz=0;
2603  float* pidata=0;
2604  cpl_image* img=NULL;
2605 
2606  lz=cpl_imagelist_get_size(cube);
2607 
2608  if ( cube == NULL || lz < 1 )
2609  {
2610  sinfo_msg_error (" no cube to take the mean of his spectra") ;
2611  return NullVector ;
2612  }
2613  img=cpl_imagelist_get(cube,0);
2614  lx=cpl_image_get_size_x(img);
2615  ly=cpl_image_get_size_y(img);
2616 
2617  if ((llx<0) || (llx>=lx) ||
2618  (urx<0) || (urx>=lx) ||
2619  (lly<0) || (lly>=ly) ||
2620  (ury<0) || (ury>=ly) ||
2621  (llx>=urx) || (lly>=ury))
2622  {
2623  sinfo_msg_error(" invalid rectangle coordinates:") ;
2624  sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
2625  llx, lly, urx, ury) ;
2626  return NullVector ;
2627  }
2628 
2629  recsize = (urx - llx + 1) * (ury - lly + 1) ;
2630 
2631  /* allocate a new vector to store the average spectral values */
2632  if (NULL == (clean = sinfo_new_vector (lz)) )
2633  {
2634  sinfo_msg_error (" cannot allocate a new vector") ;
2635  return NullVector ;
2636  }
2637 
2638  /*------------------------------------------------------------------------
2639  * loop through the cube planes, through the x axis and the y-axis of the
2640  * plane rectangle and store pixel values in a buffer.
2641  */
2642  for ( i = 0 ; i < lz ; i++ )
2643  {
2644  m = 0 ;
2645  rectangle = (pixelvalue *) cpl_calloc (recsize, sizeof (pixelvalue*));
2646  img=cpl_imagelist_get(cube,i);
2647  pidata=cpl_image_get_data(img);
2648  for ( j = lly ; j <= ury ; j++ )
2649  {
2650  for ( k = llx ; k <= urx ; k++ )
2651  {
2652  if ( isnan(pidata[k+j*lx]) )
2653  {
2654  continue ;
2655  }
2656  else
2657  {
2658  rectangle[m] = pidata[k + j * lx] ;
2659  m ++ ;
2660  }
2661  }
2662  }
2663  if ( m == 0 )
2664  {
2665  clean->data[i] = 0. ;
2666  }
2667  else
2668  {
2669  clean->data[i] = sinfo_new_clean_mean(rectangle, m,
2670  lo_reject, hi_reject) ;
2671  }
2672  cpl_free ( rectangle ) ;
2673  }
2674  return clean ;
2675 }
2676 
2677 /*--------------------------------------------------------------------------*/