sinfo_spectrum_ops.c

00001 /*
00002  * This file is part of the ESO SINFONI Pipeline
00003  * Copyright (C) 2004,2005 European Southern Observatory
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00018  */
00019 /***************************************************************************
00020 * E.S.O. - VLT project
00021 *
00022 *
00023 *
00024 * who       when      what
00025 * --------  --------  ----------------------------------------------
00026 * schreib  25/05/00  created
00027 */
00028 
00029 /************************************************************************
00030 *   NAME
00031 *        sinfo_spectrum_ops.c -
00032 *        some sinfo_vector procedures to operate on spectra
00033 *
00034 *   SYNOPSIS
00035 *   #include "sinfo_spectrum_ops.h"
00036 *
00037 *   1) Vector * sinfo_new_vector( ulong32 n_elements )
00038 *   2) void * sinfo_new_destroy_vector( Vector *sinfo_vector )
00039 *   3) cpl_image * sinfo_new_vector_to_image( Vector * spectrum )
00040 *   4) Vector * sinfo_new_image_to_vector( cpl_image * spectrum )
00041 *   5) cpl_image * 
00042        sinfo_new_extract_spectrum_from_resampled_flat(cpl_image * resflat,
00043 *                                                   float      loreject,
00044 *                                                   float      hireject ) 
00045 *   6) cpl_image * sinfo_new_multiply_image_with_spectrum(cpl_image * image, 
00046                                                           cpl_image * spectrum)
00047 *   7) cpl_image * sinfo_new_optimal_extraction_from_cube(cpl_imagelist * cube, 
00048 *                                            int       halfbox_x, 
00049 *                                            int       halfbox_y,
00050 *                                            float     fwhm_factor,
00051 *                                            float     backvariance,
00052 *                                            float     sky,
00053 *                                            float     gain,
00054 *                                            float     exptime)
00055 *   8) Vector * sinfo_new_extract_sky_from_cube( cpl_imagelist * cube,
00056 *                                   float     loReject,
00057 *                                   float     hiReject,
00058 *                                   int     * position,
00059 *                                   int       tolerance,
00060 *                                   int       posindicator )
00061 *    9) Vector * sinfo_new_sum_rectangle_of_cube_spectra( cpl_imagelist * cube,
00062 *                                     int llx,
00063 *                                     int lly,
00064 *                                     int urx,
00065 *                                     int ury )
00066 *   10) Vector * sinfo_new_sum_circle_of_cube_spectra( cpl_imagelist * cube,
00067 *                                        int       centerx,
00068 *                                        int       centery,
00069 *                                        int       radius )
00070 *   11) Vector * 
00071         sinfo_new_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
00072 *                                            int llx,
00073 *                                            int lly,
00074 *                                            int urx,
00075 *                                            int ury )
00076 *   12) Vector * sinfo_new_mean_circle_of_cube_spectra( cpl_imagelist * cube,
00077 *                                         int       centerx,
00078 *                                         int       centery,
00079 *                                         int       radius )
00080 *   13) Vector * 
00081         sinfo_new_blackbody_spectrum(char * templateSpec, double temp )
00082 *   14) Vector * 
00083         sinfo_new_median_rectangle_of_cube_spectra(cpl_imagelist * cube,
00084 *                                               int llx,
00085 *                                               int lly,
00086 *                                               int urx,
00087 *                                               int ury )
00088 *   15) Vector * sinfo_new_median_circle_of_cube_spectra( cpl_imagelist * cube,
00089 *                                           int       centerx,
00090 *                                           int       centery,
00091 *                                           int       radius )
00092 *   16) Vector * 
00093         sinfo_new_cleanmean_rectangle_of_cube_spectra(cpl_imagelist * cube,
00094 *                                                 int llx,
00095 *                                                 int lly,
00096 *                                                 int urx,
00097 *                                                 int ury,
00098 *                                                 float lo_reject,
00099 *                                                 float hi_reject )
00100 *   17) Vector * 
00101         sinfo_new_cleanmean_circle_of_cube_spectra( cpl_imagelist * cube,
00102 *                                              int       centerx,
00103 *                                              int       centery,
00104 *                                              int       radius,
00105 *                                              float     lo_reject,
00106 *                                              float     hi_reject )
00107 *   18) float * sinfo_new_shift_array ( float * input, 
00108                                         int n_elements, 
00109                                         float shift, 
00110                                         double * ker ) 
00111 *
00112 *   DESCRIPTION
00113 *   1) allocates memory for a new sinfo_vector
00114 *   2) frees memory of a sinfo_vector
00115 *   3) converts a spectral sinfo_vector to a fits image
00116 *      remark: sinfo_vector object spectrum is destroyed
00117 *   4) converts a fits image to a spectral sinfo_vector
00118 *      remark: input image is destroyed
00119 *   5) builds one spectrum in a fits image out of a resampled
00120 *      flatfield frame by taking a clean mean along the spatial pixels
00121 *   6) multiplys a resampled image with a resampled spectrum
00122 *      (calibrated halogen lamp spectrum) in the same spectral range
00123 *      that means all image columns are multiplied with the same spectrum
00124 *   7) does the optimal extraction of a standard star spectrum
00125 *      according to the equation:
00126 *       S = sum { (P^2 / V) * (I - B) / P } / sum{ P^2 / V } 
00127 *       S: spectral flux at a particular wavelength
00128 *       P: normalized PSF (determined by a 2D-Gaussian fit)
00129 *       I: pixel value
00130 *       B: background pixel value determined by the background parameter 
00131            of the 2D-Gaussian fit
00132 *       V: estimated variance of a pixel: 
00133            V = [R^2 + D + sky + I,c/exptime]/gain
00134 *          where R is the read noise, and D the sinfo_dark current variance.
00135 *          backvariance is R^2 + D in counts/sec. 
00136            I,c is the source intensity in counts
00137 *          Remember: sigma,e[e-] = gain[e/count] * sigma,c [counts] = 
00138                      sqrt(I,e) = sqrt(gain*I,c)
00139 *          => V,c = sigma,c^2 = sigma,e^2/gain^2 
00140 *          => sigma,c = sqrt(I,c/gain) => V,c = I,c/gain
00141 *   8) extracts a sky spectrum from a reduced sky spider observation, that
00142 *      means from a data cube. Therefore, the position of the sky within the
00143 *      field of view must be first read from the fits header.  
00144        A pixel tolerance is subtracted.
00145 *      The found sky spectra are averaged by rejecting the extreme 
00146        high and low values.
00147 *   9) summing routine for a reduced data to get a better spectral S/N
00148 *      only for a rectangular aperture.
00149 *   10) summing routine for a reduced data to get a better spectral S/N
00150 *       only for a circular aperture.
00151 *   11) averaging routine for a reduced data to get a better spectral S/N
00152 *       only for a rectangular aperture.
00153 *   12) averaging routine for a reduced data to get a better spectral S/N
00154 *       only for a circular aperture.
00155 *   13) computes a blackbody spectral intensity distribution
00156 *       (W/(m^2 lambda ster)) 
00157 *   14) sinfo_median routine for a reduced data to get a better spectral S/N
00158 *       only for a rectangular aperture.
00159 *   15) sinfo_median routine for a reduced data to get a better spectral S/N
00160 *       only for a circular aperture.
00161 *   16) clean averaging routine for a reduced data to get a better spectral S/N
00162 *       only for a rectangular aperture.
00163 *   17) clean averaging routine for a reduced data to get a better spectral S/N
00164 *       only for a circular aperture.
00165 *   18) shifts an array by a sub-pixel shift value using a tanh
00166 *       interpolation kernel
00167 *
00168 *   FILES
00169 *
00170 *   ENVIRONMENT
00171 *
00172 *   RETURN VALUES
00173 *
00174 *   CAUTIONS
00175 *
00176 *   EXAMPLES
00177 *
00178 *   SEE ALSO
00179 *
00180 *   BUGS
00181 *
00182 *------------------------------------------------------------------------
00183 */
00184 #ifdef HAVE_CONFIG_H
00185 #  include <config.h>
00186 #endif
00187 
00188 #define POSIX_SOURCE 1
00189 #include "sinfo_vltPort.h"
00190 
00191 /*
00192  * System Headers
00193  */
00194 
00195 /*
00196  * Local Headers
00197  */
00198 #include "sinfo_pfits.h"
00199 #include "sinfo_spectrum_ops.h"
00200 #include "sinfo_resampling.h"
00201 #include "sinfo_utilities.h"
00202 #include "sinfo_utils_wrappers.h"
00203 /*----------------------------------------------------------------------------
00204  *                            Function codes
00205  *--------------------------------------------------------------------------*/
00206 
00224 int sinfo_stectrum_ima2table(
00225                  const cpl_image* spc,
00226                  const char* filename,
00227                  cpl_table** tbl)
00228 {
00229   const float* pidata=NULL;
00230   int nx=0;
00231   int ny=0;
00232   int nraw=0;
00233   int i=0;
00234   double amp=0;
00235   double wav=0;
00236  
00237   double step=0;
00238   double ws=0;
00239   double we=0;
00240   double wc=0;
00241   cpl_propertylist* plist=NULL;
00242 
00243   if(spc == NULL){
00244     sinfo_msg_error("Input image is null");
00245     return -1;
00246   }
00247 
00248   pidata = cpl_image_get_data_const(spc);
00249   nx=cpl_image_get_size_x(spc);
00250   ny=cpl_image_get_size_y(spc);
00251 
00252   if((nx == 0) || (ny == 0)) {
00253     sinfo_msg_error("Input image has improper size: nx=%d ny=%d",nx,ny);
00254     return -1;
00255   }
00256   if((nx > 1) && (ny > 1)) {
00257     sinfo_msg_error("Input image has improper size: nx=%d ny=%d",nx,ny);
00258     return -1;
00259   }
00260 
00261 
00262   nraw=nx*ny;
00263   *tbl = cpl_table_new(nraw);
00264   cpl_table_new_column(*tbl,"WAVE",CPL_TYPE_DOUBLE);
00265   cpl_table_new_column(*tbl,"INT",CPL_TYPE_DOUBLE);
00266 
00267 
00268   if ((cpl_error_code)((plist = cpl_propertylist_load(filename, 0)) == NULL)) {
00269       sinfo_msg_error( "getting header from reference frame %s",filename);
00270       cpl_propertylist_delete(plist) ;
00271       return -1 ;
00272   }
00273 
00274 
00275   if(nx>1) {
00276     step=sinfo_pfits_get_cdelt1(plist);
00277     wc=sinfo_pfits_get_crval1(plist);
00278   } else {
00279 
00280     step=sinfo_pfits_get_cdelt2(plist);
00281     wc=sinfo_pfits_get_crval2(plist);
00282   }
00283 
00284   ws=wc-nraw*step/2;
00285   we=wc+nraw*step/2;
00286   wav=ws;
00287   sinfo_msg("ws=%f we=%f step=%f",ws,we,step);
00288   cpl_table_set_double(*tbl,"WAVE",0,wav);
00289   cpl_table_set_double(*tbl,"INT",0,pidata[i]);
00290 
00291   for(i=1;i<nraw;i++) {
00292     wav+=step;
00293     amp=(double)pidata[i];
00294     cpl_table_set_double(*tbl,"WAVE",i,wav);
00295     cpl_table_set_double(*tbl,"INT",i,amp);
00296   }
00297   cpl_propertylist_delete(plist);
00298   return 0;
00299 
00300 
00301 }
00302 
00303 
00304 
00314 Vector * sinfo_new_vector( ulong32 n_elements )
00315 {
00316     Vector * local_new_vector ;
00317 
00318     if ( n_elements <= 0 )
00319     {
00320         sinfo_msg_error (" wrong number of elements\n") ;
00321         return NullVector ;
00322     }
00323     
00324     /* allocate memory for a sinfo_vector with the given number of elements */
00325     local_new_vector = (Vector *) cpl_malloc (sizeof (Vector)) ; 
00326     local_new_vector -> n_elements = n_elements ;
00327     local_new_vector -> data = (pixelvalue *) cpl_calloc (n_elements, 
00328                                                   sizeof (pixelvalue)) ;
00329 
00330     return local_new_vector ;
00331 }
00332 
00340 void sinfo_free_svector( Vector **svector )
00341 {
00342     if ( *svector != NULL )   
00343     {
00344        
00345       if((*svector) -> data != NULL) {
00346     cpl_free ( (*svector) -> data ) ;
00347     (*svector)->data = NULL;
00348       }
00349       cpl_free ( *svector ) ;
00350       *svector = NULL;
00351     }
00352     return ;
00353 }
00354 
00362 void sinfo_new_destroy_vector( Vector *sinfo_vector )
00363 {
00364     if ( sinfo_vector == NULL )   
00365     {
00366         sinfo_msg_error(" NULL Vector given!\n") ;
00367         return ;
00368     }    
00369     
00370     cpl_free ( sinfo_vector -> data ) ;
00371     cpl_free ( sinfo_vector ) ;
00372 }
00373 
00382 cpl_image * sinfo_new_vector_to_image( Vector * spectrum )
00383 {
00384     cpl_image * returnIm ;
00385     int i ;
00386    
00387     float* podata=NULL;
00388 
00389 
00390     if ( spectrum == NULL )
00391     {
00392         sinfo_msg_error(" no spectrum given!\n") ;
00393         return NULL ;
00394     }
00395  
00396     /* allocate memory */
00397     if ( NULL == (returnIm = cpl_image_new(1, spectrum->n_elements,
00398                                            CPL_TYPE_FLOAT)) )
00399     {
00400         sinfo_msg_error(" no spectrum given!\n") ;
00401         sinfo_new_destroy_vector(spectrum) ;
00402         return NULL ;
00403     }
00404 
00405     podata=cpl_image_get_data_float(returnIm);
00406     for ( i = 0 ; i < spectrum->n_elements ; i++ )
00407     {
00408         podata[i] = spectrum -> data[i] ;
00409     }
00410 
00411     sinfo_new_destroy_vector (spectrum) ;
00412     return returnIm ;
00413 }
00414 
00423 Vector * sinfo_new_image_to_vector( cpl_image * spectrum )
00424 {
00425     Vector * returnVector ;
00426     int i ;
00427     int ilx=0;
00428     int ily=0;
00429   
00430     float* pidata=NULL;
00431 
00432     if ( spectrum == NULL )
00433     {
00434         sinfo_msg_error(" no spectrum given!") ;
00435         return NULL ;
00436     }
00437     ilx=cpl_image_get_size_x(spectrum);
00438     ily=cpl_image_get_size_y(spectrum);
00439 
00440     /* allocate memory */
00441     if ( NULL == (returnVector = sinfo_new_vector(ilx*ily)) )
00442     {
00443         sinfo_msg_error(" cannot allocate memory!") ;
00444         cpl_image_delete(spectrum) ;
00445         return NULL ;
00446     }
00447 
00448     pidata=cpl_image_get_data_float(spectrum);
00449     for ( i = 0 ; i < (int) ilx*ily ; i++ )
00450     {
00451         returnVector -> data[i] = pidata[i] ;
00452     }
00453 
00454     cpl_image_delete (spectrum) ;
00455     return returnVector ;
00456 }
00457 
00470 cpl_image * 
00471 sinfo_new_extract_spectrum_from_resampled_flat( cpl_image * resflat,
00472                                              float      loreject,
00473                                              float      hireject ) 
00474 {
00475     cpl_image * retIm ;
00476     int col, row ;
00477     int n ;
00478     float* array=NULL ;
00479     float cleanMean ;
00480     Vector * spectrum ;
00481 
00482     int ilx=0;
00483     int ily=0;
00484   
00485     float* pidata=NULL;
00486   
00487     if ( resflat == NULL )
00488     {
00489         sinfo_msg_error(" no flatfield given!") ;
00490         return NULL ;
00491     }
00492     ilx=cpl_image_get_size_x(resflat);
00493     ily=cpl_image_get_size_y(resflat);
00494 
00495     /* allocate memory */
00496     if ( NullVector == (spectrum = sinfo_new_vector(ily) ) )
00497     {
00498         sinfo_msg_error(" could not allocate memory!") ;
00499         return NULL ;
00500     }
00501 
00502     array=cpl_calloc(ily,sizeof(float)) ;
00503 
00504     pidata=cpl_image_get_data_float(resflat);
00505     for ( row = 0 ; row < ily ; row++ )
00506     {
00507         n = 0 ;
00508         for ( col = 0 ; col < ilx ; col++ )
00509         {
00510             if ( !isnan(pidata[col + row*ilx]) )
00511             {
00512                 array[n] = pidata[col+row*ilx] ;
00513                 n++ ;
00514             }
00515         }
00516         if ( n == 0 )
00517         {
00518             sinfo_msg_warning(" only bad pixels in row: %d!", row) ;
00519             cleanMean = ZERO ;
00520         }
00521         else
00522         {
00523             if ( FLT_MAX == (cleanMean = sinfo_new_clean_mean(array, n, 
00524                                                               loreject, 
00525                                                               hireject)) )
00526             {
00527                 sinfo_msg_error(" could not do sinfo_clean_mean!") ;
00528                 sinfo_new_destroy_vector(spectrum) ;
00529                 return NULL ;
00530             }
00531         }
00532         spectrum->data[row] = cleanMean ; 
00533     }
00534     if ( NULL == ( retIm = sinfo_new_vector_to_image( spectrum ) ) )
00535     {
00536         sinfo_msg_error(" could not do sinfo_vectorToImage!") ;
00537         sinfo_new_destroy_vector(spectrum) ;
00538         return NULL ;
00539     }
00540     cpl_free(array) ;
00541 
00542     return retIm ;
00543 }
00544 
00558 cpl_image * 
00559 sinfo_new_multiply_image_with_spectrum( cpl_image * image, 
00560                                         cpl_image * spectrum )
00561 {
00562     int col, row ;
00563     cpl_image * retImage ;
00564 
00565 
00566     int ilx=0;
00567     int ily=0;
00568     int slx=0;
00569     int sly=0;
00570 
00571     float* pidata=NULL;
00572     float* psdata=NULL;
00573     float* podata=NULL;
00574 
00575 
00576     if ( image == NULL )
00577     {
00578         sinfo_msg_error(" no image given!") ;
00579         return NULL ;
00580     }
00581     ilx=cpl_image_get_size_x(image);
00582     ily=cpl_image_get_size_y(image);
00583 
00584     if ( spectrum == NULL )
00585     {
00586         sinfo_msg_error(" no spectrum image given!") ;
00587         return NULL ;
00588     }
00589     slx=cpl_image_get_size_x(spectrum);
00590     sly=cpl_image_get_size_y(spectrum);
00591 
00592     if ( sly != ily )
00593     {
00594         sinfo_msg_error(" images are not compatible in pixel length!") ;
00595         return NULL ;
00596     }
00597 
00598     if ( NULL == (retImage = cpl_image_duplicate(image)) )
00599     {
00600         sinfo_msg_error(" could not copy original image!\n") ;
00601         return NULL ;
00602     }
00603 
00604     pidata=cpl_image_get_data_float(image);
00605     psdata=cpl_image_get_data_float(spectrum);
00606     podata=cpl_image_get_data_float(retImage);
00607 
00608     for ( col = 0 ; col < ilx ; col++ )
00609     {
00610         for ( row = 0 ; row < ily ; row++ )
00611         {
00612             if ( !isnan(pidata[col+row*ilx]) &&
00613                  !isnan(psdata[col+row*ilx]))
00614             {
00615                 podata[col+row*ilx] = pidata[col+row*ilx] * psdata[row] ;
00616                                                    
00617             }
00618         }
00619     }
00620     return retImage ;
00621 }
00622 
00661 cpl_image * sinfo_new_optimal_extraction_from_cube( cpl_imagelist * cube, 
00662                                       int       llx,
00663                                       int       lly,
00664                                       int       halfbox_x, 
00665                                       int       halfbox_y,
00666                                       float     fwhm_factor,
00667                                       float     backvariance,
00668                                       float     sky,
00669                                       float     gain,
00670                                       float     exptime,
00671                                       const char* name,
00672                                       cpl_table** spectrum,
00673                       int       qc_info,
00674                                       int*      check2)
00675 {
00676     int col, row, z ;
00677     cpl_image * averagedIm ; 
00678     cpl_image * retIm ;
00679     double fit_par[7] ;
00680     double derv_par[7] ;
00681     int mpar[7] ;
00682     double gfit_par[7] ;
00683     double gderv_par[7] ;
00684     int gmpar[7] ;
00685     int fitInd ;
00686     int i ;
00687     double sum ;
00688     double** weight=NULL ;
00689     double** sinfo_psf=NULL ;
00690 
00691     double variance ;
00692     double xdat[2] ;
00693     float weighted_sum ;
00694     float counts_tot ;
00695     float counts_bkg ;
00696     float bkg_tot ;
00697 
00698 
00699     int first_col, last_col ;
00700     int first_row, last_row ;
00701     float norm ;
00702     float sum_psf=0;
00703     float sum_wgt=0;
00704     float cenpix = 0;
00705     float cenLambda = 0;
00706     float dispersion = 0;
00707     float lambda=0;
00708     float lambda_start=0;
00709 
00710     int ilx=0;
00711     int ily=0;
00712     int inp=0;
00713     float* pidata=NULL;
00714     float* padata=NULL;
00715     float* podata=NULL;
00716     float tmp_val=0;
00717     cpl_propertylist* plist=NULL;
00718     cpl_image* i_img=NULL;
00719 
00720 
00721     /* TODO: the sky here is not really used. We remove compilation warning */
00722     sky=0;
00723 
00724     if ( NULL == cube )
00725     {
00726         sinfo_msg_error(" no cube given!\n") ;
00727         return NULL ;
00728     }
00729 
00730 
00731     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
00732     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
00733     inp=cpl_imagelist_get_size(cube);
00734 
00735     if ( llx < 0 || llx + 2*halfbox_x >= ilx || 
00736          lly < 0 || lly + 2*halfbox_y >= ily )
00737     {
00738       sinfo_msg("llx=%d, lly=%d,  llx + 2*halfbox_x=%d, "
00739                 "lly + 2*halfbox_y=%d",
00740                 llx,lly,llx + 2*halfbox_x,lly + 2*halfbox_y);
00741       sinfo_msg("tresh_min_x=%d, tresh_min_y=%d, "
00742                 "tresh_max_x=%d, tresh_max_y=%d",0,0,ilx,ily);
00743         sinfo_msg_error(" lower left sinfo_edge points wrong position!") ;
00744         return NULL ;
00745     }
00746     if ( halfbox_x <= 0 || halfbox_y <= 0 || 
00747          2*halfbox_x > ilx || 2*halfbox_y > ily )
00748     {
00749         sinfo_msg_error(" wrong halfbox width given!") ;
00750         return NULL ;
00751     }
00752     if ( fwhm_factor <= 0. )
00753     {
00754         sinfo_msg_error(" wrong fwhm_factor given!") ;
00755         return NULL ;
00756     }
00757     if ( backvariance < 0. )
00758     {
00759         sinfo_msg_error(" wrong backvariance given!") ;
00760         return NULL ;
00761     }
00762     if ( exptime <= 0. || exptime == FLAG )
00763     {
00764         sinfo_msg_error(" wrong exposure time given!") ;
00765         return NULL ;
00766     }
00767 
00768     /* allocate memory for spectrum */
00769     if ( NULL == (retIm = cpl_image_new(1, inp,CPL_TYPE_FLOAT)) )
00770     {
00771         sinfo_msg_error(" memory allocation failed!\n") ;
00772         return NULL ;
00773     }
00774     /* collapse the cube to be able to compute the weights 
00775        for optimal extraction */
00776     if ( NULL == (averagedIm = sinfo_new_average_cube_to_image(cube)) )
00777     {
00778         sinfo_msg_error(" sinfo_averageCubeToImage failed!") ;
00779         cpl_image_delete(retIm) ;
00780         return NULL ;
00781     }
00782 
00783     /* call the 2D-Gaussian fit routine */
00784     for ( i = 0 ; i < 7 ; i++ )
00785     {
00786         mpar[i] = 1 ;
00787     }
00788 
00789     if ( -1 == (fitInd = sinfo_new_fit_2d_gaussian(averagedIm,
00790                                                    fit_par,
00791                                                    derv_par,
00792                                                    mpar,
00793                                                    llx,
00794                                                    lly,
00795                                                    halfbox_x,
00796                                                    halfbox_y,
00797                                                    check2 )) )
00798     {
00799         sinfo_msg_warning("sinfo_fit2dGaussian failed!") ;
00800         cpl_image_delete(retIm) ;
00801         cpl_image_delete(averagedIm) ;
00802         return NULL ;
00803     }
00804 
00805     /* determine the PSF by using the found 2D-Gaussian */
00806     sinfo_psf=sinfo_new_2Ddoublearray(ilx,ily) ;
00807     sum = 0 ;
00808     for ( row = 0 ; row < ily ; row++ )
00809     {
00810         for ( col = 0 ; col < ilx ; col++ )
00811         {
00812             xdat[0] = (double) col ;
00813             xdat[1] = (double) row ;
00814             sinfo_psf[col][row] = sinfo_new_gaussian_ellipse(xdat,fit_par) - 
00815                                   fit_par[3] ;
00816             sum += sinfo_psf[col][row] ;
00817         }
00818     }
00819     /* Scale the PSF and determine the pixel variances and the 
00820        normalization factor */
00821     norm = 0. ;
00822     variance = 0. ;
00823     sum_psf=0;
00824 
00825     weight=sinfo_new_2Ddoublearray(ilx,ily) ;
00826 
00827     padata=cpl_image_get_data_float(averagedIm);
00828     for ( row = 0 ; row < ily ; row++ )
00829     {
00830         for ( col = 0 ; col < ilx ; col++ )
00831         {
00832             sinfo_psf[col][row] /= sum ;
00833         sum_psf +=  sinfo_psf[col][row];
00834             if ( !isnan(padata[col+row*ilx]) )
00835             {
00836           /*
00837                 variance = (backvariance + sky + padata[col+row*ilx] / 
00838                             exptime) / gain ;
00839           */
00840                 variance = padata[col+row*ilx] / gain ;
00841 
00842             }
00843             else 
00844             {
00845                 weight[col][row] = 0. ;
00846             }
00847             if (variance == 0.)
00848             {
00849                 weight[col][row] = 0. ;
00850             }
00851             else
00852             {
00853          
00854                 weight[col][row] = sinfo_psf[col][row]/variance ;
00855            
00856                 norm += weight[col][row] * weight[col][row] * variance ;
00857 
00858             }
00859         
00860         }
00861     }
00862 
00863     sum_wgt=0;
00864     for ( row = 0 ; row < ily ; row++ )
00865     {
00866         for ( col = 0 ; col < ilx ; col++ )
00867         {
00868       weight[col][row] /= norm;
00869           sum_wgt += weight[col][row]*sinfo_psf[col][row];
00870     }
00871     }
00872     sinfo_msg_debug("sum_psf=%f sum_wgt=%f norm=%f",sum_psf,sum_wgt,norm);
00873     cpl_image_delete(averagedIm) ;
00874     if ( norm == 0. )
00875     {
00876         sinfo_msg_error(" normalization sum is zero\n") ;
00877         cpl_image_delete(retIm) ;
00878         return NULL ;
00879     }
00880 
00881     /* limit the extraction region to the Gaussian, center +- fwhmx/y * 
00882                  cos(theta)  */
00883     /*
00884     sinfo_msg("fit_par: %f %f %f %f %f %f %f", 
00885               fit_par[0],fit_par[1],fit_par[2],fit_par[3],
00886               fit_par[4],fit_par[5],fit_par[6]);
00887     sinfo_msg("fwhm_factor=%f",fwhm_factor);
00888     */
00889 
00890     if(fabs(fit_par[6]) > PI_NUMB/4) {
00891       fit_par[6]=0;
00892     }
00893     first_col = (int) (fit_par[0] - 
00894                        fwhm_factor*fit_par[4]*cos((double)fit_par[6])) ;
00895     first_col = (first_col > 2 ) ? first_col : 2;
00896 
00897     last_col =  (int) (fit_par[0] + 
00898                        fwhm_factor*fit_par[4]*cos((double)fit_par[6])) ;
00899     last_col = (last_col < 63 ) ? last_col : 63;
00900 
00901     first_row = (int) (fit_par[1] - 
00902                        fwhm_factor*fit_par[5]*cos((double)fit_par[6])) ;
00903     first_row = (first_row > 2 ) ? first_row : 2;
00904     last_row =  (int) (fit_par[1] + 
00905                        fwhm_factor*fit_par[5]*cos((double)fit_par[6])) ;
00906     last_row = (last_row < 63 ) ? last_row : 63;
00907 
00908     
00909     if(first_col > last_col) {
00910       tmp_val=last_col;
00911       last_col=first_col;
00912       first_col=tmp_val;
00913     }
00914 
00915     if(first_row > last_row) {
00916       tmp_val=last_row;
00917       last_col=first_row;
00918       first_col=tmp_val;
00919     }
00920     if(abs(first_col- last_col) < 1) {
00921       first_col -=1;
00922       last_col +=1;
00923     }
00924     if(abs(first_row- last_row) < 1) {
00925       first_row -=1;
00926       last_row +=1;
00927     }
00928 
00929     if ( first_col < 0 || first_row < 0 || last_col >= ilx || last_row >= ily )
00930     {
00931         sinfo_msg_error(" star badly centered in FOV!") ;
00932         cpl_image_delete(retIm) ;
00933         return NULL ;
00934     }
00935 
00936 
00937     cpl_table_new_column(*spectrum,"wavelength", CPL_TYPE_FLOAT);
00938     /* cpl_table_new_column(*spectrum,"intensity" , CPL_TYPE_FLOAT); */
00939     cpl_table_new_column(*spectrum,"counts_tot" , CPL_TYPE_FLOAT);
00940     cpl_table_new_column(*spectrum,"counts_bkg" , CPL_TYPE_FLOAT);
00941     cpl_table_new_column(*spectrum,"bkg_tot" , CPL_TYPE_FLOAT);
00942 
00943     if(qc_info==1) {
00944        cpl_table_new_column(*spectrum,"AMP" , CPL_TYPE_FLOAT);
00945        cpl_table_new_column(*spectrum,"XC" , CPL_TYPE_FLOAT);
00946        cpl_table_new_column(*spectrum,"YC" , CPL_TYPE_FLOAT);
00947        cpl_table_new_column(*spectrum,"BKG" , CPL_TYPE_FLOAT);
00948        cpl_table_new_column(*spectrum,"FWHMX" , CPL_TYPE_FLOAT);
00949        cpl_table_new_column(*spectrum,"FWHMY" , CPL_TYPE_FLOAT);
00950        cpl_table_new_column(*spectrum,"ANGLE" , CPL_TYPE_FLOAT);
00951     }
00952     plist=cpl_propertylist_load(name,0);
00953     cenpix = sinfo_pfits_get_crpix3(plist);
00954     cenLambda = sinfo_pfits_get_crval3(plist);
00955     dispersion = sinfo_pfits_get_cdelt3(plist);
00956     cpl_propertylist_delete(plist);
00957     lambda_start=cenLambda-cenpix*dispersion;
00958 
00959     sinfo_msg_debug("frow %d lrow %d fcol %d lcol %d",
00960                      first_row, last_row, first_col, last_col);
00961     /* go through the planes */
00962     podata=cpl_image_get_data_float(retIm);
00963     for ( z = 0 ; z < inp ; z++ )
00964     {
00965       i_img=cpl_imagelist_get(cube,z);
00966       pidata=cpl_image_get_data_float(i_img);
00967         weighted_sum = 0. ;
00968         counts_tot=0.;
00969         counts_bkg=0.;
00970 
00971         bkg_tot=0.;
00972 
00973         if(qc_info==1) {
00974            sinfo_new_fit_2d_gaussian(i_img,gfit_par,
00975                                      gderv_par,gmpar,llx,lly,
00976                                      halfbox_x,halfbox_y,check2);
00977     }
00978 
00979         for ( row = first_row ; row <= last_row ; row++ )
00980         {
00981             for ( col = first_col ; col < last_col ; col++ )
00982             {
00983                 if ( !isnan(pidata[col+row*ilx]) )
00984                 {
00985           
00986                     weighted_sum += weight[col][row] * (pidata[col+row*ilx] - 
00987                                     fit_par[3]);
00988             
00989                     counts_bkg += (pidata[col+row*ilx] - fit_par[3]);
00990                     counts_tot += (pidata[col+row*ilx]);
00991                     bkg_tot += fit_par[3];
00992             
00993                 } 
00994             }
00995         }    
00996 
00997         if (weighted_sum == 0.)
00998         {
00999             weighted_sum = ZERO ;
01000             counts_tot = ZERO;
01001             counts_bkg = ZERO;
01002             bkg_tot = ZERO;
01003 
01004         }
01005         else
01006         {
01007       /*
01008             weighted_sum /= norm ;
01009       */
01010       
01011       
01012         }
01013 
01014         podata[z] = weighted_sum ;
01015         lambda=lambda_start+z*dispersion;
01016         cpl_table_set_float(*spectrum,"wavelength" ,z,lambda);
01017         /* cpl_table_set_float(*spectrum,"intensity" ,z,weighted_sum); */
01018         cpl_table_set_float(*spectrum,"counts_tot" ,z,counts_tot);
01019         cpl_table_set_float(*spectrum,"counts_bkg" ,z,counts_bkg);
01020         cpl_table_set_float(*spectrum,"bkg_tot" ,z,bkg_tot);
01021         sinfo_msg_debug("w=%f I=%f b=%f a=%f",
01022                          lambda,counts_tot,counts_bkg,bkg_tot);
01023         if(qc_info==1) {
01024            cpl_table_set_float(*spectrum,"AMP" ,z,gfit_par[0]);
01025            cpl_table_set_float(*spectrum,"XC" ,z,gfit_par[1]);
01026            cpl_table_set_float(*spectrum,"YC" ,z,gfit_par[2]);
01027            cpl_table_set_float(*spectrum,"BKG" ,z,gfit_par[3]);
01028            cpl_table_set_float(*spectrum,"FWHMX" ,z,gfit_par[4]);
01029            cpl_table_set_float(*spectrum,"FWHMY" ,z,gfit_par[5]);
01030            cpl_table_set_float(*spectrum,"ANGLE" ,z,gfit_par[6]);
01031     }
01032 
01033     }
01034 
01035     sinfo_new_destroy_2Ddoublearray(&sinfo_psf,ilx) ;
01036     sinfo_new_destroy_2Ddoublearray(&weight,ilx) ;
01037 
01038     return retIm ;
01039 }
01040 
01064 Vector * sinfo_new_extract_sky_from_cube( cpl_imagelist * cube,
01065                              float     loReject,
01066                              float     hiReject,
01067                              int     * position,
01068                              int       tolerance,
01069                              int       posindicator )
01070 {
01071     Vector * spectrum ;
01072     int x, y, z ;
01073     int n ;
01074     int n_sky ;
01075     int x_low , x_high ;
01076     int y_low , y_high ;
01077     int hi_x, lo_x ;
01078     float * to_average ;
01079     float   cleanMean ;
01080 
01081     int ilx=0;
01082     int ily=0;
01083     int inp=0;
01084     float* pidata=NULL;
01085     cpl_image* i_img=NULL;
01086 
01087 
01088     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
01089     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
01090     inp=cpl_imagelist_get_size(cube);
01091 
01092     if ( NULL == cube )
01093     {
01094         sinfo_msg_error(" no cube given!\n") ;
01095         return NullVector ;
01096     }
01097     if ( loReject < 0. || hiReject < 0. || loReject + hiReject >= 90. )
01098     {
01099         sinfo_msg_error("wrong or unrealistic loReject and hiReject values!") ;
01100         return NullVector ;
01101     }
01102     if ( position == NULL)
01103     {
01104         sinfo_msg_error(" no position array given!") ;
01105         return NullVector ;
01106     }
01107     if ( position[0] < 0 || position[1] < 0 || 
01108          position[0] > ilx  || position[1] > ily )
01109     {
01110         sinfo_msg_error(" wrong position of sky spider!") ;
01111         return NullVector ;
01112     }
01113     if ( tolerance < 0 || tolerance >= ilx )
01114     {
01115         sinfo_msg_error(" wrong tolerance given!") ;
01116         return NullVector ;
01117     }
01118     if ( posindicator == 0 )
01119     {
01120         sinfo_msg_error(" no sinfo_edge indicator given!") ;
01121         return NullVector ;
01122     }
01123 
01124     /* determine the edge of the image where the sky spectra are placed */
01125     switch(posindicator)
01126     {
01127         /* lower right sinfo_edge */
01128         case 1:
01129             x_low  = position[0] + tolerance ;
01130             x_high = ilx ;
01131             y_low  = 0 ;
01132             y_high = position[1] - tolerance ;
01133             break ;
01134         /* upper right sinfo_edge */
01135         case 2:
01136             x_low  = position[0] + tolerance ;
01137             x_high = ilx ;
01138             y_low  = position[1] + tolerance ;
01139             y_high = ily ;
01140             break ;
01141         /* upper left sinfo_edge */
01142         case 3:
01143             x_low  = 0 ;
01144             x_high = position[0] - tolerance ;
01145             y_low  = position [1] + tolerance ;
01146             y_high = ily ;
01147             break ;
01148         default:
01149             sinfo_msg_error(" wrong position indicator index!") ;
01150             return NullVector ;
01151             break ;
01152     }
01153     if ( x_low >= ilx || x_high < 1 || y_low >= ily || y_high < 1 )
01154     {
01155         sinfo_msg_error(" tolerance too high!") ;
01156         return NullVector ;
01157     }
01158     if ( x_high - x_low != y_high - y_low )
01159     {
01160         sinfo_msg_error(" sky sinfo_edge is not a diagonal line!\n") ;
01161         return NullVector ;
01162     }
01163 
01164     /* determine the number of sky pixels in one image plane, take only 
01165        the full sky pixels which are not cut by the diagonal line */
01166     n_sky = (x_high - x_low) * (x_high - x_low - 1) / 2 ;
01167     if ( n_sky <= 0 )
01168     {
01169         sinfo_msg_error(" no sky spectrum in found in cube!") ;
01170         return NullVector ;
01171     }
01172     if ( n_sky == 1 )
01173     {
01174         sinfo_msg_warning(" only one sky spectrum is taken, no averaging!") ;
01175     }
01176 
01177     /* allocate memory for the output spectrum */
01178     if ( NullVector == (spectrum = sinfo_new_vector(inp)) )
01179     {
01180         sinfo_msg_error(" could not allocate memory!") ;
01181         return NullVector ;
01182     }
01183 
01184     /* go through the image planes */
01185     for ( z = 0 ; z < inp ; z++ )
01186     {
01187       i_img=cpl_imagelist_get(cube,z);
01188       pidata=cpl_image_get_data_float(i_img);
01189         /* allocate memory for the sky pixels in one image plane */
01190         if (NULL == (to_average = (float*) cpl_calloc(n_sky, sizeof (float))))
01191         {
01192             sinfo_msg_error(" could not allocate memory!") ;
01193             sinfo_new_destroy_vector(spectrum) ;
01194             return NullVector ;
01195         }
01196         n = 0 ;
01197         switch(posindicator)
01198         {
01199             /* lower right sinfo_edge */
01200             case 1:
01201                 lo_x = x_low ;
01202                 for ( y = y_low ; y < y_high - 1 ; y++ )
01203                 {
01204                     lo_x++ ;
01205                     for ( x = lo_x ; x < x_high ; x++ )
01206                     {
01207                         to_average[n] = pidata[x+y*ilx] ;
01208                         n++ ;
01209                     }
01210                 }
01211                 break ;
01212             /* lower left sinfo_edge */
01213             case 2:
01214                 hi_x = x_high ;
01215                 for ( y = y_low ; y < y_high - 1 ; y++ )
01216                 {
01217                     hi_x-- ;
01218                     for ( x = x_low ; x < hi_x ; x++ )
01219                     {
01220                         to_average[n] = pidata[x+y*ilx] ;
01221                         n++ ;
01222                     }
01223                 }
01224                 break ;
01225             /* upper right sinfo_edge */
01226             case 3:
01227                 lo_x = x_high ;
01228                 for ( y = y_low+1 ; y < y_high ; y++ )
01229                 {
01230                     lo_x-- ;
01231                     for ( x = lo_x ; x < x_high ; x++ )
01232                     {
01233                         to_average[n] = pidata[x+y*ilx] ;
01234                         n++ ;
01235                     }
01236                 }
01237                 break ;
01238             /* upper left sinfo_edge */
01239             case 4:
01240                 hi_x = x_low ;
01241                 for ( y = y_low+1 ; y < y_high ; y++ )
01242                 {
01243                     hi_x++ ;
01244                     for ( x = x_low ; x < hi_x ; x++ )
01245                     {
01246                         to_average[n] = pidata[x+y*ilx] ;
01247                         n++ ;
01248                     }
01249                 }
01250                 break ;
01251             default:
01252                 sinfo_msg_error(" wrong position indicator index!\n") ;
01253                 return NullVector ;
01254                 break ;
01255         }
01256         if ( n != n_sky )
01257         {
01258             sinfo_msg_warning("number of stored sky image pixels does "
01259                               "not equal number of computed sky pixels!") ;
01260         }
01261 
01262         /* now take a clean mean of the sky "image" */
01263         cleanMean = sinfo_new_clean_mean (to_average, n, loReject, hiReject) ;
01264         if (cleanMean == FLT_MAX)
01265         {
01266             sinfo_msg_error(" could not take a clean mean!\n") ;
01267             sinfo_new_destroy_vector(spectrum) ;
01268             cpl_free(to_average) ;
01269             return NullVector ;
01270         }
01271         spectrum->data[z] = cleanMean ;
01272         cpl_free (to_average) ;
01273     }
01274      
01275     return spectrum ;
01276 }
01277 
01291 Vector * sinfo_new_sum_rectangle_of_cube_spectra( cpl_imagelist * cube,
01292                                      int llx,
01293                                      int lly,
01294                                      int urx,
01295                                      int ury )
01296 {
01297     Vector          * sum ;
01298     pixelvalue      *local_rectangle ;
01299     int             i, j, k, l, m ;
01300     int             recsize ;
01301     int ilx=0;
01302     int ily=0;
01303     int inp=0;
01304     float* pidata=NULL;
01305     cpl_image* i_img=NULL;
01306 
01307 
01308     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
01309     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
01310     inp=cpl_imagelist_get_size(cube);
01311 
01312     if ( cube == NULL || inp < 1 )
01313     {
01314         sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
01315         return NullVector ;
01316     }
01317 
01318     if ((llx<0) || (llx>=ilx) ||
01319         (urx<0) || (urx>=ilx) ||
01320         (lly<0) || (lly>=ily) ||
01321         (ury<0) || (ury>=ily) ||
01322         (llx>=urx) || (lly>=ury))
01323     {
01324         sinfo_msg_error(" invalid rectangle coordinates:") ;
01325         sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]", 
01326                          llx, lly, urx, ury) ;
01327         return NullVector ;
01328     }
01329 
01330     recsize = (urx - llx + 1) * (ury - lly + 1) ;
01331 
01332     /* allocate a new sinfo_vector to store the average spectral values */
01333     if (NULL == (sum = sinfo_new_vector (inp)) )
01334     {
01335         sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
01336         return NullVector ;
01337     }
01338 
01339     /*------------------------------------------------------------------------
01340      *  loop through the cube planes, through the x axis and the y-axis of the
01341      *  plane rectangle and store pixel values in a buffer.
01342      */
01343     for ( i = 0 ; i < inp ; i++ )
01344     {
01345       i_img=cpl_imagelist_get(cube,i);
01346       pidata=cpl_image_get_data_float(i_img);
01347         m = 0 ;
01348         local_rectangle = (pixelvalue *) cpl_calloc (recsize, 
01349                                          sizeof (pixelvalue*));
01350 
01351         for ( j = lly ; j <= ury ; j++ )
01352         {
01353             for ( k = llx ; k <= urx ; k++ )
01354             {
01355                 local_rectangle[m] = pidata[k + j * ilx] ;
01356                 m ++ ;
01357             }
01358         }
01359         for ( l = 0 ; l < recsize ; l++ )
01360         {
01361             if ( isnan(local_rectangle[l]) )
01362             {
01363                 continue ;
01364             }
01365             sum -> data[i] += local_rectangle[l] ;
01366         }
01367         cpl_free ( local_rectangle ) ;
01368     }
01369     return sum ;
01370 }
01371 
01383 Vector * sinfo_new_sum_circle_of_cube_spectra( cpl_imagelist * cube,
01384                                   int       centerx,
01385                                   int       centery,
01386                                   int       radius )
01387 {
01388     Vector          * sum ;
01389     pixelvalue      * circle ;
01390     int             i, j, k, l, m, n ;
01391     int             circsize ;
01392     int ilx=0;
01393     int ily=0;
01394     int inp=0;
01395     float* pidata=NULL;
01396     cpl_image* i_img=NULL;
01397 
01398 
01399     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
01400     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
01401     inp=cpl_imagelist_get_size(cube);
01402 
01403     if ( cube == NULL || inp < 1 )
01404     {
01405         sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
01406         return NullVector ;
01407     }
01408 
01409     if ((centerx+radius>=ilx) ||
01410         (centery+radius>=ily) ||
01411         (centerx-radius<0) ||
01412         (centery-radius<0))
01413     {
01414         sinfo_msg_error(" invalid circular coordinates") ;
01415         return NullVector ;
01416     }
01417 
01418     n = 0 ;
01419     for ( j = centery - radius ; j <= centery + radius ; j++ )
01420     {
01421         for ( k = centerx - radius ; k <= centerx + radius ; k++ )
01422         {
01423             if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
01424                            radius*radius )
01425             {
01426                 n ++ ;
01427             }
01428         }
01429     }
01430     if (n == 0)
01431     {
01432         sinfo_msg_error (" no data points found!") ;
01433         return NullVector ;
01434     }
01435     circsize = n ;
01436 
01437     /* allocate a new sinfo_vector to store the average spectral values */
01438     if (NULL == (sum = sinfo_new_vector (inp)) )
01439     {
01440         sinfo_msg_error ("  cannot allocate a new sinfo_vector") ;
01441         return NullVector ;
01442     }
01443 
01444     /*------------------------------------------------------------------------
01445      *  loop through the cube planes, through the x axis and the y-axis of the
01446      *  plane circle and store pixel values in a buffer.
01447      */
01448     for ( i = 0 ; i < inp ; i++ )
01449     {
01450       i_img=cpl_imagelist_get(cube,i);
01451       pidata=cpl_image_get_data_float(i_img);
01452         m = 0 ;
01453         circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
01454 
01455         for ( j = centery - radius ; j <= centery + radius ; j++ )
01456         {
01457             for ( k = centerx - radius ; k <= centerx + radius ; k++ )
01458             {
01459                 if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
01460                      radius*radius )
01461                 {
01462                     circle[m] = pidata[k + j * ilx] ;
01463                     m ++ ;
01464                 }
01465             }
01466         }
01467 
01468         for ( l = 0 ; l < circsize ; l++ )
01469         {
01470             if ( isnan(circle[l]) )
01471             {
01472                 continue ;
01473             }
01474             sum -> data[i] += circle[l] ;
01475         }
01476         cpl_free (circle) ;
01477     }
01478     return sum ;
01479 }
01480 
01494 Vector * sinfo_new_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
01495                                      int llx,
01496                                      int lly,
01497                                      int urx,
01498                                      int ury )
01499 {
01500     Vector          * mean ;
01501     pixelvalue      *local_rectangle ;
01502     int             i, j, k, l, m ;
01503     int             recsize, nv ;
01504     int ilx=0;
01505     int ily=0;
01506     int inp=0;
01507     float* pidata=NULL;
01508     cpl_image* i_img=NULL;
01509 
01510 
01511     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
01512     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
01513     inp=cpl_imagelist_get_size(cube);
01514 
01515     if ( cube == NULL || inp < 1 )
01516     {
01517         sinfo_msg_error ("  no cube to take the mean of his spectra\n") ;
01518         return NullVector ;
01519     }
01520 
01521     if ((llx<0) || (llx>=ilx) ||
01522         (urx<0) || (urx>=ilx) ||
01523         (lly<0) || (lly>=ily) ||
01524         (ury<0) || (ury>=ily) ||
01525         (llx>=urx) || (lly>=ury))
01526     {
01527         sinfo_msg_error("  invalid rectangle coordinates:") ;
01528         sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
01529                  llx, lly, urx, ury) ;
01530         return NullVector ;
01531     }
01532 
01533     recsize = (urx - llx + 1) * (ury - lly + 1) ;
01534 
01535     /* allocate a new sinfo_vector to store the average spectral values */
01536     if (NULL == (mean = sinfo_new_vector (inp)) )
01537     {
01538         sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
01539         return NullVector ;
01540     }
01541 
01542     /*------------------------------------------------------------------------
01543      *  loop through the cube planes, through the x axis and the y-axis of the
01544      *  plane rectangle and store pixel values in a buffer.
01545      */
01546     for ( i = 0 ; i < inp ; i++ )
01547     {
01548       i_img=cpl_imagelist_get(cube,i);
01549       pidata=cpl_image_get_data_float(i_img);
01550         m = 0 ;
01551         local_rectangle = (pixelvalue *) cpl_calloc (recsize, 
01552                            sizeof (pixelvalue*));
01553 
01554         for ( j = lly ; j <= ury ; j++ )
01555         {
01556             for ( k = llx ; k <= urx ; k++ )
01557             {
01558                 local_rectangle[m] = pidata[k + j * ilx] ;
01559                 m ++ ;
01560             }
01561         }
01562         nv = 0 ;
01563         for ( l = 0 ; l < recsize ; l++ )
01564         {
01565             if ( isnan(local_rectangle[l]) )
01566             {
01567                 continue ;
01568             }
01569             mean -> data[i] += local_rectangle[l] ;
01570             nv ++;
01571         }
01572         if ( nv == 0 )
01573         {
01574             mean -> data[i] = ZERO ;
01575         }
01576         else
01577         {
01578             mean -> data[i] /= nv ;
01579         }
01580         cpl_free ( local_rectangle ) ;
01581     }
01582     return mean ;
01583 }
01584 
01596 Vector * 
01597 sinfo_new_mean_circle_of_cube_spectra( cpl_imagelist * cube,
01598                                   int       centerx,
01599                                   int       centery,
01600                                   int       radius )
01601 {
01602     Vector          * mean ;
01603     pixelvalue      * circle ;
01604     int             i, j, k, l, m, n ;
01605     int             circsize, nv ;
01606     int ilx=0;
01607     int ily=0;
01608     int inp=0;
01609     float* pidata=NULL;
01610     cpl_image* i_img=NULL;
01611 
01612 
01613     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
01614     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
01615     inp=cpl_imagelist_get_size(cube);
01616 
01617     if ( cube == NULL || inp < 1 )
01618     {
01619         sinfo_msg_error ("no cube to take the mean of his spectra") ;
01620         return NullVector ;
01621     }
01622 
01623     if ((centerx+radius>=ilx) ||
01624         (centery+radius>=ily) ||
01625         (centerx-radius<0) ||
01626         (centery-radius<0))
01627     {
01628         sinfo_msg_error(" invalid circular coordinates") ;
01629         return NullVector ;
01630     }
01631 
01632     n = 0 ;
01633     for ( j = centery - radius ; j <= centery + radius ; j++ )
01634     {
01635         for ( k = centerx - radius ; k <= centerx + radius ; k++ )
01636         {
01637             if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
01638                  radius*radius )
01639             {
01640                 n ++ ;
01641             }
01642         }
01643     }
01644     if (n == 0)
01645     {
01646         sinfo_msg_error (" no data points found!\n") ;
01647         return NullVector ;
01648     }
01649     circsize = n ;
01650 
01651     /* allocate a new sinfo_vector to store the average spectral values */
01652     if (NULL == (mean = sinfo_new_vector (inp)) )
01653     {
01654         sinfo_msg_error (" cannot allocate a new sinfo_vector \n") ;
01655         return NullVector ;
01656     }
01657 
01658     /*------------------------------------------------------------------------
01659      *  loop through the cube planes, through the x axis and the y-axis of the
01660      *  plane circle and store pixel values in a buffer.
01661      */
01662     for ( i = 0 ; i < inp ; i++ )
01663     {
01664       i_img=cpl_imagelist_get(cube,i);
01665       pidata=cpl_image_get_data_float(i_img);
01666         m = 0 ;
01667         circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
01668 
01669         for ( j = centery - radius ; j <= centery + radius ; j++ )
01670         {
01671             for ( k = centerx - radius ; k <= centerx + radius ; k++ )
01672             {
01673                 if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
01674                      radius*radius )
01675                 {
01676                     circle[m] = pidata[k + j * ilx] ;
01677                     m ++ ;
01678                 }
01679             }
01680         }
01681 
01682         nv = 0 ;
01683         for ( l = 0 ; l < circsize ; l++ )
01684         {
01685             if ( isnan(circle[l]) )
01686             {
01687                 continue ;
01688             }
01689             mean -> data[i] += circle[l] ;
01690             nv ++;
01691         }
01692         if ( nv == 0 )
01693         {
01694             mean -> data[i] = ZERO ;
01695         }
01696         else
01697         {
01698             mean -> data[i] /= nv ;
01699         }
01700 
01701         cpl_free (circle) ;
01702     }
01703     return mean ;
01704 }
01705 
01715 Vector * sinfo_new_blackbody_spectrum( char * templateSpec, double temp )
01716 {
01717     Vector * retSpec ;
01718     int n ;
01719     double cenpix ;
01720     int npix ;
01721     double cenLambda ;
01722     double firstLambda ;
01723     double disp ;
01724     double lambda ;
01725     double intens ;
01726     double denom ;
01727     double norm ;
01728     cpl_propertylist* plist=NULL;
01729 
01730     if ( NULL == templateSpec )
01731     {
01732         sinfo_msg_error (" now input image given!\n") ;
01733         return NULL ;
01734     }
01735     if ( temp < 0. )
01736     {
01737         sinfo_msg_error (" wrong temperature given!\n") ;
01738         return NULL ;
01739     }
01740     /* get the fits header information needed */
01741     if ((cpl_error_code)((plist=cpl_propertylist_load(templateSpec,0))==NULL)){
01742       sinfo_msg_error( "getting header from frame %s",templateSpec);
01743       cpl_propertylist_delete(plist) ;
01744       return NULL ;
01745     }
01746 
01747 
01748     cenpix = sinfo_pfits_get_crpix2(plist);
01749     if(cpl_error_get_code() != CPL_ERROR_NONE) {
01750         sinfo_msg_error (" cannot get CRPIX2\n") ;
01751         sinfo_free_propertylist(&plist) ;
01752         return NULL ;
01753     }
01754 
01755     cenLambda = sinfo_pfits_get_crval2(plist);
01756     if(cpl_error_get_code() != CPL_ERROR_NONE) {
01757         sinfo_msg_error (" cannot get CRVAL2\n") ;
01758         sinfo_free_propertylist(&plist) ;
01759         return NULL ;
01760     }
01761     disp = sinfo_pfits_get_cdelt2(plist);
01762     if(cpl_error_get_code() != CPL_ERROR_NONE) {
01763         sinfo_msg_error (" cannot get CDELT2\n") ;
01764         sinfo_free_propertylist(&plist) ;
01765         return NULL ;
01766     }
01767     npix = sinfo_pfits_get_naxis2(plist);
01768     if(cpl_error_get_code() != CPL_ERROR_NONE) {
01769         sinfo_msg_error (" cannot get NAXIS2\n") ;
01770         sinfo_free_propertylist(&plist) ;
01771         return NULL ;
01772     }
01773     sinfo_free_propertylist(&plist) ;
01774 
01775 
01776     if (NULL == (retSpec = sinfo_new_vector (npix)))
01777     {
01778         sinfo_msg_error (" could not allocate memory!\n") ;
01779         return NULL ;
01780     }
01781     
01782     /* shift from fits to image coordinates */
01783     cenpix-- ;
01784   
01785     firstLambda = cenLambda - cenpix * disp ;
01786     for ( n = 0 ; n < npix ; n++ )
01787     {
01788         lambda = firstLambda + disp * (double)n ;
01789         /* convert from microns to m */
01790 
01791         lambda /= 1.0e6 ;
01792         denom = 1./(exp(PLANCK*SPEED_OF_LIGHT/(lambda*BOLTZMANN*temp)) - 1.) ;
01793         intens = 2.*PI_NUMB*PLANCK*SPEED_OF_LIGHT*SPEED_OF_LIGHT / 
01794                  pow(lambda, 5) * denom ;
01795         retSpec->data[n] = intens ;   
01796     }
01797     norm = retSpec->data[npix/2] ;
01798     for ( n = 0 ; n < npix ; n++ )
01799     {
01800         retSpec->data[n] /= norm ;
01801     }
01802     
01803     return retSpec ;
01804 }
01805 
01806 
01820 Vector * sinfo_new_median_rectangle_of_cube_spectra( cpl_imagelist * cube,
01821                                              int llx,
01822                                              int lly,
01823                                              int urx,
01824                                              int ury )
01825 {
01826     Vector          * med ;
01827     pixelvalue      *local_rectangle ;
01828     int             i, j, k, m ;
01829     int             recsize ;
01830     int ilx=0;
01831     int ily=0;
01832     int inp=0;
01833     float* pidata=NULL;
01834     cpl_image* i_img=NULL;
01835 
01836 
01837     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
01838     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
01839     inp=cpl_imagelist_get_size(cube);
01840 
01841     if ( cube == NULL || inp < 1 )
01842     {
01843         sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
01844         return NullVector ;
01845     }
01846 
01847     if ((llx<0) || (llx>=ilx) ||
01848         (urx<0) || (urx>=ilx) ||
01849         (lly<0) || (lly>=ily) ||
01850         (ury<0) || (ury>=ily) ||
01851         (llx>=urx) || (lly>=ury))
01852     {
01853         sinfo_msg_error(" invalid rectangle coordinates:") ;
01854         sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]", 
01855                         llx, lly, urx, ury) ;
01856         return NullVector ;
01857     }
01858 
01859     recsize = (urx - llx + 1) * (ury - lly + 1) ;
01860 
01861     /* allocate a new sinfo_vector to store the average spectral values */
01862     if (NULL == (med = sinfo_new_vector (inp)) )
01863     {
01864         sinfo_msg_error (" cannot allocate a new sinfo_vector \n") ;
01865         return NullVector ;
01866     }
01867 
01868     /*------------------------------------------------------------------------
01869      *  loop through the cube planes, through the x axis and the y-axis of the
01870      *  plane rectangle and store pixel values in a buffer.
01871      */
01872     for ( i = 0 ; i < inp ; i++ )
01873     {
01874 
01875       i_img=cpl_imagelist_get(cube,i);
01876       pidata=cpl_image_get_data_float(i_img);
01877       m = 0 ;
01878       local_rectangle=(pixelvalue *)cpl_calloc(recsize, sizeof (pixelvalue*));
01879 
01880         for ( j = lly ; j <= ury ; j++ )
01881         {
01882             for ( k = llx ; k <= urx ; k++ )
01883             {
01884                 if ( isnan(pidata[k+j*ilx]) )
01885                 {
01886                     continue ;
01887                 }
01888                 else
01889                 {
01890                     local_rectangle[m] = pidata[k + j * ilx] ;
01891                     m ++ ;
01892                 }
01893             }
01894         }
01895         if ( m == 0 )
01896         {
01897             med->data[i] = 0. ;
01898         }
01899         else
01900         {
01901             med->data[i] = sinfo_new_median(local_rectangle, m) ;
01902         }
01903         cpl_free ( local_rectangle ) ;
01904     }
01905     return med ;
01906 }
01907 
01919 Vector * sinfo_new_median_circle_of_cube_spectra( cpl_imagelist * cube,
01920                                   int       centerx,
01921                                   int       centery,
01922                                   int       radius )
01923 {
01924     Vector          * med ;
01925     pixelvalue      * circle ;
01926     int             i, j, k, l, m, n ;
01927     int             circsize, nv ;
01928     int ilx=0;
01929     int ily=0;
01930     int inp=0;
01931     float* pidata=NULL;
01932     cpl_image* i_img=NULL;
01933 
01934 
01935     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
01936     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
01937     inp=cpl_imagelist_get_size(cube);
01938 
01939     if ( cube == NULL || inp < 1 )
01940     {
01941         sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
01942         return NullVector ;
01943     }
01944 
01945     if ((centerx+radius>=ilx) ||
01946         (centery+radius>=ily) ||
01947         (centerx-radius<0) ||
01948         (centery-radius<0))
01949     {
01950         sinfo_msg_error(" invalid circular coordinates") ;
01951         return NullVector ;
01952     }
01953 
01954     n = 0 ;
01955     for ( j = centery - radius ; j <= centery + radius ; j++ )
01956     {
01957         for ( k = centerx - radius ; k <= centerx + radius ; k++ )
01958         {
01959             if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
01960                   radius*radius )
01961             {
01962                 n ++ ;
01963             }
01964         }
01965     }
01966     if (n == 0)
01967     {
01968         sinfo_msg_error (" no data points found!") ;
01969         return NullVector ;
01970     }
01971     circsize = n ;
01972 
01973     /* allocate a new sinfo_vector to store the average spectral values */
01974     if (NULL == (med = sinfo_new_vector (inp)) )
01975     {
01976         sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
01977         return NullVector ;
01978     }
01979 
01980     /*------------------------------------------------------------------------
01981      *  loop through the cube planes, through the x axis and the y-axis of the
01982      *  plane circle and store pixel values in a buffer.
01983      */
01984     for ( i = 0 ; i < inp ; i++ )
01985     {
01986       i_img=cpl_imagelist_get(cube,i);
01987       pidata=cpl_image_get_data_float(i_img);
01988         m = 0 ;
01989         circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
01990 
01991         for ( j = centery - radius ; j <= centery + radius ; j++ )
01992         {
01993             for ( k = centerx - radius ; k <= centerx + radius ; k++ )
01994             {
01995                 if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
01996                       radius*radius )
01997                 {
01998                     circle[m] = pidata[k + j * ilx] ;
01999                     m ++ ;
02000                 }
02001             }
02002         }
02003 
02004         nv = 0 ;
02005         for ( l = 0 ; l < circsize ; l++ )
02006         {
02007             if ( isnan(circle[l]) )
02008             {
02009                 continue ;
02010             }
02011             med -> data[i] += circle[l] ;
02012             nv ++;
02013         }
02014         if ( nv == 0 )
02015         {
02016             med->data[i] = 0. ;
02017         }
02018         else
02019         {
02020             med->data[i] = sinfo_new_median(circle, nv) ; 
02021         }
02022         cpl_free (circle) ;
02023     }
02024     return med ;
02025 }
02026 
02040 Vector * 
02041 sinfo_new_cleanmean_rectangle_of_cube_spectra( cpl_imagelist * cube,
02042                                           int llx,
02043                                           int lly,
02044                                           int urx,
02045                                           int ury,
02046                                           float lo_reject,
02047                                           float hi_reject )
02048 {
02049     Vector          * clean ;
02050     pixelvalue      *local_rectangle ;
02051     int             i, j, k, m ;
02052     int             recsize ;
02053     int ilx=0;
02054     int ily=0;
02055     int inp=0;
02056     float* pidata=NULL;
02057     cpl_image* i_img=NULL;
02058 
02059 
02060     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
02061     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
02062     inp=cpl_imagelist_get_size(cube);
02063 
02064     if ( cube == NULL || inp < 1 )
02065     {
02066         sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
02067         return NullVector ;
02068     }
02069 
02070     if ((llx<0) || (llx>=ilx) ||
02071         (urx<0) || (urx>=ilx) ||
02072         (lly<0) || (lly>=ily) ||
02073         (ury<0) || (ury>=ily) ||
02074         (llx>=urx) || (lly>=ury))
02075     {
02076         sinfo_msg_error(" invalid rectangle coordinates:") ;
02077         sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
02078                  llx, lly, urx, ury) ;
02079         return NullVector ;
02080     }
02081 
02082     recsize = (urx - llx + 1) * (ury - lly + 1) ;
02083 
02084     /* allocate a new sinfo_vector to store the average spectral values */
02085     if (NULL == (clean = sinfo_new_vector (inp)) )
02086     {
02087         sinfo_msg_error (" cannot allocate a new sinfo_vector") ;
02088         return NullVector ;
02089     }
02090 
02091     /*------------------------------------------------------------------------
02092      *  loop through the cube planes, through the x axis and the y-axis of the
02093      *  plane rectangle and store pixel values in a buffer.
02094      */
02095     for ( i = 0 ; i < inp ; i++ )
02096     {
02097       i_img=cpl_imagelist_get(cube,i);
02098       pidata=cpl_image_get_data_float(i_img);
02099       m = 0 ;
02100       local_rectangle=(pixelvalue *) cpl_calloc(recsize, sizeof (pixelvalue*));
02101 
02102         for ( j = lly ; j <= ury ; j++ )
02103         {
02104             for ( k = llx ; k <= urx ; k++ )
02105             {
02106                 if ( isnan(pidata[k+j*ilx]) )
02107                 {
02108                     continue ;
02109                 }
02110                 else
02111                 {
02112                     local_rectangle[m] = pidata[k + j * ilx] ;
02113                     m ++ ;
02114                 }
02115             }
02116         }
02117         if ( m == 0 )
02118         {
02119             clean->data[i] = 0. ;
02120         }
02121         else
02122         {
02123             clean->data[i] = sinfo_new_clean_mean(local_rectangle, m, 
02124                                                   lo_reject, hi_reject) ;
02125         }
02126         cpl_free ( local_rectangle ) ;
02127     }
02128     return clean ;
02129 }
02130 
02142 Vector * 
02143 sinfo_new_cleanmean_circle_of_cube_spectra( cpl_imagelist * cube,
02144                                   int       centerx,
02145                                   int       centery,
02146                                   int       radius,
02147                                   float     lo_reject,
02148                                   float     hi_reject )
02149 {
02150     Vector          * clean ;
02151     pixelvalue      * circle ;
02152     int             i, j, k, l, m, n ;
02153     int             circsize, nv ;
02154     int ilx=0;
02155     int ily=0;
02156     int inp=0;
02157     float* pidata=NULL;
02158     cpl_image* i_img=NULL;
02159 
02160     ilx=cpl_image_get_size_x(cpl_imagelist_get(cube,0));
02161     ily=cpl_image_get_size_y(cpl_imagelist_get(cube,0));
02162     inp=cpl_imagelist_get_size(cube);
02163 
02164     if ( cube == NULL || inp < 1 )
02165     {
02166         sinfo_msg_error (" no cube to take the mean of his spectra\n") ;
02167         return NullVector ;
02168     }
02169 
02170     if ((centerx+radius>=ilx) ||
02171         (centery+radius>=ily) ||
02172         (centerx-radius<0) ||
02173         (centery-radius<0))
02174     {
02175         sinfo_msg_error(" invalid circular coordinates") ;
02176         return NullVector ;
02177     }
02178 
02179     n = 0 ;
02180     for ( j = centery - radius ; j <= centery + radius ; j++ )
02181     {
02182         for ( k = centerx - radius ; k <= centerx + radius ; k++ )
02183         {
02184             if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
02185                   radius*radius )
02186             {
02187                 n ++ ;
02188             }
02189         }
02190     }
02191     if (n == 0)
02192     {
02193         sinfo_msg_error (" no data points found!\n") ;
02194         return NullVector ;
02195     }
02196     circsize = n ;
02197 
02198     /* allocate a new sinfo_vector to store the average spectral values */
02199     if (NULL == (clean = sinfo_new_vector (inp)) )
02200     {
02201         sinfo_msg_error (" cannot allocate a new sinfo_vector \n") ;
02202         return NullVector ;
02203     }
02204 
02205     /*------------------------------------------------------------------------
02206      *  loop through the cube planes, through the x axis and the y-axis of the
02207      *  plane circle and store pixel values in a buffer.
02208      */
02209     for ( i = 0 ; i < inp ; i++ )
02210     {
02211       i_img=cpl_imagelist_get(cube,i);
02212       pidata=cpl_image_get_data_float(i_img);
02213         m = 0 ;
02214         circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
02215 
02216         for ( j = centery - radius ; j <= centery + radius ; j++ )
02217         {
02218             for ( k = centerx - radius ; k <= centerx + radius ; k++ )
02219             {
02220                 if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
02221                      radius*radius )
02222                 {
02223                     circle[m] = pidata[k + j * ilx] ;
02224                     m ++ ;
02225                 }
02226             }
02227         }
02228 
02229         nv = 0 ;
02230         for ( l = 0 ; l < circsize ; l++ )
02231         {
02232             if ( isnan(circle[l]) )
02233             {
02234                 continue ;
02235             }
02236             clean -> data[i] += circle[l] ;
02237             nv ++;
02238         }
02239         if ( nv == 0 )
02240         {
02241             clean->data[i] = 0. ;
02242         }
02243         else
02244         {
02245             clean->data[i] = sinfo_new_clean_mean(circle, nv, 
02246                                                   lo_reject, hi_reject) ; 
02247         }
02248         cpl_free (circle) ;
02249     }
02250     return clean ;
02251 }
02252 
02264 float * 
02265 sinfo_new_shift_array ( float * input, int n_elements, 
02266                         float shift, double * ker ) 
02267 {
02268     float  *         shifted ;
02269     int              samples = KERNEL_SAMPLES ;
02270     int           i ;
02271     float            fx ;
02272     float            rx ;
02273     int              px ;
02274     int              tabx ;
02275     float            value ;
02276     /*size_t           pos ;*/
02277     register float * pix ;
02278     int              mid;
02279     float            norm ;
02280 
02281     /* error handling: test entries */
02282     if (input==NULL) 
02283     {
02284         sinfo_msg_error(" no input array given!\n") ;
02285         return NULL ;
02286     }
02287     if (n_elements<=0) 
02288     {
02289         sinfo_msg_error(" wrong number of elements in input array given!\n") ;
02290         return NULL ;
02291     }
02292 
02293     shifted    = (float*) cpl_calloc(n_elements, sizeof(float)) ;
02294 
02295     /* Shifting by a zero offset returns a copy of the input image */
02296     if ((fabs(shift)<1e-2))
02297     {
02298         for (i = 0 ; i <  n_elements ; i++ )
02299         {
02300             shifted[i] = input[i] ;
02301         }
02302         return shifted ;
02303     }
02304     
02305     mid = (int)samples/(int)2 ;
02306 
02307     for (i=1 ; i<  n_elements-2 ; i++) 
02308     {
02309         fx = (float)i+shift ;
02310         px = sinfo_new_nint(fx) ;
02311         rx = fx - (float)px ;
02312         pix = input ;
02313 
02314         if ((px>=1) && (px<(n_elements-2))) 
02315         {
02316             tabx = (int)(fabs((float)mid * rx)) ;
02317             /* exclude blank (ZERO) pixels from interpolation */
02318             if (isnan(pix[i]))
02319             {
02320                 value = ZERO ;
02321             }
02322             else
02323             {
02324                 if (isnan(pix[i-1]))
02325                 {
02326                     pix[i-1] = 0. ;
02327                 }
02328                 if (isnan(pix[i+1]))
02329                 {
02330                     pix[i+1] = 0. ;
02331                 }
02332                 if (isnan(pix[i+2]))
02333                 {
02334                     pix[i+2] = 0. ;
02335                 }
02336 
02337                 /*
02338                  * Sum up over 4 closest pixel values,
02339                  * weighted by interpolation kernel values
02340                  */
02341                 value =     pix[i-1] * ker[mid+tabx] +
02342                             pix[i] *   ker[tabx] +
02343                             pix[i+1] * ker[mid-tabx] +
02344                             pix[i+2] * ker[samples-tabx-1] ;
02345                 /*
02346                  * Also sum up interpolation kernel coefficients
02347                  * for further normalization
02348                  */
02349                 norm =      ker[mid+tabx] +
02350                             ker[tabx] +
02351                             ker[mid-tabx] +
02352                             ker[samples-tabx-1] ;
02353                 if (fabs(norm) > 1e-4) 
02354                 {
02355                     value /= norm ;
02356                 }
02357             }
02358         }   
02359         else 
02360         {
02361             value = 0.0 ;
02362         }
02363         if ( isnan(value) )
02364         {
02365             shifted[i] = ZERO ;
02366         }
02367         else
02368         {
02369             shifted[i] = value ;
02370         }
02371     }  
02372     return shifted ;
02373 }
02374 
02375 
02376 /*--------------------------------------------------------------------------*/
02377 
02389 cpl_image * 
02390 sinfo_new_div_image_by_spectrum( cpl_image * image, cpl_image * spectrum )
02391 {
02392     int col, row ;
02393     cpl_image * retImage ;
02394     int ilx=0;
02395     int ily=0;
02396 
02397     int slx=0;
02398     int sly=0;
02399 
02400     float* pidata=NULL;
02401     float* psdata=NULL;
02402     float* podata=NULL;
02403 
02404     if ( image == NULL )
02405     {
02406         sinfo_msg_error("no image given!") ;
02407         return NULL ;
02408     }
02409     ilx=cpl_image_get_size_x(image);
02410     ily=cpl_image_get_size_y(image);
02411 
02412 
02413     if ( spectrum == NULL )
02414     {
02415         sinfo_msg_error("no spectrum image given!") ;
02416         return NULL ;
02417     }
02418     slx=cpl_image_get_size_x(spectrum);
02419     sly=cpl_image_get_size_y(spectrum);
02420 
02421     if ( sly != ily )
02422     {
02423         sinfo_msg_error("images are not compatible in pixel length!") ;
02424         return NULL ;
02425     }
02426     if ( NULL == (retImage = cpl_image_duplicate(image)) )
02427     {
02428         sinfo_msg_error("could not copy original image!") ;
02429         return NULL ;
02430     }
02431     pidata=cpl_image_get_data_float(image);
02432     psdata=cpl_image_get_data_float(spectrum);
02433     podata=cpl_image_get_data_float(retImage);
02434 
02435     for ( col = 0 ; col < ilx ; col++ )
02436     {
02437         for ( row = 0 ; row < ily ; row++ )
02438         {
02439             if ( !isnan(pidata[col+row*ilx]) &&
02440                  !isnan(psdata[col+row*ilx]))
02441             {
02442                 podata[col+row*ilx] = pidata[col+row*ilx] / psdata[row] ;
02443             }
02444          }
02445     }
02446     return retImage ;
02447 }
02448 
02449 /*---------------------------------------------------------------------------
02450    Function     :       sinfo_new_clean_mean_circle_of_cube_spectra()
02451    In           :       cube: 1 allocated cube, 
02452                         centerx, centery: center pixel of circular aperture 
02453                                           in image coordinates
02454                         radius: integer radius of circular aperture
02455    Out          :       result spectrum vector
02456    Job          :       clean averaging routine for a reduced data to get 
02457                         a better spectral S/N only for a circular aperture.
02458  ---------------------------------------------------------------------------*/
02459 
02460 Vector * sinfo_new_clean_mean_circle_of_cube_spectra(cpl_imagelist * cube,
02461                                   int       centerx,
02462                                   int       centery,
02463                                   int       radius,
02464                                   float     lo_reject,
02465                                   float     hi_reject )
02466 {
02467     Vector          * clean ;
02468     pixelvalue      * circle ;
02469     int             i, j, k, l, m, n ;
02470     int             circsize, nv ;
02471     int lx=0;
02472     int ly=0;
02473     int lz=0;
02474     float* pidata=NULL;
02475     cpl_image* img=NULL;
02476 
02477     lz=cpl_imagelist_get_size(cube);
02478 
02479     if ( cube == NULL || lz < 1 )
02480     {
02481         sinfo_msg_error (" no cube to take the mean of his spectra") ;
02482         return NullVector ;
02483     }
02484     img=cpl_imagelist_get(cube,0);
02485     lx=cpl_image_get_size_x(img);
02486     ly=cpl_image_get_size_y(img);
02487 
02488     if ((centerx+radius>=lx) ||
02489         (centery+radius>=ly) ||
02490         (centerx-radius<0) ||
02491         (centery-radius<0))
02492     {
02493         sinfo_msg_error(" invalid circular coordinates") ;
02494         return NullVector ;
02495     }
02496 
02497     n = 0 ;
02498     for ( j = centery - radius ; j <= centery + radius ; j++ )
02499     {
02500         for ( k = centerx - radius ; k <= centerx + radius ; k++ )
02501         {
02502             if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
02503                  radius*radius )
02504             {
02505                 n ++ ;
02506             }
02507         }
02508     }
02509     if (n == 0)
02510     {
02511         sinfo_msg_error (" no data points found!") ;
02512         return NullVector ;
02513     }
02514     circsize = n ;
02515 
02516     /* allocate a new vector to store the average spectral values */
02517     if (NULL == (clean = sinfo_new_vector (lz)) )
02518     {
02519         sinfo_msg_error (" cannot allocate a new vector") ;
02520         return NullVector ;
02521     }
02522 
02523     /*------------------------------------------------------------------------
02524      *  loop through the cube planes, through the x axis and the y-axis of the
02525      *  plane circle and store pixel values in a buffer.
02526      */
02527     for ( i = 0 ; i < lz ; i++ )
02528     {
02529       img=cpl_imagelist_get(cube,i);
02530       pidata=cpl_image_get_data(img);
02531       m = 0 ;
02532       circle = (pixelvalue *) cpl_calloc (circsize, sizeof (pixelvalue*));
02533 
02534       for ( j = centery - radius ; j <= centery + radius ; j++ )
02535         {
02536             for ( k = centerx - radius ; k <= centerx + radius ; k++ )
02537             {
02538                 if ( (k-centerx)*(k-centerx)+(j-centery)*(j-centery) <= 
02539                      radius*radius )
02540                 {
02541                      circle[m] = pidata[k + j * lx] ;
02542                     m ++ ;
02543                 }
02544             }
02545         }
02546 
02547         nv = 0 ;
02548         for ( l = 0 ; l < circsize ; l++ )
02549         {
02550             if ( isnan(circle[l]) )
02551             {
02552                 continue ;
02553             }
02554             clean -> data[i] += circle[l] ;
02555             nv ++;
02556         }
02557         if ( nv == 0 )
02558         {
02559             clean->data[i] = 0. ;
02560         }
02561         else
02562         {
02563             clean->data[i] = sinfo_new_clean_mean(circle, nv, 
02564                                                   lo_reject, hi_reject) ; 
02565         }
02566         cpl_free (circle) ;
02567     }
02568     return clean ;
02569 }
02570 
02571 
02572 
02573 /*---------------------------------------------------------------------------
02574    Function     :       sinfo_new_clean_mean_rectangle_of_cube_spectra()
02575    In           :       cube: 1 allocated cube, 
02576                         llx, lly, urx, ury: lower left and upper right
02577                                             position of rectangle in x-y plane ,
02578                                             image coordinates 0...
02579    Out          :       result spectrum vector
02580    Job          :       clean averaging routine for a reduced data to get a
02581                         better spectral S/N only for a rectangular aperture.
02582  ---------------------------------------------------------------------------*/
02583 
02584 Vector * sinfo_new_clean_mean_rectangle_of_cube_spectra( cpl_imagelist * cube,
02585                                           int llx,
02586                                           int lly,
02587                                           int urx,
02588                                           int ury,
02589                                           float lo_reject,
02590                                           float hi_reject )
02591 {
02592     Vector          * clean ;
02593     pixelvalue      *rectangle ;
02594     int             i, j, k, m ;
02595     int             recsize ;
02596     int lx=0;
02597     int ly=0;
02598     int lz=0;
02599     float* pidata=0;
02600     cpl_image* img=NULL;
02601 
02602     lz=cpl_imagelist_get_size(cube);
02603 
02604     if ( cube == NULL || lz < 1 )
02605     {
02606         sinfo_msg_error (" no cube to take the mean of his spectra") ;
02607         return NullVector ;
02608     }
02609     img=cpl_imagelist_get(cube,0);
02610     lx=cpl_image_get_size_x(img);
02611     ly=cpl_image_get_size_y(img);
02612 
02613     if ((llx<0) || (llx>=lx) ||
02614         (urx<0) || (urx>=lx) ||
02615         (lly<0) || (lly>=ly) ||
02616         (ury<0) || (ury>=ly) ||
02617         (llx>=urx) || (lly>=ury))
02618     {
02619         sinfo_msg_error(" invalid rectangle coordinates:") ;
02620         sinfo_msg_error("lower left is [%d %d] upper right is [%d %d]",
02621                  llx, lly, urx, ury) ;
02622         return NullVector ;
02623     }
02624 
02625     recsize = (urx - llx + 1) * (ury - lly + 1) ;
02626 
02627     /* allocate a new vector to store the average spectral values */
02628     if (NULL == (clean = sinfo_new_vector (lz)) )
02629     {
02630         sinfo_msg_error (" cannot allocate a new vector") ;
02631         return NullVector ;
02632     }
02633 
02634     /*------------------------------------------------------------------------
02635      *  loop through the cube planes, through the x axis and the y-axis of the
02636      *  plane rectangle and store pixel values in a buffer.
02637      */
02638     for ( i = 0 ; i < lz ; i++ )
02639     {
02640         m = 0 ;
02641         rectangle = (pixelvalue *) cpl_calloc (recsize, sizeof (pixelvalue*));
02642         img=cpl_imagelist_get(cube,i);
02643         pidata=cpl_image_get_data(img);
02644         for ( j = lly ; j <= ury ; j++ )
02645         {
02646             for ( k = llx ; k <= urx ; k++ )
02647             {
02648                 if ( isnan(pidata[k+j*lx]) )
02649                 {
02650                     continue ;
02651                 }
02652                 else
02653                 {
02654                     rectangle[m] = pidata[k + j * lx] ;
02655                     m ++ ;
02656                 }
02657             }
02658         }
02659         if ( m == 0 )
02660         {
02661             clean->data[i] = 0. ;
02662         }
02663         else
02664         {
02665             clean->data[i] = sinfo_new_clean_mean(rectangle, m, 
02666                                                   lo_reject, hi_reject) ;
02667         }
02668         cpl_free ( rectangle ) ;
02669     }
02670     return clean ;
02671 }
02672 
02673 /*--------------------------------------------------------------------------*/

Generated on 3 Mar 2013 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1