sinfo_wavecal.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  22/01/02  created
00027 */
00028 
00029 /************************************************************************
00030 *   NAME
00031 *     sinfo_wavecal.c -
00032 *     routines needed for wavelength calibration with smoothing only
00033 *     within the slitlets
00034 *
00035 *   SYNOPSIS
00036 *  1) Bcoeffs * sinfo_new_b_coeffs( int n_slitlets,
00037 *                           int n_acoeffs,
00038 *                           int n_bcoeffs )
00039 *  2) void sinfo_new_destroy_b_coeffs ( Bcoeffs * bco )
00040 *  3) int   sinfo_new_coeffs_cross_slit_fit ( int      n_columns,
00041 *                                float ** acoefs,
00042 *                                float ** dacoefs,
00043 *                                Bcoeffs* bco,
00044 *                                float    sigma_factor,
00045 *                                float    dispersion,
00046 *                                float    pixel_dist,
00047 *                                float  * chisq )
00048 *  4) cpl_image * sinfo_new_wave_map_slit ( float ** acoefs,
00049 *                              int      n_acoefs,
00050 *                              int      n_rows,
00051 *                              int      n_columns )
00052 *  5) cpl_image * sinfo_new_wave_cal( cpl_image   * image, 
00053 *                         FitParams ** par ,
00054 *                         float     ** abuf,
00055 *                         int          n_slitlets,
00056 *                         int       ** row_clean,
00057 *                         float     ** wavelength_clean,
00058 *                         int        * n_found_lines,
00059 *                         float        dispersion,
00060 *                         int          halfWidth,
00061 *                         float        minAmplitude,
00062 *                         float        max_residual,
00063 *                         float        fwhm,
00064 *                         int          n_a_fitcoefs,
00065 *                         int          n_b_fitcoefs,
00066 *                         float        sigmaFactor,
00067 *                         float        pixel_dist )
00068 *  6) int sinfo_new_check_for_fake_lines ( FitParams ** par,
00069 *                             float        dispersion,
00070 *                             float     ** wavelength_clean,
00071 *                             int       ** row_clean,
00072 *                             int        * n_found_lines,
00073 *                             int          n_columns,
00074 *                             float        pixel_tolerance )
00075 *  7) cpl_image * sinfo_new_create_shifted_slit_wavemap ( cpl_image * lineIm,
00076 *                                           float    ** coeffs,
00077 *                                           int      n_fitcoeffs,
00078 *                                           float  * wavelength,
00079 *                                           float  * intensity,
00080 *                                           int      n_lines,
00081 *                                           int      magFactor )
00082 *   
00083 *   DESCRIPTION
00084 *  1) allocates memory for a new array of 
00085 *     Bcoeffs data structures
00086 *  2) frees memory of an array of Bcoeffs data structures
00087 *  3) Fits each single polynomial coefficient acoefs resulting from 
00088       sinfo_polyfit 
00089 *     across the columns of each slitlet and use the result of this fit to
00090 *     smooth the acoefs.
00091 *  4) builds a new wavelength calibration map as fits image
00092 *     by using the fit coeficients.
00093 *  5) this routine takes an image from a calibration
00094 *     emission lamp and delivers the smoothed fit coefficients of  
00095 *     a polynomial fit along the columns of the line positions as output. 
00096 *     This routine expects Nyquist sampled spectra 
00097 *     (either an interleaved image or an image convolved with an 
00098 *      appropriate function in spectral direction)
00099 *  6) this routine searches for successfully fitted fake lines like
00100 *     bad pixels by comparing the found line positons with 
00101 *     estimated template positions. This routine should be
00102 *     inserted in the wavelength calibration routine just after
00103 *     the sinfo_fitLines() routine.
00104 *  7) This routine cross-correlates a shifted emission line frames 
00105 *     and determines the shift to the old one which is given by
00106 *     its polynomial coefficients.
00107 *     Then the a0 coefficients is recalculated and afterwards
00108 *     a new wavelength calibration map is generated using the 
00109 *     already calculated smoothed polynomial coefficients.
00110 *
00111 *   FILES
00112 *
00113 *   ENVIRONMENT
00114 *
00115 *   RETURN VALUES 
00116 *
00117 *   CAUTIONS 
00118 *
00119 *   EXAMPLES
00120 *
00121 *   SEE ALSO
00122 *
00123 *   BUGS   
00124 *
00125 *------------------------------------------------------------------------
00126 */
00127 
00128 #ifdef HAVE_CONFIG_H
00129 #  include <config.h>
00130 #endif
00131 #include "sinfo_vltPort.h"
00132 #include <math.h>
00133 
00134 /* 
00135  * System Headers
00136  */
00137 /* 
00138  * Local Headers
00139  */
00140 
00141 #include "sinfo_function_1d.h"
00142 #include "sinfo_recipes.h"
00143 #include "sinfo_wavecal.h"
00144 #include "sinfo_wave_calibration.h"
00145 #include "sinfo_solve_poly_root.h"
00146 #include "sinfo_utils_wrappers.h"
00147 #include "sinfo_error.h"
00148 
00149 #include "sinfo_svd.h"
00150 /*
00151  * Private functions prototype
00152  */
00153 static Bcoeffs * 
00154 sinfo_new_b_coeffs( int n_slitlets,
00155                       int n_acoeffs,
00156                       int n_bcoeffs ) ;
00157 
00158 static void 
00159 sinfo_new_destroy_b_coeffs ( Bcoeffs * bco ) ;
00160 
00161 static int   
00162 sinfo_new_coeffs_cross_slit_fit ( int      n_columns,
00163                            float ** acoefs,
00164                            float ** dacoefs,
00165                            Bcoeffs* bco,
00166                            float    sigma_factor,
00167                            float    dispersion,
00168                            float    pixel_dist,
00169                            float  * chisq ) ;
00170 
00171 
00172 static int   
00173 sinfo_new_spred_coeffs_cross_slit_fit ( int      n_columns,
00174                             float ** acoefs,
00175                             float ** dacoefs,
00176                             Bcoeffs* bco,
00177                             float    sigma_factor,
00178                             float    dispersion,
00179                             float    pixel_dist,
00180                             float  * chisq,
00181                           float ** sinfo_slit_pos) ;
00182 /*
00183  * function definitions
00184  */
00200 static Bcoeffs * 
00201 sinfo_new_b_coeffs( int n_slitlets,
00202                       int n_acoeffs,
00203                       int n_bcoeffs )
00204 {
00205     int i, n ;
00206     Bcoeffs * returnbco ;
00207 
00208     if(NULL == (returnbco=(Bcoeffs*) cpl_calloc(n_slitlets, sizeof(Bcoeffs))) )
00209     {
00210         sinfo_msg_error ("could not allocate memory") ;
00211         return NULL ;
00212     }
00213     returnbco -> n_slitlets = n_slitlets ;
00214     returnbco -> n_acoeffs  = n_acoeffs ;
00215     returnbco -> n_bcoeffs  = n_bcoeffs ;
00216     for ( i = 0 ; i < n_slitlets ; i++ )
00217     {
00218         returnbco[i].slitlet = i ;
00219         if ( NULL == (returnbco[i].b = (float**)cpl_calloc(n_acoeffs, 
00220                                                 sizeof(float*)) ) ) 
00221         {
00222             sinfo_msg_error ("could not allocate memory") ;
00223             return NULL ;
00224         }
00225         for ( n = 0 ; n < n_acoeffs ; n++ )
00226         {
00227             if ( NULL == (returnbco[i].b[n] = (float*)cpl_calloc(n_bcoeffs, 
00228                                                sizeof(float))) )
00229             {
00230                 sinfo_msg_error ("could not allocate memory") ;
00231                 return NULL ;
00232             }
00233         }  
00234     }
00235     return returnbco ;
00236 }
00237 
00245 static void 
00246 sinfo_new_destroy_b_coeffs ( Bcoeffs * bco )
00247 {
00248     int i, n ;
00249   
00250     for ( i = 0 ; i < bco->n_slitlets ; i++ )
00251     {
00252         for ( n = 0 ; n < bco->n_acoeffs ; n++ )
00253         {
00254             cpl_free (bco[i].b[n]) ;
00255         }
00256         cpl_free(bco[i].b) ;
00257     }
00258     
00259     cpl_free (bco) ;  
00260 }
00261 
00287 static int   
00288 sinfo_new_coeffs_cross_slit_fit ( int      n_columns,
00289                            float ** acoefs,
00290                            float ** dacoefs,
00291                            Bcoeffs* bco,
00292                            float    sigma_factor,
00293                            float    dispersion,
00294                            float    pixel_dist,
00295                            float  * chisq )
00296 {
00297     float col_index;
00298     float ** ucoefs, **vcoefs, **covar ;
00299     float * acoefsclean ;
00300     double sum, sumq, mean ;
00301     double sigma ;
00302     double cliphi, cliplo ;
00303     float offset ;
00304     float threshold ;
00305     float* sub_col_index=NULL ;
00306     float* sub_acoefs=NULL;
00307     float* sub_dacoefs=NULL ;
00308     float* wcoefs=NULL ;
00309     int* edge=NULL ;
00310 
00311     int ed1, ed2 ;
00312     int i, n, num, ndata ;
00313     int nc, ns ;
00314     int loc_index ;
00315     int last_i=PIXEL;
00316     
00317     if ( n_columns < 1 )
00318     {
00319         sinfo_msg_error("wrong number of image columns given") ;
00320         return -1 ;
00321     }
00322     if ( acoefs == NULL || dacoefs == NULL )
00323     {
00324         sinfo_msg_error("acoeffs or errors of coefficients are not given") ;
00325         return -1 ;
00326     }
00327     if ( bco == NULL )
00328     {
00329         sinfo_msg_error("bcoeffs are not allocated") ;
00330         return -1 ;
00331     }
00332     if ( sigma_factor <= 0. )
00333     {
00334         sinfo_msg_error("impossible sigma_factor given!") ;
00335         return -1 ;
00336     }
00337     if ( dispersion == 0. )
00338     {
00339         sinfo_msg_error("impossible dispersion given!") ;
00340         return -1 ;
00341     }
00342 
00343     /*-------------------------------------------------------------------------
00344      * search for the slitlet edges by comparing the a0 coefficients along 
00345        the columns if a bigger deviation occurrs it is assumed that there 
00346        is an edge.
00347      */
00348 
00349     edge=cpl_calloc(bco->n_slitlets,sizeof(int)) ;
00350     wcoefs=cpl_calloc(bco->n_bcoeffs,sizeof(float)) ;
00351 
00352     n = 0 ;
00353     threshold = pixel_dist * fabs(dispersion) ;
00354     for ( i = PIXEL ; i < n_columns - PIXEL ; )
00355     {
00356         if ( !isnan(acoefs[0][i+1]) && 
00357                     acoefs[0][i+1] != 0. && 
00358                     acoefs[0][i] != 0.  &&
00359                     dacoefs[0][i+1] != 0.)
00360         {
00361             if ( isnan(acoefs[0][i]) || acoefs[0][i] == 0. )
00362             {
00363                 if (fabs(acoefs[0][i+1] - acoefs[0][i-1]) >= threshold )
00364                 {
00365            if( (i-last_i) < 60 && (i > 80) ) {
00366              sinfo_msg_warning("skip1 i=%d diff=%d\n",i,i-last_i);
00367              goto skip;
00368                    } else {  
00369              /*
00370                  sinfo_msg("diff1=%f i=%d threshold-%f size=%d\n", 
00371                                fabs(acoefs[0][i+1] - acoefs[0][i-1]),i,
00372                                threshold,i-last_i);
00373              */
00374                      edge[n] = i+1 ;
00375              //sinfo_msg("1found edge: %d",edge[n]);
00376                      n++ ;
00377                      last_i = i;
00378                      i += PIXEL ;
00379            }
00380                 }
00381             }
00382             else
00383             {
00384                 if ((fabs(acoefs[0][i+1] - acoefs[0][i]) >= threshold) || 
00385                     (i-last_i) > 63 )
00386                 {
00387            if( (i-last_i) < 60 && ((i> 80) || (i<PIXEL+2))) {
00388              sinfo_msg_warning("skip2 i=%d diff=%d\n",i,i-last_i);
00389              goto skip;
00390                    } else {  
00391                       
00392              /*
00393                       sinfo_msg_warning("diff2=%f i=%d threshold-%f size=%d",
00394                       fabs(acoefs[0][i+1] - acoefs[0][i]),
00395                       i,threshold,i-last_i);                      
00396                       */
00397               
00398  
00399                   
00400                       edge[n] = i+1 ;
00401                 //sinfo_msg("2found edge: %d",edge[n]);
00402                       n++ ;
00403                       last_i = i;
00404                       i += PIXEL ;
00405            }
00406                 }
00407             }
00408         /* sometimes a slitlet may be lost due to divergences in acoeffs[0]
00409                we try to recover it */
00410             if( ( (i-last_i) > 63 ) && 
00411                 ( isnan(fabs(acoefs[0][i+1] - acoefs[0][i])) ||
00412                   isnan(fabs(acoefs[0][i+1] - acoefs[0][i-1])) ) ) 
00413           {
00414         edge[n] = i+1 ;
00415         //sinfo_msg("3found edge: %d",edge[n]);
00416         n++ ;
00417         last_i = i;
00418                 sinfo_msg_warning("recovered slitlet edge i=%d",i);
00419         i += PIXEL ;
00420 
00421           }
00422     }
00423       skip:
00424         i++ ;
00425     }
00426     /*
00427     printf("X min %d max %d last %d\n", PIXEL, n_columns - PIXEL, i);
00428     printf("n=%d check=%d\n",n,bco->n_slitlets - 1);
00429     */
00430     if ( n != bco->n_slitlets - 1 )
00431     {
00432         sinfo_msg_error("could not find the right number "
00433                         "of slitlets, found: %d",n+1) ;
00434         return -1 ;
00435     }
00436  
00437     sub_col_index=cpl_calloc(n_columns,sizeof(float)) ;
00438     sub_acoefs=cpl_calloc(n_columns,sizeof(float));
00439     sub_dacoefs=cpl_calloc(n_columns,sizeof(float)) ;
00440 
00441     /* go through the coefficents indices */
00442     for ( loc_index = 0 ; loc_index < bco->n_acoeffs ; loc_index++ )
00443     {
00444         /* go through the single slitlets */
00445         for ( ns = 0 ; ns < bco->n_slitlets ; ns++ )
00446         {
00447             /* determine the slitlet edges */
00448             if ( ns == 0 )
00449             {
00450                 ed1 = 0 ;
00451                 ed2 = edge[0] ;
00452             }
00453             else if ( ns == bco->n_slitlets - 1 )
00454             {
00455                 ed1 = edge[bco->n_slitlets - 2] ;
00456                 ed2 = n_columns ;
00457             }
00458             else
00459             {
00460                 ed1 = edge[ns-1] ;
00461                 ed2 = edge[ns] ;
00462             }
00463 
00464             nc = 0 ;
00465             for ( i = ed1 ; i < ed2 ; i++ )
00466             {
00467                 if ( isnan(acoefs[loc_index][i]) || 
00468                            acoefs[loc_index][i] == 0. || 
00469                           dacoefs[loc_index][i] == 0. )
00470                 {
00471                     continue ;
00472                 }
00473                 else
00474                 {
00475                     nc++ ;
00476                 }
00477             }
00478             if (NULL==(acoefsclean = (float*) cpl_calloc(nc , sizeof(float))) )
00479             {
00480                 sinfo_msg_error("could not allocate memory for acoefsclean!") ;
00481                 return -1 ;
00482             }
00483             nc = 0 ;
00484             for ( i = ed1 ; i < ed2 ; i++ )
00485             {
00486                 if ( isnan(acoefs[loc_index][i]) || 
00487                       acoefs[loc_index][i] == 0. || 
00488                      dacoefs[loc_index][i] == 0. )
00489                 {
00490                     continue ;
00491                 }
00492                 else
00493                 {
00494                     acoefsclean[nc] = acoefs[loc_index][i] ;
00495                     nc++ ;
00496                 }
00497             }
00498 
00499             /* ----------------------------------------------------------
00500              * determine the clean mean and sigma value of the coefficients,
00501              * that means reject 10 % of the extreme low and high values
00502              */
00503             sinfo_pixel_qsort(acoefsclean, nc) ;
00504 
00505             sum   = 0. ;
00506             sumq  = 0. ;
00507             mean  = 0. ;
00508             sigma = 0. ;
00509             n     = 0 ;
00510             for ( i = (int)((float)nc*LOW_REJECT) ; 
00511                   i < (int)((float)nc*HIGH_REJECT) ; i++ )
00512             {
00513                 sum  += (double)acoefsclean[i] ;
00514                 sumq += ((double)acoefsclean[i] * (double)acoefsclean[i]) ;
00515                 n ++ ;
00516             }
00517             mean          = sum/(double)n ;
00518             sigma         = sqrt( sumq/(double)n - (mean * mean) ) ;
00519             cliphi        = mean + sigma * (double)sigma_factor ;
00520             cliplo        = mean - sigma * (double)sigma_factor ;
00521             /* fit only the reasonnable values */
00522             num = 0 ;
00523             col_index = 0 ;
00524             /*
00525             printf("ed1=%d ed2=%d\n",ed1,ed2);
00526         */
00527             for ( i = ed1 ; i < ed2 ; i++ )
00528             {
00529                 /* take only the reasonnable coefficients */
00530                  /*
00531         printf("acoeffs=%f dacoefs=%f cliphi=%f cliplo=%f\n",
00532                    acoefs[loc_index][i],dacoefs[loc_index][i],cliphi,cliplo);
00533          */
00534                 if ( !isnan(acoefs[loc_index][i])     && 
00535                      (acoefs[loc_index][i] <= cliphi) && 
00536                      (acoefs[loc_index][i] >= cliplo) &&
00537                      (dacoefs[loc_index][i] != 0. )   && 
00538                      (acoefs[loc_index][i] != 0.)     )
00539                 {
00540                     sub_acoefs[num]    = acoefs[loc_index][i] ;
00541                     sub_dacoefs[num]   = dacoefs[loc_index][i] ;
00542                     sub_col_index[num] = col_index ;
00543                     num ++ ;
00544                 }
00545                 col_index++ ;
00546             }
00547             ndata = num ;
00548             offset = (float)(col_index-1) / 2. ;
00549             /* printf("ndata=%d bco->n_bcoeffs=%d\n",ndata,bco->n_bcoeffs); */
00550 
00551             if ( ndata < bco->n_bcoeffs )
00552             {
00553                 sinfo_msg_error("not enough data found in slitlet %d to "
00554                                 "determine the fit coefficients.", ns) ;
00555                 cpl_free(acoefsclean) ;
00556                 return -1 ;
00557             }
00558 
00559             /* allocate coefficient matrices */
00560             ucoefs = sinfo_matrix(1, ndata, 1, bco->n_bcoeffs) ;
00561             vcoefs = sinfo_matrix(1, ndata, 1, bco->n_bcoeffs) ;
00562             covar  = sinfo_matrix(1, bco->n_bcoeffs, 1, bco->n_bcoeffs) ;
00563 
00564             /* scale the x-values for the fit */
00565             for ( i = 0 ; i < ndata ; i++ )
00566             {
00567                 sub_col_index[i] = (sub_col_index[i] - offset) / offset ;
00568             }
00569 
00570             /* finally, do the singular value decomposition fit */
00571             sinfo_svd_fitting ( sub_col_index-1, sub_acoefs-1, 
00572                                 sub_dacoefs-1, ndata, bco[ns].b[loc_index]-1,
00573                                 bco->n_bcoeffs, ucoefs, vcoefs, 
00574                                 wcoefs-1, covar, &chisq[ns], sinfo_fpol ) ;
00575 
00576             /* scale the found coefficients */
00577             for ( i = 0 ; i < bco->n_bcoeffs ; i ++ )
00578             {
00579                 bco[ns].b[loc_index][i] /= pow( offset, i ) ;
00580             }
00581 
00582             /* free memory */
00583             cpl_free (acoefsclean) ;
00584             sinfo_free_matrix( ucoefs, 1/*, ndata*/, 1/*, bco->n_bcoeffs */) ;
00585             sinfo_free_matrix( vcoefs, 1/*, ndata*/, 1/*, bco->n_bcoeffs */) ;
00586             sinfo_free_matrix( covar, 1/*, bco->n_bcoeffs*/, 
00587                                 1/*, bco->n_bcoeffs */) ;
00588 
00589             /* now calculate the smoothed acoefs for each column */
00590             col_index = 0 ;
00591             for ( i = ed1 ; i < ed2  ; i++ )
00592             {
00593                 acoefs[loc_index][i] = 0. ;
00594                 for ( n = 0 ; n < bco->n_bcoeffs ; n++ )
00595                 {
00596                     acoefs[loc_index][i] += bco[ns].b[loc_index][n] * 
00597                                         pow(col_index - offset, n) ;
00598                 }
00599                 col_index++ ;
00600             }
00601 
00602         }
00603     }
00604 
00605     cpl_free(sub_col_index) ;
00606     cpl_free(sub_acoefs) ;
00607     cpl_free(sub_dacoefs) ;
00608 
00609 
00610     cpl_free(edge) ;
00611     cpl_free(wcoefs) ;
00612 
00613     return 0 ;
00614 }
00615 
00616 
00629 cpl_image * sinfo_new_wave_map_slit ( float ** acoefs,
00630                          int      n_acoefs,
00631                          int      n_rows,
00632                          int      n_columns )
00633 {
00634     cpl_image * newIm=NULL ;
00635     float lambda=0 ;
00636     float offset=0 ;
00637     int col=0;
00638     int row=0 ;
00639     int i=0 ;
00640     float row_index=0 ;
00641     float* podata=NULL;
00642     if ( NULL == acoefs )
00643     {
00644         sinfo_msg_error (" no coefficient sinfo_matrix given!") ;
00645         return NULL ;
00646     }
00647 
00648     /* allocate new image */
00649     if ( NULL == (newIm = cpl_image_new(n_columns , n_rows,CPL_TYPE_FLOAT)) )
00650     {
00651         sinfo_msg_error ("could not allocate new image!") ;
00652         return NULL ;
00653     }
00654     podata=cpl_image_get_data_float(newIm);
00655 
00656     /* make the parabola symmetric to the image */
00657     offset = (float)(n_rows - 1) / 2. ; 
00658 
00659     /* go through the rows */
00660     for ( col = 0 ; col < n_columns ; col++ )
00661     {
00662         /* go through the columns */
00663         for ( row = 0 ; row < n_rows ; row++ )
00664         {
00665             lambda = 0. ;
00666             row_index = (float)row - offset ;
00667             for ( i = 0 ; i < n_acoefs ; i++ )
00668             {
00669                 lambda += acoefs[i][col] * pow(row_index, i) ;
00670             }
00671             podata[col+row*n_columns] = lambda ;
00672         }
00673     }
00674     return newIm ;
00675 }
00676 
00677 
00724 cpl_image * sinfo_new_wave_cal( cpl_image   * image,
00725                     FitParams ** par ,
00726                     float     ** abuf,
00727                     int          n_slitlets,
00728                     int       ** row_clean,
00729                     float     ** wavelength_clean,
00730                     int        * n_found_lines,
00731                     float        dispersion,
00732                     int          halfWidth,
00733                     float        minAmplitude,
00734                     float        max_residual,
00735                     float        fwhm,
00736                     int          n_a_fitcoefs,
00737                     int          n_b_fitcoefs,
00738                     float        sigmaFactor,
00739                     float        pixel_dist,
00740                     float        pixel_tolerance )
00741 
00742 {
00743     int          i=0, j=0, k=0 ;
00744     int          n_fit=0 ;
00745     int          n_reject=0 ;
00746     float     *  acoefs=NULL ;
00747     float     *  dacoefs=NULL ;
00748     float     ** dabuf=NULL ;
00749     float        chisq_poly=0 ;
00750     float     *  chisq_cross=NULL ;
00751     int          zeroind=0 ;
00752     int          crossInd=0 ;
00753     Bcoeffs   *  bco=NULL ;
00754     cpl_image  *  wavemap=NULL ;
00755     int ilx=0;
00756     int ily=0;
00757     float* pidata=NULL;
00758 
00759 
00760     if (  NULL == image )
00761     {
00762         sinfo_msg_error("no image given") ;
00763         return NULL ;
00764     }
00765     check_nomsg(ilx=cpl_image_get_size_x(image));
00766     check_nomsg(ily=cpl_image_get_size_y(image));
00767     check_nomsg(pidata=cpl_image_get_data_float(image));
00768 
00769     if ( par == NULL )
00770     {
00771         sinfo_msg_error("no fit parameter data structure given") ;
00772         return NULL ;
00773     }
00774     if ( abuf == NULL )
00775     {
00776         sinfo_msg_error("no buffer for fit coefficients given") ;
00777         return NULL ;
00778     }
00779     if ( n_slitlets <= 0 )
00780     {
00781         sinfo_msg_error("impossible number of slitlets given") ;
00782         return NULL ;
00783     }
00784     if ( row_clean == NULL )
00785     {
00786         sinfo_msg_error("no row_clean array given") ;
00787         return NULL ;
00788     }
00789     if ( wavelength_clean == NULL )
00790     {
00791         sinfo_msg_error("no wavelength_clean array given") ;
00792         return NULL ;
00793     }
00794 
00795     if ( dispersion == 0. )
00796     {
00797         sinfo_msg_error("impossible dispersion given") ;
00798         return NULL ;
00799     }
00800 
00801     if ( halfWidth <= 0 || halfWidth > ily/2 )
00802     {
00803         sinfo_msg_error("impossible half width of the fitting box given") ;
00804         return NULL ;
00805     }
00806     if ( minAmplitude < 1. )
00807     {
00808         sinfo_msg_error("impossible minimal amplitude") ;
00809         return NULL ;
00810     }
00811 
00812     if ( max_residual <= 0. || max_residual > 1. )
00813     {
00814         sinfo_msg_error("impossible max_residual given") ;
00815         return NULL ;
00816     }
00817     if ( fwhm <= 0. || fwhm > 10. )
00818     {
00819         sinfo_msg_error("impossible fwhm given") ;
00820         return NULL ;
00821     }
00822 
00823     if ( n_a_fitcoefs <= 0 || n_a_fitcoefs > 9 )
00824     {
00825         sinfo_msg_error("unrealistic n_a_fitcoefs given") ;
00826         return NULL ;
00827     }
00828 
00829     if ( n_b_fitcoefs <= 0 || n_b_fitcoefs > 9 )
00830     {
00831         sinfo_msg_error("unrealistic n_b_fitcoefs given") ;
00832         return NULL ;
00833     }
00834     if ( sigmaFactor <= 0. )
00835     {
00836         sinfo_msg_error("impossible sigmaFactor given") ;
00837         return NULL ;
00838     }
00839 
00840     /* initialize the variables */
00841     n_reject = 0 ;
00842     n_fit = 0 ;
00843 
00844 
00845     /* fit each found line by using a Gaussian function and determine 
00846        the exact position */
00847     if ( 0 > (n_fit = sinfo_new_fit_lines( image , par, fwhm, n_found_lines, 
00848                                      row_clean, wavelength_clean,
00849                                      halfWidth, minAmplitude )) )
00850     {
00851         sinfo_msg_error("cannot fit the lines, error code of "
00852                         "sinfo_fitLines: %d", n_fit) ;
00853         return NULL ;
00854     }
00855 
00856     /* first check for faked lines like bad pixels */
00857     if ( -1 == sinfo_new_check_for_fake_lines (par, dispersion, 
00858                                                wavelength_clean, 
00859                                          row_clean, n_found_lines,
00860                                          ilx, pixel_tolerance) )
00861     {
00862         sinfo_msg_error("cannot fit the lines, error code of "
00863                         "sinfo_fitLines: %d", n_fit) ;
00864         return NULL ;
00865     }
00866 
00867     /* allocate memory */
00868     if (NULL == (acoefs = (float*) cpl_calloc(n_a_fitcoefs, sizeof(float))) ||
00869         NULL == (dacoefs = (float*) cpl_calloc(n_a_fitcoefs, sizeof(float))) ||
00870         NULL == (dabuf = (float**) cpl_calloc(n_a_fitcoefs, sizeof(float*))) ||
00871         NULL == (chisq_cross = (float*) cpl_calloc(n_slitlets, sizeof(float))))
00872     {
00873         sinfo_msg_error("cannot allocate memory\n") ;
00874         return NULL ;
00875     }
00876     for ( i = 0 ; i < n_a_fitcoefs ; i++ )
00877     {
00878         if (  NULL == (dabuf[i] = (float*) cpl_calloc(ilx, sizeof(float))) )
00879         {
00880             sinfo_msg_error("cannot allocate memory") ;
00881             sinfo_free_float (&acoefs ) ;
00882             sinfo_free_float ( &dacoefs ) ;
00883             sinfo_free_float ( &chisq_cross ) ;
00884             sinfo_free_float_array(&dabuf,n_a_fitcoefs) ;
00885             return NULL ;
00886         }
00887     }
00888 
00889 
00890     /* fit wavelengths to the corresponding found positions for each column */
00891     k = 0 ;
00892     for ( i = 0 ; i < ilx ; i++ )
00893     {
00894         zeroind = 0 ;
00895         if ( FLT_MAX == (chisq_poly = sinfo_new_polyfit( par, i, 
00896                                                          n_found_lines[i], 
00897                                                    ily, dispersion,
00898                                                    max_residual, acoefs, 
00899                                                    dacoefs, &n_reject, 
00900                                                    n_a_fitcoefs)) )
00901         {
00902       /*
00903             sinfo_msg_warning ("error in sinfo_polyfit in column: %d\n", i) ;
00904       */
00905             for ( j = 0 ; j < n_a_fitcoefs ; j++ )
00906             {
00907                 acoefs[j] = ZERO ;
00908                 dacoefs[j] = ZERO ;
00909             }
00910         }
00911 
00912         for ( j = 0 ; j < n_a_fitcoefs ; j++ )
00913         {
00914 
00915             if ( acoefs[0] <= 0. || acoefs[1] ==0. ||
00916                  dacoefs[j] == 0. || isnan(acoefs[j]) )
00917             {
00918                 zeroind = 1 ;
00919             }
00920         }
00921         for ( j = 0 ; j < n_a_fitcoefs ; j++ )
00922         {
00923             if ( zeroind == 0 )
00924             {
00925                 abuf[j][i]  = acoefs[j] ;
00926                 dabuf[j][i] = dacoefs[j] ;
00927             }
00928             else
00929             {
00930                 abuf[j][i]  = ZERO ;
00931                 dabuf[j][i] = ZERO ;
00932             }
00933         }
00934     }
00935  
00936     /* allocate memory for the fitting coefficients */
00937     if ( NULL == ( bco = sinfo_new_b_coeffs( n_slitlets, 
00938                                              n_a_fitcoefs, n_b_fitcoefs)) )
00939     {
00940         sinfo_msg_error ("cannot allocate memory for the bcoeffs") ;
00941         sinfo_free_float_array(&dabuf,n_a_fitcoefs) ;
00942         sinfo_free_float (&acoefs ) ;
00943         sinfo_free_float (&dacoefs ) ;
00944         sinfo_free_float (&chisq_cross ) ;
00945         return NULL ;
00946     }
00947 
00948     /* fit each acoefs across the slitlets to smooth the result */
00949     if ( -1 == ( crossInd = sinfo_new_coeffs_cross_slit_fit( ilx, 
00950                                                 abuf, 
00951                                                 dabuf,
00952                                                 bco, 
00953                                                 sigmaFactor, 
00954                                                 dispersion, 
00955                                                 pixel_dist, 
00956                                                 chisq_cross )) )
00957     {
00958         sinfo_msg_error ("cannot carry out the fitting of "
00959                          "coefficients across the columns") ;
00960         sinfo_free_float_array(&dabuf,n_a_fitcoefs) ;
00961         sinfo_free_float (&acoefs ) ;
00962         sinfo_free_float (&dacoefs ) ;
00963         sinfo_free_float (&chisq_cross ) ;
00964         return NULL ;
00965     }
00966   
00967 
00968     if ( NULL == (wavemap = sinfo_new_wave_map_slit (abuf, n_a_fitcoefs, 
00969                                                      ily, ilx)) )
00970     {
00971         sinfo_msg_error ("cannot carry out wavemap creation") ;
00972         sinfo_free_float_array(&dabuf,n_a_fitcoefs) ;
00973         sinfo_free_float (&acoefs ) ;
00974         sinfo_free_float (&dacoefs ) ;
00975         sinfo_free_float (&chisq_cross ) ;
00976         sinfo_new_destroy_b_coeffs(bco) ;
00977         return NULL ;
00978     }
00979 
00980     /* free all allocated memory */
00981     sinfo_free_float_array(&dabuf,n_a_fitcoefs) ;
00982     sinfo_free_float (&acoefs ) ;
00983     sinfo_free_float (&dacoefs ) ;
00984     sinfo_free_float (&chisq_cross ) ;
00985     sinfo_new_destroy_b_coeffs(bco) ;
00986 
00987     return wavemap ;
00988  cleanup:
00989     sinfo_free_float (&acoefs ) ;
00990     sinfo_free_float ( &dacoefs ) ;
00991     sinfo_free_float ( &chisq_cross ) ;
00992     sinfo_free_float_array(&dabuf,n_a_fitcoefs) ;
00993     sinfo_new_destroy_b_coeffs(bco) ;
00994     return NULL;
00995 }
00996 
00997 
00998 
01021 int sinfo_new_check_for_fake_lines ( FitParams ** par,
01022                         float        dispersion,
01023             float     ** wavelength_clean,
01024             int       ** row_clean,
01025             int        * n_found_lines,
01026             int          n_columns,
01027             float        pixel_tolerance )
01028 {
01029     int i,  k ;
01030     int col ;
01031     int found ;
01032     float row ;
01033     float * beginWave ;
01034     float firstWave ;
01035 
01036     if ( par == NULL )
01037     {
01038         sinfo_msg_error("no fit parameter data structure given") ;
01039         return -1 ;
01040     }
01041     if ( dispersion == 0. )
01042     {
01043         sinfo_msg_error("dispersion zero given!") ;
01044         return -1 ;
01045     }
01046     if ( wavelength_clean == NULL )
01047     {
01048         sinfo_msg_error("no wavelength array given!") ;
01049         return -1 ;
01050     }
01051     if ( row_clean == NULL )
01052     {
01053         sinfo_msg_error("no row array given!") ;
01054         return -1 ;
01055     }
01056     if ( n_found_lines == NULL )
01057     {
01058         sinfo_msg_error("no number of lines given!") ;
01059         return -1 ;
01060     }
01061     if ( n_columns < 200 )
01062     {
01063         sinfo_msg_error("wrong number of columns given!") ;
01064         return -1 ;
01065     }
01066 
01067     /* first determine the estimated beginning wavelength of the first row */
01068     for ( col = 0 ; col < n_columns ; col++ )
01069     {
01070         if ( n_found_lines[col] == 0 )
01071         {
01072         continue ;
01073         } 
01074         if ( NULL == (beginWave = (float*) cpl_calloc( n_found_lines[col], 
01075                                                        sizeof(float) ) ) )
01076         {
01077             sinfo_msg_error("could not allocate memory!") ;
01078             return -1 ;
01079     }
01080     for ( k = 0 ; k < n_found_lines[col] ; k++ ) 
01081     {
01082         beginWave[k] = wavelength_clean[col][k] - 
01083                            (float)row_clean[col][k] * dispersion ;
01084         }
01085     /* determine the clean mean of the estimated 
01086            beginning wavelengths of one column */
01087     if ( FLT_MAX == (firstWave = sinfo_new_clean_mean (beginWave, 
01088                                                            n_found_lines[col], 
01089                                                            10., 10.) ) )
01090     {
01091             sinfo_msg_error("clean mean did not work!") ;
01092             return -1 ;
01093     }
01094 
01095         cpl_free (beginWave) ;
01096         /* go through the lines in that column and select the 
01097            correct FitParam structure */
01098         for ( k = 0 ; k < n_found_lines[col] ; k++ ) 
01099         {    
01100         /* compute the estimated line position */
01101         row = ( wavelength_clean[col][k] - firstWave ) / dispersion ;
01102 
01103             /* go through all fit parameters and find the corresponding one */
01104         found = -1 ;
01105             for ( i = 0 ; i < (par[0] -> n_params) ; i ++ )
01106             {    
01107             /* find the given column and go through the 
01108                    lines in that column */
01109         if ( (par[i] -> column == col) && (par[i] -> line == k) && 
01110              (par[i] -> wavelength == wavelength_clean[col][k]) )
01111         {
01112                 found = i ;
01113             break ;
01114                 }
01115             }
01116         if ( found != -1 )
01117         {
01118             /* set fit params to zero where the fitted row 
01119                    position and the estimated 
01120             row positions are outside the tolerance */
01121                 if ( fabs(row - par[found]->fit_par[2]) > pixel_tolerance ) 
01122             {
01123                 sinfo_msg_warning("found bad line in col: "
01124                                       "%d line: %d in row: %f difference: %f", 
01125                                       col, k, par[found]->fit_par[2],
01126                                       row - par[found]->fit_par[2])  ;
01127                 par[found]->fit_par[2] = 0. ;
01128                 }
01129             }
01130         else
01131         {
01132         sinfo_msg_warning("fit parameter of col %d and line "
01133                                   "no %d not found!\n", col, k ) ;
01134         }
01135         }
01136     }
01137 
01138     return 0 ;
01139 }
01140 
01159 cpl_image * 
01160 sinfo_new_create_shifted_slit_wavemap ( cpl_image * lineIm,
01161                               float    ** coeffs,
01162                           int      n_fitcoeffs,
01163                                       float  * wavelength,
01164                                       float  * intensity,
01165                                       int      n_lines,
01166                                       int      magFactor )
01167 {
01168     cpl_image * wavemap ;
01169     float* emline=NULL ;
01170     float* spec=NULL ;
01171     float* wave=NULL ;
01172     double* a=NULL ;
01173     float* par=NULL ;
01174     float* derv_par=NULL ;
01175     double* z=NULL ;
01176 
01177     double  * result ;
01178     float * filter_spec ;
01179     float centreval ;
01180     float centrepix ;
01181     float cenpos, cenpix ;
01182     float pixvalue ;
01183     float wavelag ;
01184     float angst ;
01185     float a_initial ;
01186     int        numpar, its ;
01187     int        * mpar ;
01188     float      tol, lab ;
01189     float      * xdat, * wdat ;
01190     Vector     * peak;
01191     int   iters, xdim, ndat ;
01192     int   row , col ;
01193     int   i, j, k/*, l, m*/ ;
01194     int   sign, found, line, width ;
01195     int var, maxlag, cmin, cmax ;
01196     gsl_poly_complex_workspace * w ;
01197     double xcorr_max ;
01198     int delta ;
01199     int ilx=0;
01200     int ily=0;
01201     int olx=0;
01202     int oly=0;
01203     float* pidata=NULL;
01204     float* podata=NULL;
01205 
01206 
01207     if ( lineIm == NULL )
01208     {
01209         sinfo_msg_error ("no input image given!") ;
01210         return NULL ;
01211     }
01212     ilx=cpl_image_get_size_x(lineIm);
01213     ily=cpl_image_get_size_y(lineIm);
01214     pidata=cpl_image_get_data_float(lineIm);
01215 
01216     if ( coeffs == NULL )
01217     {
01218         sinfo_msg_error ("no coefficient sinfo_matrix given!") ;
01219         return NULL ;
01220     }
01221     if ( n_fitcoeffs < 2 )
01222     {
01223         sinfo_msg_error ("wrong number of polynomial coefficients given!") ;
01224         return NULL ;
01225     }
01226     if ( wavelength == NULL || intensity == NULL )
01227     {
01228         sinfo_msg_error ("no input image given!") ;
01229         return NULL ;
01230     }
01231     if ( n_lines < 1 )
01232     {
01233         sinfo_msg_error ("no input image given!") ;
01234         return NULL ;
01235     }
01236 
01237     /* find out if Angstroem or microns are used */
01238     if ( wavelength[0] > 10000. )
01239     {
01240         /* Angstroem */
01241         angst = 10000. ;
01242     }
01243     else if ( wavelength[0] > 1000. && wavelength[0] < 10000. )
01244     {
01245         /* nanometers */
01246         angst = 1000. ;
01247     }
01248     else
01249     {
01250         /* microns */
01251         angst = 1. ;
01252     }
01253 
01254     /* allocate memory */
01255     if ( NULL == (wavemap = cpl_image_new ( ilx, ily, CPL_TYPE_FLOAT)) )
01256     {
01257         sinfo_msg_error ("could not allocate memory!") ;
01258         return NULL ;
01259     }
01260     olx=cpl_image_get_size_x(wavemap);
01261     oly=cpl_image_get_size_y(wavemap);
01262     podata=cpl_image_get_data_float(wavemap);
01263 
01264     var = (magFactor-1)*(magFactor-1) ;
01265 
01266 
01267  
01268     emline=cpl_calloc(ily,sizeof(float)) ;
01269     spec=cpl_calloc(ily,sizeof(float)) ;
01270     wave=cpl_calloc(n_lines,sizeof(float)) ;
01271     par=cpl_calloc(MAXPAR,sizeof(float)) ;
01272     derv_par=cpl_calloc(MAXPAR,sizeof(float)) ;
01273 
01274     a=cpl_calloc(n_fitcoeffs,sizeof(double)) ;
01275     z=cpl_calloc(2*(n_fitcoeffs - 1),sizeof(double)) ;
01276 
01277    
01278     /* first store each spectrum in a buffer */
01279     for ( col = 0 ; col < ilx ; col++ )
01280     {
01281         /* initialize the emline array for each column */
01282         for ( i = 0 ; i < ily ; i++ )
01283         {
01284             emline[i] = 0. ;
01285         }
01286         /* determine the coefficients by using the given bcoefs */
01287         for ( i = 0 ; i < n_fitcoeffs ; i++ )
01288         {
01289             /* initialize coefficients and solution */
01290             if (i < n_fitcoeffs-1)
01291             {
01292                 z[2*i] = 0. ;
01293                 z[2*i+1] = 0. ;
01294             }
01295             a[i] = coeffs[i][col] ;
01296         }
01297          
01298         a_initial = coeffs[0][col] ;
01299         /* go through the lines and generate an artificial spectrum */
01300         for ( line = 0 ; line < n_lines ; line++ )
01301         {
01302             /* go from Angstroem to micron */
01303             wave[line] = wavelength[line]/angst ;
01304 
01305             /* -----------------------------------------------------------
01306              * solve the polynomial for the exact offset of the line that means
01307              * find the root of the polynomial of order n_fitcoefs - 1
01308              */
01309             a[0] = a_initial - wave[line] ;
01310 
01311             if(NULL==(w=sinfo_gsl_poly_complex_workspace_alloc(n_fitcoeffs))) 
01312             {
01313                 sinfo_msg_error("could not allocate complex workspace!") ;
01314                 cpl_image_delete(wavemap) ;
01315                 return NULL ;
01316             }
01317             if (-1 == sinfo_gsl_poly_complex_solve(a, n_fitcoeffs, w, z)) 
01318             {
01319                 sinfo_msg_error("sinfo_gsl_poly_complex_solve did not work!") ;
01320                 cpl_image_delete(wavemap) ;
01321                 return NULL ;
01322             }
01323             sinfo_gsl_poly_complex_workspace_free(w) ;           
01324 
01325             j = 0 ;
01326             found = -1 ;
01327             for ( i = 0 ; i < n_fitcoeffs - 1 ; i++ )
01328             {
01329                 /* test for appropriate solution */
01330                 if( (z[2*i] > (-1.)*(float) ily/2. &&
01331                      z[2*i] < (float)ily/2.) && z[2*i+1] == 0. )
01332                 {
01333                     found = 2*i ;
01334                     j ++ ;
01335                 }
01336                 else
01337                 {
01338                     continue ;
01339                 }
01340             }
01341             if ( j == 0 )
01342             {
01343                 sinfo_msg_warning("no offset solution found for line %d in "
01344                                   "column %d", line, col) ;
01345                 continue ;
01346             }
01347             else if ( j == 1 )
01348             {
01349                 cenpos = z[found] + (float) ily /2. ;
01350             }
01351             else
01352             {
01353                 sinfo_msg_warning("two or more offset solutions found for "
01354                                   "line %d in column %d", line, col) ;
01355                 continue ;
01356             }
01357 
01358             /*-----------------------------------------------------------------
01359              * magnify image by the given factor add an additional offset
01360              */
01361             cenpix = cenpos ;
01362 
01363             /* determine max and min pixel limits over 
01364                which line should be convolved */
01365             cmin = (sinfo_new_nint(cenpix) - (var-1)) > 0 ? 
01366                     sinfo_new_nint(cenpix) - (var-1) : 0 ;
01367             cmax = (sinfo_new_nint(cenpix) + (var-1)) < ily ?
01368                     sinfo_new_nint(cenpix) + (var-1) : ily ;
01369 
01370             /* convolve neon lines with Gaussian function */
01371             for ( j = cmin ; j < cmax ; j++ )
01372             {
01373                 emline[j] += intensity[line] * 
01374                      exp((double)(-0.5*(j-cenpix)*(j-cenpix))/(double)var) ;
01375             }
01376         }
01377 
01378         /*-------------------------------------------------------------------
01379          * for each column, map the image data points onto an magFactor times 
01380            bigger element grid for FFT in the cross sinfo_correlation, first 
01381            initialize the two helping arrays for each new column.
01382          */
01383         for ( k = 0 ; k < ily ; k++ )
01384         {
01385             spec[k] = 0. ;
01386         }
01387 
01388         /* now take the image data points of the column and put 
01389            them into the spec array */
01390         for ( row = 0 ; row < ily ; row++ ) /* go through the column */
01391         {
01392             /* set bad pixels or negative values to zero */
01393             if (!isnan(pidata[col + row*ilx]) &&
01394                 (pidata[col + row*ilx] > 0.))
01395             {
01396                 spec[row] = pidata[col + row*ilx] ;
01397             }
01398             else
01399             {
01400                 spec[row] = 0. ;
01401             }
01402         }
01403         /* convolve the spectrum by Gaussian */
01404         filter_spec = sinfo_function1d_filter_lowpass(spec, ily, 
01405                                                       LOW_PASS_GAUSSIAN, 
01406                                                       magFactor) ; 
01407 
01408         /* now call the cross sinfo_correlation routine */
01409         result = sinfo_new_xcorrel( filter_spec, ily, emline, ily,
01410                           ily/2, &delta, &maxlag, &xcorr_max) ;
01411 
01412         if ( xcorr_max <= 0. )
01413         {
01414             sinfo_msg_warning("no positive cross correlation sum , "
01415                               "col %d set to ZERO \n", col) ;
01416             for ( row = 0 ; row < ily ; row++ )
01417             {
01418                 podata[col + row*ilx] = ZERO ;
01419             }
01420             sinfo_function1d_del(filter_spec) ;
01421             cpl_free(result) ;
01422             continue ;
01423         }
01424 
01425        /* in this section, we fit the correlation function with a gauss, 
01426           and find its peak, thus getting subpixel-accuracy */
01427 
01428         i = maxlag; j = i+1;
01429         while (result[j] < result[i])
01430         {
01431             i++; j++;
01432         }
01433         i = maxlag; k = i-1;
01434         while (result[k] < result[i])
01435         {
01436             i--; k--;
01437         }
01438         width = j-k+1;
01439         /* allocate memory for the spectral sinfo_vector */
01440         if ( NULL == (peak = sinfo_new_vector (width)) )
01441         {
01442             sinfo_msg_error ("cannot allocate new Vector \n") ;
01443             sinfo_function1d_del(filter_spec) ;
01444             cpl_free(result) ;
01445             return NULL ;
01446         }
01447 
01448 
01449         /* allocate memory */
01450         xdat = (float *) cpl_calloc( peak -> n_elements, sizeof (float) ) ;
01451         wdat = (float *) cpl_calloc( peak -> n_elements, sizeof (float) ) ;
01452         mpar = (int *)   cpl_calloc( MAXPAR, sizeof (int) ) ;
01453 
01454         /* determine the values of the spectral sinfo_vector given as input */
01455         /* go through the chosen column */
01456 
01457         for ( i = 0 ; i < width ; i++ )
01458         {
01459             peak -> data[i] = result[k+i]/xcorr_max * 100. ;
01460             xdat[i] = i;
01461             wdat[i] = 1.0;
01462         }
01463 
01464         /* set initial values for the fitting routine */
01465         xdim     = XDIM;
01466         ndat     = peak -> n_elements ;
01467         numpar   = MAXPAR ;
01468         tol      = TOL ;
01469         lab      = LAB ;
01470         its      = ITS ;
01471         par[1] = width/2.0 ;
01472         par[2] = (float) (maxlag - k) ;
01473         par[3] = (peak -> data[0] + peak -> data[peak->n_elements - 1]) / 2.0 ;
01474         par[0]  = result[maxlag]/xcorr_max * 100. - (par[3]) ;
01475 
01476         for ( i = 0 ; i < MAXPAR ; i++ )
01477         {
01478             derv_par[i] = 0.0 ;
01479             mpar[i] = 1 ;
01480         }
01481 
01482         /* finally, do the least square fit using a sinfo_gaussian */
01483         if ( 0 > ( iters = sinfo_new_lsqfit_c( xdat, &xdim, 
01484                                                peak -> data, wdat, 
01485                                                &ndat, par, derv_par, mpar,
01486                                                &numpar, &tol, &its, &lab )) )
01487         {
01488             sinfo_msg_warning ("sinfo_new_lsqfit_c: least squares fit failed "
01489                                "in col: %d, error no.: %d", col, iters) ;
01490             sinfo_new_destroy_vector ( peak ) ;
01491             cpl_free ( xdat ) ;
01492             cpl_free ( wdat ) ;
01493             cpl_free ( mpar ) ;
01494             sinfo_function1d_del(filter_spec) ;
01495             cpl_free(result) ;
01496             continue ;
01497         }
01498 
01499         sinfo_new_destroy_vector ( peak ) ;
01500         cpl_free (xdat) ;
01501         cpl_free (wdat) ;
01502         cpl_free (mpar) ;
01503         sinfo_function1d_del(filter_spec) ;
01504         cpl_free(result) ;
01505 
01506         wavelag =((float)ily/2 - (float)k - par[2]) ;
01507 
01508         if ( fabs(wavelag) > (float)ily/20. )
01509         {
01510             sinfo_msg_warning("wavelag very big , col %d set to ZERO", col) ;
01511             for ( row = 0 ; row < ily ; row++ )
01512             {
01513                 podata[col + row*ilx] = ZERO ;
01514             }
01515             continue ;
01516         }
01517 
01518         /*--------------------------------------------------------------------
01519          * determine new zero order coefficient centreval, of which the 
01520          * formula is determined by setting equal a polynomial shifted by 
01521          * wavelag with the same higher order coefficients and set the new 
01522          * zero order coefficient to
01523          * get both sides of the equation approximately equal.
01524          */
01525         centreval = a_initial ;
01526         for ( i = 1 ; i < n_fitcoeffs ; i++ )
01527         {
01528             if ( i%2 == 0 ) 
01529             {
01530                 sign = -1 ;
01531             }
01532             else
01533             {
01534                 sign = 1 ;
01535             }
01536             centreval += (float)sign * coeffs[i][col]*pow(wavelag, i) ;
01537         }
01538 
01539         /* prepare to write out wavelength as pixel values */
01540         for ( row = 0 ; row < oly ; row++ )
01541         {
01542             centrepix = (float)row - ((float)oly - 1.)/2. ;
01543             pixvalue = 0. ;
01544             for ( i = 1 ; i < n_fitcoeffs ; i++ )
01545             {
01546                 pixvalue += coeffs[i][col]*pow(centrepix, i) ;
01547             }
01548             podata[col+row*olx] = centreval + pixvalue ;
01549         }
01550     }
01551 
01552 
01553     cpl_free(emline) ;
01554     cpl_free(spec) ;
01555     cpl_free(wave) ;
01556     cpl_free(par) ;
01557     cpl_free(derv_par) ;
01558 
01559     cpl_free(a) ;
01560     cpl_free(z) ;
01561 
01562 
01563 
01564     return wavemap ;
01565 }
01566 
01591 cpl_image * sinfo_new_create_shifted_slit_wavemap2 ( cpl_image * lineIm,
01592                                       float    ** coeffs,
01593                                       int      n_fitcoeffs,
01594                                       float  * wavelength,
01595                                       float  * intensity,
01596                                       int      n_lines,
01597                                       int      magFactor,
01598                                       float    dispersion,
01599                                       float    pixel_dist )
01600 {
01601     cpl_image * wavemap ;
01602     double * result ;
01603     float * filter_spec ;
01604     float centreval ;
01605     float centrepix ;
01606     float cenpos, cenpix ;
01607     float pixvalue ;
01608     float wavelag ;
01609     /*float maxres ;*/
01610     float angst ;
01611     /*float temp ;*/
01612     float a_initial ;
01613     int        numpar, its ;
01614     int        * mpar ;
01615     float      tol, lab ;
01616     float      * xdat, * wdat ;
01617     Vector     * peak;
01618     int   iters, xdim, ndat ;
01619     int   row , col ;
01620     int   i, j, k/*, l, m*/, n ;
01621     int   sign, found, line, width ;
01622     int var, maxlag, cmin, cmax ;
01623     float offset2 ;
01624     float threshold ;
01625     int ed1, ed2 ;
01626 
01627     int edge[N_SLITLETS] ;
01628     float par[MAXPAR] ;
01629     float derv_par[MAXPAR] ;
01630 
01631     float* emline=NULL ;
01632     float* spec=NULL ;
01633     float* wave=NULL ;
01634     float* a0=NULL ;
01635     float* a0_clean=NULL ;
01636 
01637 
01638     float* sub_col_index=NULL ;
01639     float* sub_acoefs=NULL;
01640     float* sub_dacoefs=NULL ;
01641     double* z=NULL ;
01642     double* a=NULL ;
01643 
01644     float** bcoef=NULL ;
01645     float* wcoefs=NULL ;
01646 
01647 
01648     int ns, nc ;
01649     float * acoefsclean ;
01650     float col_index;
01651 
01652     float ** ucoefs, **vcoefs, **covar ;
01653     double sum, sumq, mean ;
01654     double sigma ;
01655     double cliphi, cliplo ;
01656     float chisq ;
01657     int num, ndata ;
01658     gsl_poly_complex_workspace * w ;
01659     double xcorr_max ;
01660     int delta ;
01661     int ilx=0;
01662     int ily=0;
01663     int olx=0;
01664     int oly=0;
01665     float* pidata=NULL;
01666     float* podata=NULL;
01667 
01668 
01669     if ( lineIm == NULL )
01670     {
01671         sinfo_msg_error (" no input image given!\n") ;
01672         return NULL ;
01673     }
01674 
01675     ilx=cpl_image_get_size_x(lineIm);
01676     ily=cpl_image_get_size_y(lineIm);
01677     pidata=cpl_image_get_data_float(lineIm);
01678 
01679     if ( coeffs == NULL )
01680     {
01681         sinfo_msg_error (" no coefficient sinfo_matrix given!\n") ;
01682         return NULL ;
01683     }
01684     if ( n_fitcoeffs < 2 )
01685     {
01686         sinfo_msg_error (" wrong number of polynomial coefficients given!\n") ;
01687         return NULL ;
01688     }
01689     if ( wavelength == NULL || intensity == NULL )
01690     {
01691         sinfo_msg_error (" no input image given!\n") ;
01692         return NULL ;
01693     }
01694     if ( n_lines < 1 || magFactor < 1 )
01695     {
01696         sinfo_msg_error (" no input image given!\n") ;
01697         return NULL ;
01698     }
01699     var    = (magFactor - 1)*(magFactor - 1) ;
01700     /* find out if Angstroem or microns are used */
01701     if ( wavelength[0] > 10000. )
01702     {
01703         /* Angstroem */
01704         angst = 10000. ;
01705     }
01706     else if ( wavelength[0] > 1000. && wavelength[0] < 10000. )
01707     {
01708         /* nanometers */
01709         angst = 1000. ;
01710     }
01711     else
01712     {
01713         /* microns */
01714         angst = 1. ;
01715     }
01716 
01717     bcoef=sinfo_new_2Dfloatarray(N_SLITLETS,n_fitcoeffs) ;
01718     wcoefs=cpl_calloc(n_fitcoeffs,sizeof(float)) ;
01719 
01720     emline=cpl_calloc(ily,sizeof(float)) ;
01721     spec=cpl_calloc(ily,sizeof(float)) ;
01722     wave=cpl_calloc(n_lines,sizeof(float)) ;
01723     a0=cpl_calloc(ilx,sizeof(float)) ;
01724     a0_clean=cpl_calloc(ilx,sizeof(float)) ;
01725 
01726 
01727 
01728     sub_col_index=cpl_calloc(ilx,sizeof(float)) ;
01729     sub_acoefs=cpl_calloc(ilx,sizeof(float));
01730     sub_dacoefs=cpl_calloc(ilx,sizeof(float)) ;
01731 
01732     a=cpl_calloc(n_fitcoeffs,sizeof(double)) ;
01733     z=cpl_calloc(2*(n_fitcoeffs - 1),sizeof(double)) ;
01734 
01735     /* find the slitlet edges from the a0 coefficient */
01736     n = 0 ;
01737     threshold = pixel_dist * fabs(dispersion) ;
01738     for ( i = PIXEL ; i < ilx - PIXEL ; )
01739     {
01740         if (fabs(coeffs[0][i+1] - coeffs[0][i]) >= threshold )
01741         {
01742             edge[n] = i+1 ;
01743             n++ ;
01744             i += PIXEL ;
01745         }
01746         i++ ;
01747     }
01748 
01749 
01750     /* allocate memory */
01751     if ( NULL == (wavemap = cpl_image_new ( ilx, ily, CPL_TYPE_FLOAT)) )
01752     {
01753         sinfo_msg_error (" could not allocate memory!\n") ;
01754         return NULL ;
01755     }
01756     olx=cpl_image_get_size_x(wavemap);
01757     oly=cpl_image_get_size_y(wavemap);
01758     podata=cpl_image_get_data_float(wavemap);
01759 
01760     /* first store each spectrum in a buffer */
01761     for ( col = 0 ; col < ilx ; col++ )
01762     {
01763         /* initialize the emline array for each column */
01764         for ( i = 0 ; i < ily ; i++ )
01765         {
01766             emline[i] = 0. ;
01767         }
01768         /* determine the coefficients by using the given bcoefs */
01769         for ( i = 0 ; i < n_fitcoeffs ; i++ )
01770         {
01771             /* initialize coefficients and solution */
01772             if (i < n_fitcoeffs-1)
01773             {
01774                 z[2*i] = 0. ;
01775                 z[2*i+1] = 0. ;
01776             }
01777             a[i] = coeffs[i][col] ;
01778         }
01779          
01780         a_initial = coeffs[0][col] ;
01781         /* go through the lines and generate an artificial spectrum */
01782         for ( line = 0 ; line < n_lines ; line++ )
01783         {
01784             /* go from Angstroem to micron */
01785             wave[line] = wavelength[line]/angst ;
01786 
01787             /* ------------------------------------------------------------
01788              * solve the polynomial for the exact offset of the line that means
01789              * find the root of the polynomial of order n_fitcoefs - 1
01790              */
01791             a[0] = a_initial - wave[line] ;
01792 
01793             if (NULL==(w=sinfo_gsl_poly_complex_workspace_alloc(n_fitcoeffs))) 
01794             {
01795                 sinfo_msg_error(" could not allocate complex workspace!") ;
01796                 cpl_image_delete(wavemap) ;
01797                 return NULL ;
01798             }
01799             if (-1 == sinfo_gsl_poly_complex_solve(a, n_fitcoeffs, w, z)) 
01800             {
01801                 sinfo_msg_error(" sinfo_gsl_poly_complex_solve did not work!") ;
01802                 cpl_image_delete(wavemap) ;
01803                 return NULL ;
01804             }
01805             sinfo_gsl_poly_complex_workspace_free(w) ;           
01806 
01807             j = 0 ;
01808             found = -1 ;
01809             for ( i = 0 ; i < n_fitcoeffs - 1 ; i++ )
01810             {
01811                 /* test for appropriate solution */
01812                 if( (z[2*i] > (-1.)*(float) ily/2. &&
01813                      z[2*i] < (float)ily/2.) && z[2*i+1] == 0. )
01814                 {
01815                     found = 2*i ;
01816                     j ++ ;
01817                 }
01818                 else
01819                 {
01820                     continue ;
01821                 }
01822             }
01823             if ( j == 0 )
01824             {
01825                 sinfo_msg_warning(" no offset solution found for "
01826                                   "line %d in column %d\n", line, col) ;
01827                 continue ;
01828             }
01829             else if ( j == 1 )
01830             {
01831                 cenpos = z[found] + (float) ily/2. ;
01832             }
01833             else
01834             {
01835                 sinfo_msg_warning(" two or more offset solutions found "
01836                                   "for line %d in column %d", line, col) ;
01837                 continue ;
01838             }
01839 
01840             /*----------------------------------------------------------------
01841              * magnify image by the given factor add an additional offset
01842              */
01843             cenpix = cenpos ;
01844 
01845             /* determine max and min pixel limits over which line should 
01846                be convolved */
01847             cmin = (sinfo_new_nint(cenpix) - (var-1)) > 0 ? 
01848                     sinfo_new_nint(cenpix) - (var-1) : 0 ;
01849             cmax = (sinfo_new_nint(cenpix) + (var-1)) < ily ?
01850                     sinfo_new_nint(cenpix) + (var-1)  : ily ;
01851 
01852             /* convolve neon lines with Gaussian function */
01853             for ( j = cmin ; j < cmax ; j++ )
01854             {
01855                 emline[j] += intensity[line] * 
01856                        exp((double)(-0.5*(j-cenpix)*(j-cenpix))/(double)var) ;
01857             }
01858         }
01859 
01860         /*--------------------------------------------------------------------
01861          * for each column, map the image data points onto an magFactor times 
01862            bigger element grid for FFT  in the cross sinfo_correlation, first 
01863            initialize the two helping arrays for each new column.
01864          */
01865         for ( k = 0 ; k < ily ; k++ )
01866         {
01867             spec[k] = 0. ;
01868         }
01869 
01870         /* now take the image data points of the column and put them into 
01871            the spec array */
01872         for ( row = 0 ; row < ily ; row++ ) /* go through the column */
01873         {
01874             /* set bad pixels or negative values to zero */
01875             if (!isnan(pidata[col + row*ilx]) &&
01876                 (pidata[col + row*ilx] > 0.))
01877             {
01878                 spec[row] = pidata[col + row*ilx] ;
01879             }
01880             else
01881             {
01882                 spec[row] = 0. ;
01883             }
01884         }
01885         /* convolve the spectrum by Gaussian */
01886         filter_spec = sinfo_function1d_filter_lowpass(spec,ily, 
01887                                                       LOW_PASS_GAUSSIAN, 
01888                                                       magFactor) ; 
01889 
01890         /* now call the cross sinfo_correlation routine */
01891         result = sinfo_new_xcorrel( filter_spec, ily, emline, ily,
01892                           ily/2, &delta, &maxlag, &xcorr_max) ;
01893 
01894         if ( xcorr_max <= 0. )
01895         {
01896             sinfo_msg_warning("no positive cross sinfo_correlation "
01897                               "sum , col %d set to ZERO \n", col) ;
01898             for ( row = 0 ; row < ily ; row++ )
01899             {
01900                 podata[col + row*ilx] = ZERO ;
01901             }
01902             sinfo_function1d_del(filter_spec) ;
01903             cpl_free(result) ;
01904             continue ;
01905         }
01906 
01907        /* in this section, we fit the sinfo_correlation function with a gauss, 
01908           and find its peak, thus getting subpixel-accuracy */
01909 
01910         i = maxlag; j = i+1;
01911         while (result[j] < result[i])
01912         {
01913             i++; j++;
01914         }
01915         i = maxlag; k = i-1;
01916         while (result[k] < result[i])
01917         {
01918             i--; k--;
01919         }
01920         width = j-k+1;
01921         /* allocate memory for the spectral sinfo_vector */
01922         if ( NULL == (peak = sinfo_new_vector (width)) )
01923         {
01924             sinfo_msg_error (" cannot allocate new Vector \n") ;
01925             sinfo_function1d_del(filter_spec) ;
01926             cpl_free(result) ;
01927             return NULL ;
01928         }
01929 
01930 
01931         /* allocate memory */
01932         xdat = (float *) cpl_calloc( peak -> n_elements, sizeof (float) ) ;
01933         wdat = (float *) cpl_calloc( peak -> n_elements, sizeof (float) ) ;
01934         mpar = (int *)   cpl_calloc( MAXPAR, sizeof (int) ) ;
01935 
01936         /* determine the values of the spectral sinfo_vector given as input */
01937         /* go through the chosen column */
01938 
01939         for ( i = 0 ; i < width ; i++ )
01940         {
01941             peak -> data[i] = result[k+i]/xcorr_max * 100. ;
01942             xdat[i] = i;
01943             wdat[i] = 1.0;
01944         }
01945 
01946         /* set initial values for the fitting routine */
01947         xdim     = XDIM;
01948         ndat     = peak -> n_elements ;
01949         numpar   = MAXPAR ;
01950         tol      = TOL ;
01951         lab      = LAB ;
01952         its      = ITS ;
01953         par[1] = width/2.0 ;
01954         par[2] = (float) (maxlag - k) ;
01955         par[3] = (peak -> data[0] + peak -> data[peak->n_elements - 1]) / 2.0 ;
01956         par[0]  = result[maxlag]/xcorr_max * 100. - (par[3]) ;
01957 
01958         for ( i = 0 ; i < MAXPAR ; i++ )
01959         {
01960             derv_par[i] = 0.0 ;
01961             mpar[i] = 1 ;
01962         }
01963 
01964         /* finally, do the least square fit using a sinfo_gaussian */
01965         if ( 0 > ( iters = sinfo_new_lsqfit_c( xdat, &xdim, peak -> data, 
01966                                                wdat, &ndat, par, 
01967                                                derv_par, mpar,
01968                                                &numpar, &tol, &its, &lab )) )
01969         {
01970             sinfo_msg_warning (" sinfo_new_lsqfit_c: least squares fit "
01971                                "failed in col: %d, error no.: %d", col, iters);
01972             sinfo_new_destroy_vector ( peak ) ;
01973             cpl_free ( xdat ) ;
01974             cpl_free ( wdat ) ;
01975             cpl_free ( mpar ) ;
01976             sinfo_function1d_del(filter_spec) ;
01977             cpl_free(result) ;
01978             continue ;
01979         }
01980 
01981         sinfo_new_destroy_vector ( peak ) ;
01982         cpl_free (xdat) ;
01983         cpl_free (wdat) ;
01984         cpl_free (mpar) ;
01985         sinfo_function1d_del(filter_spec) ;
01986         cpl_free(result) ;
01987 
01988         wavelag =((float)ily/2 - (float)k - par[2]) ;
01989 
01990         if ( fabs(wavelag) > (float)ily/20. )
01991         {
01992             sinfo_msg_warning("wavelag very big , col %d set to ZERO ", col) ;
01993             for ( row = 0 ; row < ily ; row++ )
01994             {
01995                 podata[col + row*ilx] = ZERO ;
01996             }
01997             continue ;
01998         }
01999 
02000         /*--------------------------------------------------------------------
02001          * determine new zero order coefficient centreval, of which the 
02002          * formula is determined by setting equal a polynomial shifted by 
02003          * wavelag with the same higher order coefficients and set the new 
02004          * zero order coefficient to get both sides of the equation 
02005          * approximately equal.
02006          */
02007         centreval = a_initial ;
02008         for ( i = 1 ; i < n_fitcoeffs ; i++ )
02009         {
02010             if ( i%2 == 0 )
02011             {
02012                 sign = -1 ;
02013             }
02014             else
02015             {
02016                 sign = 1 ;
02017             }
02018             centreval += (float)sign * coeffs[i][col]*pow(wavelag, i) ;
02019         }
02020         a0[col] = centreval ;
02021     }
02022 
02023     /* go through the single slitlets */
02024     for ( ns = 0 ; ns < N_SLITLETS ; ns++ )
02025     {
02026         /* determine the slitlet edges */
02027         if ( ns == 0 )
02028         {
02029             ed1 = 0 ;
02030             ed2 = edge[0] ;
02031         }
02032         else if ( ns == N_SLITLETS - 1 )
02033         {
02034             ed1 = edge[N_SLITLETS - 2] ;
02035             ed2 = ilx ;
02036         }
02037         else
02038         {
02039             ed1 = edge[ns-1] ;
02040             ed2 = edge[ns] ;
02041         }
02042 
02043         nc = 0 ;
02044         for ( i = ed1 ; i < ed2 ; i++ )
02045         {
02046             if ( isnan(a0[i]) || a0[i] == 0. )
02047             {
02048                 continue ;
02049             }
02050             else
02051             {
02052                 nc++ ;
02053             }
02054         }
02055         if ( NULL == (acoefsclean = (float*) cpl_calloc(nc , sizeof(float))) )
02056         {
02057             sinfo_msg_error("could not allocate memory for acoefsclean!\n") ;
02058             return NULL ;
02059         }
02060         nc = 0 ;
02061         for ( i = ed1 ; i < ed2 ; i++ )
02062         {
02063             if ( isnan(a0[i]) || a0[i] == 0. )
02064             {
02065                 continue ;
02066             }
02067             else
02068             {
02069                 acoefsclean[nc] = a0[i] ;
02070                 nc++ ;
02071             }
02072         }
02073 
02074         /* ----------------------------------------------------------
02075          * determine the clean mean and sigma value of the coefficients,
02076          * that means reject 10 % of the extreme low and high values
02077          */
02078         sinfo_pixel_qsort(acoefsclean, nc) ;
02079         sum   = 0. ;
02080         sumq  = 0. ;
02081         mean  = 0. ;
02082         sigma = 0. ;
02083         n     = 0 ;
02084         for ( i = (int)((float)nc*LOW_REJECT) ; 
02085               i < (int)((float)nc*HIGH_REJECT) ; i++ )
02086         {
02087             sum  += (double)acoefsclean[i] ;
02088             sumq += ((double)acoefsclean[i] * (double)acoefsclean[i]) ;
02089             n ++ ;
02090         }
02091         mean          = sum/(double)n ;
02092         sigma         = sqrt( sumq/(double)n - (mean * mean) ) ;
02093         cliphi        = mean + sigma * (double)3. ;
02094         cliplo        = mean - sigma * (double)3. ;
02095         /* fit only the reasonnable values */
02096         num = 0 ;
02097         col_index = 0 ;
02098         for ( i = ed1 ; i < ed2 ; i++ )
02099         {
02100             /* take only the reasonnable coefficients */
02101             if ( !isnan(a0[i]) && (a0[i] <= cliphi) && (a0[i] >= cliplo) &&
02102                  (a0[i] != 0.) )
02103             {
02104                 sub_acoefs[num]    = a0[i] ;
02105                 sub_dacoefs[num]   = 0.0000005 ;
02106                 sub_col_index[num] = col_index ;
02107                 num ++ ;
02108             }
02109             col_index++ ;
02110         }
02111         ndata = num ;
02112         offset2 = (float)(col_index-1) / 2. ;
02113 
02114         if ( ndata < n_fitcoeffs )
02115         {
02116             sinfo_msg_error(" not enough data found in slitlet %d\
02117                     to determine the fit coefficients.\n", ns) ;
02118             cpl_free(acoefsclean) ;
02119             return NULL ;
02120         }
02121 
02122         /* allocate coefficient matrices, see numerical recipe function 
02123            sinfo_matrix */
02124         ucoefs = sinfo_matrix(1, ndata, 1, n_fitcoeffs) ;
02125         vcoefs = sinfo_matrix(1, ndata, 1, n_fitcoeffs) ;
02126         covar  = sinfo_matrix(1, n_fitcoeffs, 1, n_fitcoeffs) ;
02127 
02128         /* scale the x-values for the fit */
02129         for ( i = 0 ; i < ndata ; i++ )
02130         {
02131             sub_col_index[i] = (sub_col_index[i] - offset2) / offset2 ;
02132         }
02133 
02134         /* finally, do the singular value decomposition fit */
02135         sinfo_svd_fitting ( sub_col_index-1, sub_acoefs-1, 
02136                             sub_dacoefs-1, ndata, bcoef[ns]-1,
02137                             n_fitcoeffs, ucoefs, vcoefs, wcoefs-1, 
02138                             covar, &chisq, sinfo_fpol ) ;
02139 
02140         /* scale the found coefficients */
02141         for ( i = 0 ; i < n_fitcoeffs ; i ++ )
02142         {
02143             bcoef[ns][i] /= pow( offset2, i ) ;
02144         }
02145 
02146         /* free memory */
02147         cpl_free (acoefsclean) ;
02148         sinfo_free_matrix( ucoefs, 1/*, ndata*/, 1/*, n_fitcoeffs */) ;
02149         sinfo_free_matrix( vcoefs, 1/*, ndata*/, 1/*, n_fitcoeffs */) ;
02150         sinfo_free_matrix( covar, 1/*, n_fitcoeffs*/, 1/*, n_fitcoeffs*/) ;
02151 
02152         /* now calculate the smoothed acoefs for each column */
02153         col_index = 0 ;
02154         for ( i = ed1 ; i < ed2 ; i++ )
02155         {
02156             a0_clean[i] = 0. ;
02157             for ( n = 0 ; n < n_fitcoeffs ; n++ )
02158             {
02159               a0_clean[i] += bcoef[ns][n] * 
02160                              pow((float)col_index - offset2, n) ;
02161             }
02162             col_index++ ;
02163         }
02164 
02165     }
02166 
02167     for ( col = 0 ; col < ilx ; col++ )
02168     {
02169         /* prepare to write out wavelength as pixel values */
02170         for ( row = 0 ; row < oly ; row++ )
02171         {
02172             centrepix = (float)row - ((float)oly - 1.)/2. ;
02173             pixvalue = 0. ;
02174             for ( i = 1 ; i < n_fitcoeffs ; i++ )
02175             {
02176                 pixvalue += coeffs[i][col]*pow(centrepix, i) ;
02177             }
02178             podata[col+row*olx] = a0_clean[col] + pixvalue ;
02179         }
02180     }
02181 
02182 
02183     cpl_free(emline) ;
02184     cpl_free(spec) ;
02185     cpl_free(wave) ;
02186     cpl_free(a0) ;
02187     cpl_free(a0_clean) ;
02188 
02189 
02190     cpl_free(sub_col_index) ;
02191     cpl_free(sub_acoefs);
02192     cpl_free(sub_dacoefs) ;
02193 
02194     cpl_free(a) ;
02195     cpl_free(z) ;
02196 
02197     sinfo_new_destroy_2Dfloatarray(&bcoef,n_fitcoeffs) ;
02198     cpl_free(wcoefs) ;
02199 
02200     return wavemap ;
02201 }
02202 
02226 cpl_image * sinfo_new_create_shifted_slit_wavemap3 ( cpl_image * lineIm,
02227                               float    ** coeffs,
02228                           int      n_fitcoeffs,
02229                                       float  * wavelength,
02230                                       float  * intensity,
02231                                       int      n_lines,
02232                                       int      magFactor )
02233 {
02234 
02235     cpl_image * wavemap ;
02236     double * result ;
02237     float * filter_spec ;
02238     float centreval ;
02239     float centrepix ;
02240     float cenpos, cenpix ;
02241     float pixvalue ;
02242     float wavelag_mean ;
02243     /*float maxres ;*/
02244     float angst ;
02245     /*float temp ;*/
02246     float a_initial ;
02247     /*float solution[n_fitcoeffs-1], im_solution[n_fitcoeffs-1] ;*/
02248 
02249     float par[MAXPAR] ;
02250     float derv_par[MAXPAR] ;
02251     int        numpar, its ;
02252     int        * mpar ;
02253     float      tol, lab ;
02254     float      * xdat, * wdat ;
02255     Vector     * peak;
02256     int   iters, xdim, ndat ;
02257     int   row , col ;
02258     int   i, j, k/*, l, m, n*/ ;
02259     int   sign, found, line, width ;
02260     int var, maxlag, cmin, cmax ;
02261 
02262     float* emline=NULL ;
02263     float* spec=NULL ;
02264     float* wavelag=NULL ;
02265     float* wave=NULL ;
02266     double* a=NULL ;
02267     double* z=NULL ;
02268 
02269     gsl_poly_complex_workspace * w ;
02270     double xcorr_max ;
02271     int delta ;
02272     
02273     int ilx=0;
02274     int ily=0;
02275     float* pidata=NULL;
02276     int olx=0;
02277     int oly=0;
02278     float* podata=NULL;
02279 
02280 
02281 
02282     if ( lineIm == NULL )
02283     {
02284         sinfo_msg_error (" no input image given!\n") ;
02285         return NULL ;
02286     }
02287     ilx=cpl_image_get_size_x(lineIm);
02288     ily=cpl_image_get_size_y(lineIm);
02289     pidata=cpl_image_get_data_float(lineIm);
02290 
02291     if ( coeffs == NULL )
02292     {
02293         sinfo_msg_error (" no coefficient sinfo_matrix given!\n") ;
02294         return NULL ;
02295     }
02296     if ( n_fitcoeffs < 2 )
02297     {
02298         sinfo_msg_error (" wrong number of polynomial coefficients given!\n") ;
02299         return NULL ;
02300     }
02301 
02302     if ( wavelength == NULL || intensity == NULL )
02303     {
02304         sinfo_msg_error (" no wavelength list given!\n") ;
02305         return NULL ;
02306     }
02307     if ( n_lines < 1 || magFactor < 1 )
02308     {
02309         sinfo_msg_error (" wrong n_lines or magFactor given!\n") ;
02310         return NULL ;
02311     }
02312     
02313     var    = (magFactor - 1)*(magFactor - 1) ;
02314     /* find out if Angstroem or microns are used */
02315     if ( wavelength[0] > 10000. )
02316     {
02317         /* Angstroem */
02318         angst = 10000. ;
02319     }
02320     else if ( wavelength[0] > 1000. && wavelength[0] < 10000. )
02321     {
02322         /* nanometers */
02323         angst = 1000. ;
02324     }
02325     else
02326     {
02327         /* microns */
02328         angst = 1. ;
02329     }
02330 
02331 
02332 
02333     /* allocate memory */
02334     if ( NULL == (wavemap = cpl_image_new ( ilx, ily,CPL_TYPE_FLOAT)) )
02335     {
02336         sinfo_msg_error (" could not allocate memory!\n") ;
02337         return NULL ;
02338     }
02339     podata=cpl_image_get_data_float(lineIm);
02340     olx=ilx;
02341     oly=ily;
02342 
02343     emline=cpl_calloc(ily,sizeof(float)) ;
02344     spec=cpl_calloc(ily,sizeof(float)) ;
02345     wavelag=cpl_calloc(ilx,sizeof(float)) ;
02346     wave=cpl_calloc(n_lines,sizeof(float)) ;
02347     a=cpl_calloc(n_fitcoeffs,sizeof(double)) ;
02348     z=cpl_calloc(2*(n_fitcoeffs - 1),sizeof(double)) ;
02349 
02350     
02351     /* first store each spectrum in a buffer */
02352     for ( col = 0 ; col < ilx ; col++ )
02353     {
02354         /* initialize the emline array for each column */
02355         for ( i = 0 ; i < ily ; i++ )
02356         {
02357             emline[i] = 0. ;
02358         }
02359         /* determine the coefficients by using the given bcoefs */
02360         for ( i = 0 ; i < n_fitcoeffs ; i++ )
02361         {
02362             /* initialize coefficients and solution */
02363             if (i < n_fitcoeffs-1)
02364             {
02365                 z[2*i] = 0. ;
02366                 z[2*i+1] = 0. ;
02367             }
02368             a[i] = coeffs[i][col] ;
02369         }
02370          
02371         a_initial = coeffs[0][col] ;
02372         /* go through the lines and generate an artificial spectrum */
02373         for ( line = 0 ; line < n_lines ; line++ )
02374         {
02375             /* go from Angstroem to micron */
02376             wave[line] = wavelength[line]/angst ;
02377 
02378             /* ----------------------------------------------------------------
02379              * solve the polynomial for the exact offset of the line that means
02380              * find the root of the polynomial of order n_fitcoefs - 1
02381              */
02382             a[0] = a_initial - wave[line] ;
02383 
02384             if (NULL==(w=sinfo_gsl_poly_complex_workspace_alloc(n_fitcoeffs))) 
02385             {
02386                 sinfo_msg_error(" could not allocate complex workspace!") ;
02387                 cpl_image_delete(wavemap) ;
02388                 return NULL ;
02389             }
02390             if (-1 == sinfo_gsl_poly_complex_solve(a, n_fitcoeffs, w, z)) 
02391             {
02392                 sinfo_msg_error("sinfo_gsl_poly_complex_solve did not work!") ;
02393                 cpl_image_delete(wavemap) ;
02394                 return NULL ;
02395             }
02396             sinfo_gsl_poly_complex_workspace_free(w) ;           
02397 
02398             j = 0 ;
02399             found = -1 ;
02400             for ( i = 0 ; i < n_fitcoeffs - 1 ; i++ )
02401             {
02402                 /* test for appropriate solution */
02403                 if( (z[2*i] > (-1.)*(float) ily/2. &&
02404                      z[2*i] < (float)ily/2.) && z[2*i+1] == 0. )
02405                 {
02406                     found = 2*i ;
02407                     j ++ ;
02408                 }
02409                 else
02410                 {
02411                     continue ;
02412                 }
02413             }
02414             if ( j == 0 )
02415             {
02416                 sinfo_msg_warning("no offset solution found for line %d "
02417                                   "in column %d\n", line, col) ;
02418                 continue ;
02419             }
02420             else if ( j == 1 )
02421             {
02422                 cenpos = z[found] + (float) ily /2. ;
02423             }
02424             else
02425             {
02426                 sinfo_msg_warning("two or more offset solutions found for "
02427                                   "line %d in column %d\n", line, col) ;
02428                 continue ;
02429             }
02430 
02431             /*-----------------------------------------------------------------
02432              * magnify image by the given factor add an additional offset
02433              */
02434             cenpix = cenpos ;
02435 
02436             /* determine max and min pixel limits over which 
02437                line should be convolved */
02438             cmin = (sinfo_new_nint(cenpix) - (var-1)) > 0 ? 
02439                     sinfo_new_nint(cenpix) - (var-1) : 0 ;
02440             cmax = (sinfo_new_nint(cenpix) + (var-1)) < ily ?
02441                     sinfo_new_nint(cenpix) + (var-1)  : ily ;
02442 
02443             /* convolve neon lines with Gaussian function */
02444             for ( j = cmin ; j < cmax ; j++ )
02445             {
02446                 emline[j] += intensity[line] * 
02447                         exp((double)(-0.5*(j-cenpix)*(j-cenpix))/(double)var) ;
02448             }
02449         }
02450 
02451         /*--------------------------------------------------------------------
02452          * for each column, map the image data points onto an magFactor times 
02453            bigger element grid for FFT in the cross sinfo_correlation, first 
02454            initialize the two helping arrays for each new column.
02455          */
02456         for ( k = 0 ; k < ily ; k++ )
02457         {
02458             spec[k] = 0. ;
02459         }
02460 
02461         /* now take the image data points of the column and put them into 
02462            the spec array */
02463         for ( row = 0 ; row < ily ; row++ ) /* go through the column */
02464         {
02465             /* set bad pixels or negative values to zero */
02466             if (!isnan(pidata[col + row*ilx]) &&
02467                             (pidata[col + row*ilx] > 0.))
02468             {
02469                 spec[row] = pidata[col + row*ilx] ;
02470             }
02471             else
02472             {
02473                 spec[row] = 0. ;
02474             }
02475         }
02476         /* convolve the spectrum by Gaussian */
02477         filter_spec = sinfo_function1d_filter_lowpass(spec, ily, 
02478                                                       LOW_PASS_GAUSSIAN, 
02479                                                       magFactor) ; 
02480 
02481         /* now call the cross sinfo_correlation routine */
02482         result = sinfo_new_xcorrel( filter_spec, ily, emline, ily,
02483                           ily/2, &delta, &maxlag, &xcorr_max) ;
02484 
02485         if ( xcorr_max <= 0. )
02486         {
02487             sinfo_msg_warning("no positive cross correlation sum , "
02488                               "col %d set to ZERO \n", col) ;
02489             for ( row = 0 ; row < ily ; row++ )
02490             {
02491                 podata[col + row*ilx] = ZERO ;
02492             }
02493             sinfo_function1d_del(filter_spec) ;
02494             cpl_free(result) ;
02495             continue ;
02496         }
02497 
02498        /* in this section, we fit the sinfo_correlation function with a 
02499            gauss, and find its peak, thus getting subpixel-accuracy */
02500 
02501         i = maxlag; j = i+1;
02502         while (result[j] < result[i])
02503         {
02504             i++; j++;
02505         }
02506         i = maxlag; k = i-1;
02507         while (result[k] < result[i])
02508         {
02509             i--; k--;
02510         }
02511         width = j-k+1;
02512         /* allocate memory for the spectral sinfo_vector */
02513         if ( NULL == (peak = sinfo_new_vector (width)) )
02514         {
02515             sinfo_msg_error (" cannot allocate new Vector \n") ;
02516             sinfo_function1d_del(filter_spec) ;
02517             cpl_free(result) ;
02518             return NULL ;
02519         }
02520 
02521 
02522         /* allocate memory */
02523         xdat = (float *) cpl_calloc( peak -> n_elements, sizeof (float) ) ;
02524         wdat = (float *) cpl_calloc( peak -> n_elements, sizeof (float) ) ;
02525         mpar = (int *)   cpl_calloc( MAXPAR, sizeof (int) ) ;
02526 
02527         /* determine the values of the spectral sinfo_vector given as input */
02528         /* go through the chosen column */
02529 
02530         for ( i = 0 ; i < width ; i++ )
02531         {
02532             peak -> data[i] = result[k+i]/xcorr_max * 100. ;
02533             xdat[i] = i;
02534             wdat[i] = 1.0;
02535         }
02536 
02537         /* set initial values for the fitting routine */
02538         xdim     = XDIM;
02539         ndat     = peak -> n_elements ;
02540         numpar   = MAXPAR ;
02541         tol      = TOL ;
02542         lab      = LAB ;
02543         its      = ITS ;
02544         par[1] = width/2.0 ;
02545         par[2] = (float) (maxlag - k) ;
02546         par[3] = (peak -> data[0] + peak -> data[peak->n_elements - 1]) / 2.0 ;
02547         par[0]  = result[maxlag]/xcorr_max * 100. - (par[3]) ;
02548 
02549         for ( i = 0 ; i < MAXPAR ; i++ )
02550         {
02551             derv_par[i] = 0.0 ;
02552             mpar[i] = 1 ;
02553         }
02554 
02555         /* finally, do the least square fit using a sinfo_gaussian */
02556         if ( 0 > ( iters = sinfo_new_lsqfit_c( xdat, &xdim, 
02557                                                peak -> data, wdat, 
02558                                                &ndat, par, derv_par, mpar,
02559                                                &numpar, &tol, &its, &lab )) )
02560         {
02561             sinfo_msg_warning (" sinfo_new_lsqfit_c: least squares fit"
02562                                " failed in col: %d, error no.: %d\n", 
02563                                col, iters) ;
02564             sinfo_new_destroy_vector ( peak ) ;
02565             cpl_free ( xdat ) ;
02566             cpl_free ( wdat ) ;
02567             cpl_free ( mpar ) ;
02568             sinfo_function1d_del(filter_spec) ;
02569             cpl_free(result) ;
02570             continue ;
02571         }
02572 
02573         sinfo_new_destroy_vector ( peak ) ;
02574         cpl_free (xdat) ;
02575         cpl_free (wdat) ;
02576         cpl_free (mpar) ;
02577         sinfo_function1d_del(filter_spec) ;
02578         cpl_free(result) ;
02579 
02580         wavelag[col] =((float)ily/2 - (float)k - par[2]) ;
02581 
02582     }
02583     
02584     if (FLT_MAX==(wavelag_mean=sinfo_new_clean_mean(wavelag, ilx, 10., 10.)) )
02585     {
02586         sinfo_msg_error(" could not determine a mean offset\n") ;
02587         return NULL ;
02588     }
02589 
02590     if ( fabs(wavelag_mean) > (float)ily/20. )
02591     {
02592         sinfo_msg_error(" wavelag too big \n") ;
02593         return NULL ;
02594     }
02595 
02596     
02597 
02598     for ( col = 0 ; col < ilx ; col++ )
02599     {
02600         /*--------------------------------------------------------------------
02601          * determine new zero order coefficient centreval, of which the 
02602          * formula is determined by setting equal a polynomial shifted by 
02603          * wavelag with the same higher order coefficients and set the new 
02604          * zero order coefficient to get both sides of the equation 
02605          * approximately equal.
02606          */
02607         a_initial = coeffs[0][col] ;
02608     centreval = a_initial ;
02609     for ( i = 1 ; i < n_fitcoeffs ; i++ )
02610         {
02611             if ( i%2 == 0 )
02612             {
02613                 sign = -1 ;
02614             }
02615             else
02616             {
02617                 sign = 1 ;
02618             }
02619             centreval += (float)sign * coeffs[i][col]*pow(wavelag_mean, i) ;
02620         }
02621 
02622     
02623         /* prepare to write out wavelength as pixel values */
02624         for ( row = 0 ; row < oly ; row++ )
02625         {
02626             centrepix = (float)row - ((float)oly - 1.)/2. ;
02627             pixvalue = 0. ;
02628             for ( i = 1 ; i < n_fitcoeffs ; i++ )
02629             {
02630                 pixvalue += coeffs[i][col]*pow(centrepix, i) ;
02631             }
02632             podata[col+row*olx] = centreval + pixvalue ;
02633         }
02634     }
02635 
02636 
02637 
02638     cpl_free(emline) ;
02639     cpl_free(spec) ;
02640     cpl_free(wavelag) ;
02641     cpl_free(wave) ;
02642     cpl_free(a) ;
02643     cpl_free(z) ;
02644 
02645 
02646     return wavemap ;
02647 }
02648 
02671 float sinfo_new_check_line_positions ( cpl_image     * lineIm,
02672                        float       ** coeffs,
02673                        int            n_fitcoeffs,
02674                        float            gdisp1,
02675                        FitParams   ** par )
02676 {
02677     float wave_shift=0 ;
02678     float amp[100] ;
02679     float sort_amp[100] ;
02680     float offset=0 ;
02681     float shift=0 ;
02682     float position=0;
02683     float lambda=0;
02684     float wave=0 ;
02685     int i=0;
02686     int j=0;
02687     int k=0;
02688     int l=0;
02689     int m=0;
02690     int n=0;
02691     int col=0;
02692     int firstj=0;
02693     float* shift_col=NULL ;
02694     int* foundit=NULL ;
02695     int n_lines=0;
02696     int lin, found=0 ;
02697     int lx=0;
02698     int ly=0;
02699     float* pdata=NULL;
02700 
02701     if ( lineIm == NULL )
02702     {
02703         sinfo_msg_error (" no input image given!\n") ;
02704         return FLAG ;
02705     }
02706     lx=cpl_image_get_size_x(lineIm);
02707     ly=cpl_image_get_size_y(lineIm);
02708     pdata=cpl_image_get_data_float(lineIm);
02709 
02710     if ( coeffs == NULL )
02711     {
02712         sinfo_msg_error (" no coefficient sinfo_matrix given!\n") ;
02713         return FLAG ;
02714     }
02715     if ( par == NULL )
02716     {
02717         sinfo_msg_error (" no fit parameters given!\n") ;
02718         return FLAG ;
02719     }
02720     if ( n_fitcoeffs < 2 )
02721     {
02722         sinfo_msg_error (" wrong number of polynomial coefficients given!\n") ;
02723         return FLAG ;
02724     }
02725 
02726     offset = (float) (ly -1.) / 2. ;
02727     n_lines = par[0]->n_params/lx ;
02728 
02729     shift_col=cpl_calloc(lx,sizeof(float)) ;
02730     foundit=cpl_calloc(par[0]->n_params,sizeof(int)) ;
02731     
02732     /*search for the brightest 5 lines in each column and compute the 
02733       wavelength difference*/
02734     for ( col = 0 ; col < lx ; col++ )
02735     {
02736         n = 0 ;
02737         for ( i = 0 ; i < par[0]->n_params ; i++ )
02738         {
02739             if (par[i]->column == col && par[i]->fit_par[2] != 0. && 
02740                 par[i]->fit_par[1] > 1. && par[i]->fit_par[1] < 7. )
02741             {
02742                 foundit[n] = i ;
02743                 amp[n] = par[i]->fit_par[0] ;
02744                 sort_amp[n] = amp[n] ;
02745                 n++ ;
02746             }
02747         }
02748         sinfo_pixel_qsort(sort_amp, n) ;
02749 
02750         if ( n > 5 )
02751         {
02752             firstj = n - 5 ;
02753         }
02754         else
02755         {
02756             firstj = 0 ;
02757         }
02758         l = 0 ; 
02759         shift = 0 ;
02760         for ( j = firstj ; j < n ; j++ )
02761         {
02762             for ( m = 0 ; m < n ; m++ )
02763             {
02764                 if ( sort_amp[j] == amp[m] )
02765                 {
02766                     position = par[foundit[m]]->fit_par[2] ; 
02767                     lambda   = par[foundit[m]]->wavelength ;
02768                     wave = 0 ;
02769                     for ( k = 0 ; k < n_fitcoeffs ; k++ ) 
02770                     {
02771                         wave += coeffs[k][col]*pow(position-offset, k) ;
02772                     }
02773                     shift += lambda - wave ;
02774                     l++ ;
02775                 }
02776             }
02777         }
02778         if ( l == 0 ) continue ;
02779         shift_col[col] = shift/(float)l ; 
02780     }
02781     wave_shift = sinfo_new_clean_mean(shift_col, lx, 10., 10.) ;
02782     sinfo_msg("Overall positioning error: %3.2g [um] %3.2g [pix]", 
02783                wave_shift,wave_shift/fabs(gdisp1)) ;
02784 
02785 
02786     /* determine positioning error for each found line */
02787     for ( lin = 0 ; lin < n_lines ; lin++ )
02788     {
02789         for ( col = 0 ; col < lx ; col++ )
02790         {
02791             shift_col[col] = 0. ;
02792             found = -1 ;
02793             for ( i = 0 ; i < par[0]->n_params ; i++ )
02794             {
02795                 if (par[i]->column == col && par[i]->fit_par[2] != 0. && 
02796                     par[i]->fit_par[1] > 1. && par[i]->fit_par[1] < 7. && 
02797                     par[i]->line == lin )
02798                 {
02799                     found = i ;
02800                 }
02801             }
02802             if (found == -1) break ;
02803 
02804             position = par[found]->fit_par[2] ; 
02805             lambda  = par[found]->wavelength ;
02806             wave = 0 ;
02807             for ( k = 0 ; k < n_fitcoeffs ; k++ ) 
02808             {
02809                 wave += coeffs[k][col]*pow(position-offset, k) ;
02810             }
02811             shift_col[col] = lambda - wave ;
02812         }
02813         if (found != -1 )
02814         {
02815       sinfo_msg("shift: %3.2g [um] %3.2g (pix) at: %4.3f [um]",
02816             sinfo_new_clean_mean(shift_col,lx, 10., 10.),
02817                     sinfo_new_clean_mean(shift_col,lx, 10., 10.)/fabs(gdisp1),
02818                     lambda) ;
02819         }
02820     }
02821     cpl_free(shift_col) ;
02822     cpl_free(foundit) ;
02823 
02824     return wave_shift ;
02825 }
02826 
02827 
02856 float sinfo_new_check_correlated_line_positions ( cpl_image     * lineIm,
02857                                      float       ** coeffs,
02858                                      int            n_fitcoeffs,
02859                                      float        * wavelength,
02860                                      float        * intensity,
02861                                      int            n_lines,
02862                                      float          fwhm, 
02863                                      float          width,
02864                                      float          min_amplitude,
02865                                      float          dispersion,
02866                                      FitParams   ** par )
02867 {
02868     float wave_shift=0 ;
02869     float offset=0;
02870     float shift=0;
02871     float position=0;
02872     float lambda=0;
02873     float wave=0;
02874     int i=0;
02875     int j=0;
02876     int k=0;  /*, l, m*/
02877     int n=0;
02878     int c=0;
02879     int z=0;
02880     int col=0;/*, firstj*/
02881     int found=0;/*lin,*/
02882     int line=0;
02883     int result=0;
02884     float cenpos=0;
02885     float angst=0;
02886     float a_initial=0;
02887 
02888     int* foundit=NULL ;
02889     float* shift_col=NULL ;
02890     float* wave_cor=NULL ;
02891     double* a=NULL ;
02892     double* zroot=NULL ;
02893 
02894     gsl_poly_complex_workspace * w=NULL ;
02895     Vector * vline=NULL;
02896     int    * mpar=NULL;
02897     float  * xdat=NULL;
02898     float  * wdat=NULL;
02899     int lx=0;
02900     int ly=0;
02901     float* pdata=NULL;
02902 
02903     if ( lineIm == NULL )
02904     {
02905         sinfo_msg_error (" no input image given!\n") ;
02906         return FLAG ;
02907     }
02908     lx=cpl_image_get_size_x(lineIm);
02909     ly=cpl_image_get_size_y(lineIm);
02910     pdata=cpl_image_get_data_float(lineIm);
02911 
02912 
02913     if ( coeffs == NULL )
02914     {
02915         sinfo_msg_error (" no coefficient sinfo_matrix given!\n") ;
02916         return FLAG ;
02917     }
02918     if ( par == NULL )
02919     {
02920         sinfo_msg_error (" no fit parameters given!\n") ;
02921         return FLAG ;
02922     }
02923     if ( n_fitcoeffs < 2 )
02924     {
02925         sinfo_msg_error (" wrong number of polynomial coefficients given!\n") ;
02926         return FLAG ;
02927     }
02928     if ( wavelength == NULL || intensity == NULL )
02929     {
02930         sinfo_msg_error (" no line list given!\n") ;
02931         return FLAG ;
02932     }
02933     if ( fwhm <= 0 )
02934     {
02935         sinfo_msg_error (" wrong guess fwhm given!\n") ;
02936         return FLAG ;
02937     }
02938     if ( width <= 0 )
02939     {
02940         sinfo_msg_error (" wrong half width given!\n") ;
02941         return FLAG ;
02942     } 
02943     if ( min_amplitude <= 0 )
02944     {
02945         sinfo_msg_error (" wrong guess amplitude given!\n") ;
02946         return FLAG ;
02947     } 
02948 
02949     /* allocate memory for the spectral sinfo_vector */
02950     if ( NULL == (vline = sinfo_new_vector (2*width + 1)) )
02951     {
02952         sinfo_msg_error (" cannot allocate new Vector \n") ;
02953         return -14 ;
02954     }
02955     /* allocate memory */
02956     xdat = (float *) cpl_calloc( vline -> n_elements, sizeof (float) ) ;
02957     wdat = (float *) cpl_calloc( vline -> n_elements, sizeof (float) ) ;
02958     mpar = (int *)   cpl_calloc( MAXPAR, sizeof (int) ) ;
02959 
02960 
02961     foundit=cpl_calloc(par[0]->n_params,sizeof(int)) ;
02962     shift_col=cpl_calloc(lx,sizeof(float)) ;
02963     wave_cor=cpl_calloc(n_lines,sizeof(float)) ;
02964     a=cpl_calloc(n_fitcoeffs,sizeof(float)) ;
02965     zroot=cpl_calloc(2*(n_fitcoeffs - 1),sizeof(float)) ;
02966 
02967 
02968 
02969     /* determine the approximate line positions using the line list and the 
02970        coefficients */
02971     /* find out if Angstroem or microns are used */
02972     if ( wavelength[0] > 10000. )
02973     {
02974         /* Angstroem */
02975         angst = 10000. ;
02976     }
02977     else if ( wavelength[0] > 1000. && wavelength[0] < 10000. )
02978     {
02979         /* nanometers */
02980         angst = 1000. ;
02981     }
02982     else
02983     {
02984         /* microns */
02985         angst = 1. ;
02986     }
02987     offset = ((float) ly -1.) / 2. ;
02988 
02989     k = 0 ;
02990     for ( col = 10 ; col < 25 ; col++ )
02991     {
02992         /* determine the coefficients by using the given bcoefs */
02993         for ( i = 0 ; i < n_fitcoeffs ; i++ )
02994         {
02995             /* initialize coefficients and solution */
02996             if (i < n_fitcoeffs-1)
02997             {
02998                 zroot[2*i] = 0. ;
02999                 zroot[2*i+1] = 0. ;
03000             }
03001             a[i] = coeffs[i][col] ;
03002         }
03003         a_initial = a[0] ;
03004 
03005         /* go through the lines */
03006         for ( line = 0 ; line < n_lines ; line++ )
03007         {
03008             /* go from Angstroem to micron */
03009             wave_cor[line] = wavelength[line]/angst ;
03010             if (line > 0 && line < n_lines-1)
03011             {
03012                 if (fabs((wave_cor[line] - wave_cor[line-1]) / 
03013                          dispersion ) < 2*width ||
03014                     fabs((wave_cor[line] - wave_cor[line+1]) / 
03015                          dispersion ) < 2*width )
03016                 {
03017                     continue ;
03018                 }
03019             }
03020 
03021             a[0] = a_initial - wave_cor[line] ;
03022 
03023             if (NULL==(w=sinfo_gsl_poly_complex_workspace_alloc(n_fitcoeffs)))
03024             {
03025                 sinfo_msg_error(" could not allocate complex workspace!") ;
03026                 return FLAG ;
03027             }
03028             if (-1 == sinfo_gsl_poly_complex_solve(a, n_fitcoeffs, w, zroot))
03029             {
03030                 sinfo_msg_error(" sinfo_gsl_poly_complex_solve did not work!") ;
03031                 return FLAG ;
03032             }
03033             sinfo_gsl_poly_complex_workspace_free(w) ;
03034 
03035             j = 0 ;
03036             found = -1 ;
03037             for ( i = 0 ; i < n_fitcoeffs - 1 ; i++ )
03038             {
03039                 /* test for appropriate solution */
03040                 if( (zroot[2*i] > (-1.)*(float) ly/2. &&
03041                      zroot[2*i] < (float)ly/2.) && zroot[2*i+1] == 0. )
03042                 {
03043                     found = 2*i ;
03044                     j ++ ;
03045                 }
03046                 else
03047                 {
03048                     continue ;
03049                 }
03050             }
03051 
03052             if ( j == 0 )
03053             {
03054                 sinfo_msg_warning(" no offset solution found for line %d "
03055                                   "in column %d\n", line, col) ;
03056                 continue ;
03057             }
03058             else if ( j == 1 )
03059             {
03060                 cenpos = zroot[found] + (float)ly / 2. ; ;
03061             }
03062             else
03063             {
03064                 sinfo_msg_warning(" two or more offset solutions found for \
03065                        line %d in column %d\n", line, col) ;
03066                 continue ;
03067             }
03068 
03069             if ( cenpos <= 0 )
03070             {
03071                 continue ;
03072             }
03073 
03074             /* --------------------------------------------------------------
03075              * fit the single lines using sinfo_linefit and store the 
03076              * parameters in
03077              * an array of the FitParams data structure allParams[].
03078              */
03079             if ( (result = sinfo_new_line_fit ( lineIm, par[k], 
03080                                                 fwhm, line, col,
03081                                          width, cenpos, min_amplitude, vline,
03082                                          mpar, xdat, wdat ) ) < 0 )
03083             {
03084              sinfo_msg_debug ("sinfo_linefit failed, error no.: %d, "
03085                               "column: %d, row: %f, line: %d\n", 
03086                               result, col, cenpos, line) ;
03087                 continue ;
03088             }
03089             if ( (par[k] -> fit_par[0] <= 0.) || (par[k] -> fit_par[1] <= 0.)
03090                   || (par[k] -> fit_par[2] <= 0.) )
03091             {
03092                 sinfo_msg_warning ("negative fit parameters in column: %d, "
03093                                    "line: %d\n", col, line) ;
03094                 continue ;
03095             }
03096             par[k] -> wavelength = wavelength[line] ;
03097             k++ ;
03098         }
03099 
03100     }
03101     
03102     /* free memory */
03103     sinfo_new_destroy_vector(vline);
03104     cpl_free(xdat);
03105     cpl_free(wdat);
03106     cpl_free(mpar);
03107 
03108     
03109     c = 0 ;
03110     for ( col = 10 ; col < 25 ; col++ )
03111     {
03112         n = 0 ;
03113         for ( i = 0 ; i < k ; i++ )
03114         {
03115             if (par[i]->column == col && par[i]->fit_par[2] != 0. && 
03116                 par[i]->fit_par[1] > 1. && par[i]->fit_par[1] < 7. )
03117             {
03118                 foundit[n] = i ;
03119                 n++ ;
03120             }
03121         }
03122         if ( n == 0 ) continue ;
03123 
03124         shift = 0 ;
03125         z = 0 ;
03126         for ( j = 0 ; j < n ; j++ )
03127         {
03128             position = par[foundit[j]]->fit_par[2] ; 
03129             lambda   = par[foundit[j]]->wavelength ;
03130             line     = par[foundit[j]]->line ;
03131             if (line > 0 && line < n_lines-1)
03132             {
03133                 if (fabs((wave_cor[line] - wave_cor[line-1]) / 
03134                           dispersion ) < 2*width ||
03135                     fabs((wave_cor[line] - wave_cor[line+1]) / 
03136                           dispersion ) < 2*width )
03137                 {
03138                     continue ;
03139                 }
03140             }
03141             wave = 0 ;
03142             for ( i = 0 ; i < n_fitcoeffs ; i++ ) 
03143             {
03144                 wave += coeffs[i][col]*pow(position-offset, i) ;
03145             }
03146             shift += lambda - wave ;
03147             z++ ;
03148         }
03149         shift_col[c] = shift/(float)z ; 
03150         c++ ;
03151     }
03152     if ( c > 0 )
03153     {
03154         wave_shift = sinfo_new_clean_mean(shift_col, c, 10., 10.) ;
03155         sinfo_msg("overall positioning error in microns: %g", wave_shift) ;
03156     }
03157 
03158     /* determine positioning error for each found line */
03159     for ( line = 0 ; line < n_lines ; line++ )
03160     {
03161         if (line > 0 && line < n_lines-1)
03162         {
03163             if (fabs((wave_cor[line] - wave_cor[line-1]) / dispersion ) < 
03164                                          2*width ||
03165                 fabs((wave_cor[line] - wave_cor[line+1]) / dispersion ) < 
03166                                          2*width )
03167             {
03168                 continue ;
03169             }
03170         }
03171 
03172         c = 0 ;
03173         for ( col = 10 ; col < 25 ; col++ )
03174         {
03175             shift_col[c] = 0. ;
03176             found = -1 ;
03177             for ( i = 0 ; i < k ; i++ )
03178             {
03179                 if (par[i]->column == col && par[i]->fit_par[2] != 0. && 
03180                     par[i]->fit_par[1] > 1. && par[i]->fit_par[1] < 7. && 
03181                     par[i]->line == line )
03182                 {
03183                     found = i ;
03184                 }
03185             }
03186             if (found == -1) break ;
03187 
03188             position = par[found]->fit_par[2] ; 
03189             lambda  = par[found]->wavelength ;
03190             wave = 0 ;
03191             for ( i = 0 ; i < n_fitcoeffs ; i++ ) 
03192             {
03193                 wave += coeffs[i][col]*pow(position-offset, i) ;
03194             }
03195             shift_col[c] = lambda - wave ;
03196             c++ ;
03197         }
03198         if (found != -1 && c > 0 )
03199         {
03200             sinfo_msg("shift in microns: %g at wavelength: %f\n", 
03201             sinfo_new_clean_mean(shift_col, c, 20., 20.), lambda) ;
03202         }
03203     }
03204 
03205 
03206 
03207     cpl_free(foundit) ;
03208     cpl_free(shift_col) ;
03209     cpl_free(wave_cor) ;
03210     cpl_free(a) ;
03211     cpl_free(zroot) ;
03212 
03213     return wave_shift ;
03214 }
03215 
03216 
03217 
03242  static int   
03243 sinfo_new_spred_coeffs_cross_slit_fit ( int      n_columns,
03244                             float ** acoefs,
03245                             float ** dacoefs,
03246                             Bcoeffs* bco,
03247                             float    sigma_factor,
03248                             float    dispersion,
03249                             float    pixel_dist,
03250                             float  * chisq,
03251                           float ** sinfo_slit_pos )
03252  {
03253      float col_index;
03254 
03255 
03256      float ** ucoefs, **vcoefs, **covar ;
03257      float * acoefsclean ;
03258      double sum, sumq, mean ;
03259      double sigma ;
03260      double cliphi, cliplo ;
03261      float offset ;
03262      float threshold ;
03263 
03264      int* edge=NULL ;
03265      float* sub_col_index=NULL ;
03266      float* sub_acoefs=NULL;
03267      float* sub_dacoefs=NULL ;
03268      float* wcoefs=NULL ;
03269 
03270 
03271      int ed1, ed2 ;
03272      int i, n, num, ndata ;
03273      int nc, ns ;
03274      int loc_index ;
03275      int sl_index;
03276      int last_i=PIXEL;
03277  
03278      if ( n_columns < 1 )
03279      {
03280          sinfo_msg_error(" wrong number of image columns given\n") ;
03281          return -1 ;
03282      }
03283      if ( acoefs == NULL || dacoefs == NULL )
03284      {
03285          sinfo_msg_error(" acoeffs or errors of coefficients are not given") ;
03286          return -1 ;
03287      }
03288      if ( bco == NULL )
03289      {
03290          sinfo_msg_error(" bcoeffs are not allocated\n") ;
03291          return -1 ;
03292      }
03293      if ( sigma_factor <= 0. )
03294      {
03295          sinfo_msg_error(" impossible sigma_factor given!\n") ;
03296          return -1 ;
03297      }
03298      if ( dispersion == 0. )
03299      {
03300          sinfo_msg_error(" impossible dispersion given!\n") ;
03301          return -1 ;
03302      }
03303 
03304 
03305      edge=cpl_calloc(bco->n_slitlets,sizeof(int)) ;
03306      sub_col_index=cpl_calloc(n_columns,sizeof(float)) ;
03307      sub_acoefs=cpl_calloc(n_columns,sizeof(float));
03308      sub_dacoefs=cpl_calloc(n_columns,sizeof(float)) ;
03309 
03310      wcoefs=cpl_calloc(bco->n_bcoeffs,sizeof(float)) ;
03311 
03312      /*------------------------------------------------------------------------
03313       * search for the slitlet edges by comparing the a0 coefficients along i
03314       * the columns
03315       * if a bigger deviation occurrs it is assumed that there is an edge.
03316       */
03317      n = 0 ;
03318      threshold = pixel_dist * fabs(dispersion) ;
03319      sinfo_slit_pos[0][0]=0 ;
03320      sl_index  = 0;
03321      /* it was for ( i = PIXEL ; i  < n_columns - PIXEL ; ) */
03322      for ( i = 0 ; i  < n_columns - PIXEL ; )
03323      {
03324          if ( !isnan(acoefs[0][i+1]) && 
03325                      acoefs[0][i+1] != 0. && 
03326                      acoefs[0][i] != 0.
03327                    && dacoefs[0][i+1] != 0.)
03328          {
03329              if ( isnan(acoefs[0][i]) || acoefs[0][i] == 0. )
03330              {
03331                  if (fabs(acoefs[0][i+1] - acoefs[0][i-1]) >= threshold )
03332              {
03333              /* printf("case a pos1 %d pos2 %d \n",i,i+1); */
03334                      edge[n] = i+1 ;
03335              sinfo_slit_pos[sl_index][1] = i ;
03336              sinfo_slit_pos[sl_index+1][0] = i + 1 ;
03337              sl_index++;
03338                      n++ ;
03339              last_i = i;
03340                      i += PIXEL ;
03341                  }
03342              }
03343              else
03344              {
03345                  if (fabs(acoefs[0][i+1] - acoefs[0][i]) >= threshold )
03346              {
03347              /* printf("case b pos1 %d pos2 %d \n",i,i+1); */
03348                      edge[n] = i+1 ;
03349              sinfo_slit_pos[sl_index][1] = i ;
03350              sinfo_slit_pos[sl_index+1][0] = i + 1 ;
03351              sl_index++;
03352                      n++ ;
03353              last_i = i;
03354                      i += PIXEL ;
03355                  }
03356              }
03357 
03358 
03359             /* sometimes a slitlet may be lost due to divergences in 
03360                 acoeffs[0] we try to recover it */
03361              if( ( (i-last_i) > 63 ) && 
03362                 ( isnan(fabs(acoefs[0][i+1] - acoefs[0][i])) ||
03363                   isnan(fabs(acoefs[0][i+1] - acoefs[0][i-1])) ) ) 
03364          {
03365                      edge[n] = i+1 ;
03366                      sinfo_slit_pos[sl_index][1] = i ;
03367                      sinfo_slit_pos[sl_index+1][0] = i + 1 ;
03368                      sl_index++;
03369                      n++ ;
03370 
03371                      last_i = i;
03372                      sinfo_msg_warning("2 recovered slitlet edge i=%d",i);
03373                      i += PIXEL ;
03374 
03375          }
03376          }
03377          i++ ;
03378      }
03379      sinfo_slit_pos[sl_index][1]  = 2047;
03380      /* printf("2 Found n slitlest: %d check %d\n", n,bco->n_slitlets - 1); */
03381      if ( n != bco->n_slitlets - 1 )
03382      {
03383          sinfo_msg_error("could not find the right number of "
03384                          "slitlets, found: %d\n",n+1) ;
03385          return -1 ;
03386      }
03387 
03388      /* go through the coefficents indices */
03389      for ( loc_index = 0 ; loc_index < bco->n_acoeffs ; loc_index++ )
03390      {
03391          /* go through the single slitlets */
03392          for ( ns = 0 ; ns < bco->n_slitlets ; ns++ )
03393          {
03394              /* determine the slitlet edges */
03395              if ( ns == 0 )
03396              {
03397                  ed1 = 0 ;
03398                  ed2 = edge[0] ;
03399              }
03400              else if ( ns == bco->n_slitlets - 1 )
03401              {
03402                  ed1 = edge[bco->n_slitlets - 2] ;
03403                  ed2 = n_columns ;
03404              }
03405              else
03406              {
03407                  ed1 = edge[ns-1] ;
03408                  ed2 = edge[ns] ;
03409              }
03410 
03411              nc = 0 ;
03412              for ( i = ed1 ; i < ed2 ; i++ )
03413              {
03414                  if ( isnan(acoefs[loc_index][i]) || 
03415                             acoefs[loc_index][i] == 0. || 
03416                            dacoefs[loc_index][i] == 0. )
03417                  {
03418                      continue ;
03419                  }
03420                  else
03421                  {
03422                      nc++ ;
03423                  }
03424              }
03425              if (NULL==(acoefsclean=(float*) cpl_calloc(nc , sizeof(float))) )
03426              {
03427                  sinfo_msg_error("could not allocate memory for acoefsclean!");
03428                  return -1 ;
03429              }
03430              nc = 0 ;
03431              for ( i = ed1 ; i  < ed2 ; i++ )
03432             {
03433                 if ( isnan(acoefs[loc_index][i]) || 
03434                            acoefs[loc_index][i] == 0. || 
03435                           dacoefs[loc_index][i] == 0. )
03436                 {
03437                     continue ;
03438                 }
03439                 else
03440                 {
03441                     acoefsclean[nc] = acoefs[loc_index][i] ;
03442                     nc++ ;
03443                 }
03444             }
03445 
03446             /* ----------------------------------------------------------
03447              * determine the clean mean and sigma value of the coefficients,
03448              * that means reject 10 % of the extreme low and high values
03449              */
03450             sinfo_pixel_qsort(acoefsclean, nc) ;
03451 
03452             sum   = 0. ;
03453             sumq  = 0. ;
03454             mean  = 0. ;
03455             sigma = 0. ;
03456             n     = 0 ;
03457             for ( i = (int)((float)nc*LOW_REJECT) ; 
03458                   i < (int)((float)nc*HIGH_REJECT) ; i++ )
03459             {
03460                 sum  += (double)acoefsclean[i] ;
03461                 sumq += ((double)acoefsclean[i] * (double)acoefsclean[i]) ;
03462                 n ++ ;
03463             }
03464             mean          = sum/(double)n ;
03465             sigma         = sqrt( sumq/(double)n - (mean * mean) ) ;
03466             cliphi        = mean + sigma * (double)sigma_factor ;
03467             cliplo        = mean - sigma * (double)sigma_factor ;
03468             /* fit only the reasonnable values */
03469             num = 0 ;
03470             col_index = 0 ;
03471             for ( i = ed1 ; i < ed2 ; i++ )
03472             {
03473                 /* take only the reasonnable coefficients */
03474                 if ( !isnan(acoefs[loc_index][i]) && 
03475                            (acoefs[loc_index][i] <= cliphi) && 
03476                            (acoefs[loc_index][i] >= cliplo) &&
03477                      (dacoefs[loc_index][i] != 0. ) && 
03478              (acoefs[loc_index][i] != 0.) )
03479                 {
03480                     sub_acoefs[num]    = acoefs[loc_index][i] ;
03481                     sub_dacoefs[num]   = dacoefs[loc_index][i] ;
03482                     sub_col_index[num] = col_index ;
03483                     num ++ ;
03484                 }
03485                 col_index++ ;
03486             }
03487             ndata = num ;
03488             offset = (float)(col_index-1) / 2. ;
03489 
03490             if ( ndata < bco->n_bcoeffs )
03491             {
03492                 sinfo_msg_error(" not enough data found in slitlet %da"
03493                                 " to determine the fit coefficients.\n", ns) ;
03494                 cpl_free(acoefsclean) ;
03495                 return -1 ;
03496             }
03497 
03498             /* allocate coefficient matrices */
03499             ucoefs = sinfo_matrix(1, ndata, 1, bco->n_bcoeffs) ;
03500             vcoefs = sinfo_matrix(1, ndata, 1, bco->n_bcoeffs) ;
03501             covar  = sinfo_matrix(1, bco->n_bcoeffs, 1, bco->n_bcoeffs) ;
03502 
03503             /* scale the x-values for the fit */
03504             for ( i = 0 ; i < ndata ; i++ )
03505             {
03506                 sub_col_index[i] = (sub_col_index[i] - offset) / offset ;
03507             }
03508 
03509             /* finally, do the singular value decomposition fit */
03510             sinfo_svd_fitting ( sub_col_index-1, sub_acoefs-1, 
03511                                 sub_dacoefs-1, ndata, bco[ns].b[loc_index]-1,
03512                                 bco->n_bcoeffs, ucoefs, vcoefs, wcoefs-1, 
03513                                 covar, &chisq[ns], sinfo_fpol ) ;
03514 
03515             /* scale the found coefficients */
03516             for ( i = 0 ; i < bco->n_bcoeffs ; i ++ )
03517             {
03518                 bco[ns].b[loc_index][i] /= pow( offset, i ) ;
03519             }
03520 
03521             /* free memory */
03522             cpl_free (acoefsclean) ;
03523             sinfo_free_matrix( ucoefs, 1/*, ndata*/, 1/*, bco->n_bcoeffs */) ;
03524             sinfo_free_matrix( vcoefs, 1/*, ndata*/, 1/*, bco->n_bcoeffs */) ;
03525             sinfo_free_matrix( covar, 1/*, bco->n_bcoeffs*/, 
03526                                1/*, bco->n_bcoeffs */) ;
03527 
03528             /* now calculate the smoothed acoefs for each column */
03529             col_index = 0 ;
03530             for ( i = ed1 ; i < ed2  ; i++ )
03531             {
03532                 acoefs[loc_index][i] = 0. ;
03533                 for ( n = 0 ; n < bco->n_bcoeffs ; n++ )
03534                 {
03535                     acoefs[loc_index][i] += bco[ns].b[loc_index][n] * 
03536                                         pow(col_index - offset, n) ;
03537                 }
03538                 col_index++ ;
03539             }
03540 
03541         }
03542     }
03543 
03544 
03545     cpl_free(edge) ;
03546     cpl_free(sub_col_index) ;
03547     cpl_free(sub_acoefs);
03548     cpl_free(sub_dacoefs) ;
03549     cpl_free(wcoefs) ;
03550 
03551     return 0 ;
03552 }
03553 
03554 
03603 cpl_image * sinfo_new_spred_wave_cal( cpl_image   * image,
03604                     FitParams ** par ,
03605                     float     ** abuf,
03606                     int          n_slitlets,
03607                     int       ** row_clean,
03608                     float     ** wavelength_clean,
03609                     int        * n_found_lines,
03610                     float        dispersion,
03611                     int          halfWidth,
03612                     float        minAmplitude,
03613                     float        max_residual,
03614                     float        fwhm,
03615                     int          n_a_fitcoefs,
03616                     int          n_b_fitcoefs,
03617                     float        sigmaFactor,
03618                     float        pixel_dist,
03619                     float        pixel_tolerance,
03620                   float ** sinfo_slit_pos)
03621 
03622 
03623 {
03624     int          i, j, k ;
03625     int          n_fit ;
03626     int          n_reject ;
03627     float     *  acoefs ;
03628     float     *  dacoefs ;
03629     float     ** dabuf ;
03630     float        chisq_poly ;
03631     float     *  chisq_cross ;
03632     int          zeroind ;
03633     int          crossInd ;
03634     Bcoeffs   *  bco ;
03635     cpl_image  *  wavemap ;
03636     int ilx=0;
03637     int ily=0;
03638     float* pidata=NULL;
03639 
03640 
03641     if (  NULL == image )
03642     {
03643         sinfo_msg_error(" no image given\n") ;
03644         return NULL ;
03645     }
03646     ilx=cpl_image_get_size_x(image);
03647     ily=cpl_image_get_size_y(image);
03648     pidata=cpl_image_get_data_float(image);
03649 
03650     if ( par == NULL )
03651     {
03652         sinfo_msg_error(" no fit parameter data structure given\n") ;
03653         return NULL ;
03654     }
03655     if ( abuf == NULL )
03656     {
03657         sinfo_msg_error(" no buffer for fit coefficients given\n") ;
03658         return NULL ;
03659     }
03660     if ( n_slitlets <= 0 )
03661     {
03662         sinfo_msg_error(" impossible number of slitlets given\n") ;
03663         return NULL ;
03664     }
03665     if ( row_clean == NULL )
03666     {
03667         sinfo_msg_error(" no row_clean array given\n") ;
03668         return NULL ;
03669     }
03670     if ( wavelength_clean == NULL )
03671     {
03672         sinfo_msg_error(" no wavelength_clean array given\n") ;
03673         return NULL ;
03674     }
03675 
03676     if ( dispersion == 0. )
03677     {
03678         sinfo_msg_error(" impossible dispersion given\n") ;
03679         return NULL ;
03680     }
03681 
03682     if ( halfWidth <= 0 || halfWidth > ily/2 )
03683     {
03684         sinfo_msg_error(" impossible half width of the fitting box given\n") ;
03685         return NULL ;
03686     }
03687     if ( minAmplitude < 1. )
03688      {
03689          sinfo_msg_error(" impossible minimal amplitude\n") ;
03690          return NULL ;
03691      }
03692 
03693      if ( max_residual <= 0. || max_residual > 1. )
03694      {
03695          sinfo_msg_error(" impossible max_residual given\n") ;
03696          return NULL ;
03697      }
03698      if ( fwhm <= 0. || fwhm > 10. )
03699      {
03700          sinfo_msg_error(" impossible fwhm given\n") ;
03701          return NULL ;
03702      }
03703 
03704      if ( n_a_fitcoefs <= 0 || n_a_fitcoefs > 9 )
03705      {
03706          sinfo_msg_error(" unrealistic n_a_fitcoefs given\n") ;
03707          return NULL ;
03708      }
03709 
03710      if ( n_b_fitcoefs <= 0 || n_b_fitcoefs > 9 )
03711      {
03712          sinfo_msg_error(" unrealistic n_b_fitcoefs given\n") ;
03713          return NULL ;
03714      }
03715      if ( sigmaFactor <= 0. )
03716      {
03717          sinfo_msg_error(" impossible sigmaFactor given\n") ;
03718          return NULL ;
03719      }
03720 
03721      /* initialize the variables */
03722      n_reject = 0 ;
03723      n_fit = 0 ;
03724 
03725      /* fit each found line by using a sinfo_gaussian function and 
03726         determine the exact position */
03727      if ( 0 > (n_fit = sinfo_new_fit_lines( image , par, fwhm, n_found_lines, 
03728                                       row_clean, wavelength_clean,
03729                                       halfWidth, minAmplitude )) )
03730      {
03731          sinfo_msg_error(" cannot fit the lines, error code of "
03732                          "sinfo_fitLines: %d", n_fit) ;
03733          return NULL ;
03734      }
03735 
03736      /* first check for faked lines like bad pixels */
03737      if ( -1 == sinfo_new_check_for_fake_lines (par, 
03738                                                 dispersion, 
03739                                                 wavelength_clean, 
03740                                                 row_clean, 
03741                                                 n_found_lines,
03742                                                 ilx, 
03743                                                 pixel_tolerance) )
03744      {
03745          sinfo_msg_error(" cannot fit the lines, error code of "
03746                          " sinfo_fitLines: %d\n", n_fit) ;
03747          return NULL ;
03748      }
03749 
03750 
03751      /* allocate memory */
03752      if (NULL==(acoefs = (float*) cpl_calloc (n_a_fitcoefs, sizeof(float))) ||
03753          NULL==(dacoefs = (float*) cpl_calloc (n_a_fitcoefs, sizeof(float))) ||
03754          NULL==(dabuf = (float**) cpl_calloc (n_a_fitcoefs, sizeof(float*))) ||
03755          NULL==(chisq_cross = (float*) cpl_calloc(n_slitlets, sizeof(float))) )
03756      {
03757          sinfo_msg_error(" cannot allocate memory\n") ;
03758          return NULL ;
03759      }
03760      for ( i = 0 ; i < n_a_fitcoefs ; i++ )
03761      {
03762          if (  NULL == (dabuf[i] = (float*) cpl_calloc(ilx, sizeof(float))) )
03763          {
03764              sinfo_msg_error(" cannot allocate memory\n") ;
03765              cpl_free ( acoefs ) ;
03766              cpl_free ( dacoefs ) ;
03767              cpl_free ( chisq_cross ) ;
03768              cpl_free(dabuf) ;
03769              return NULL ;
03770          }
03771      }
03772 
03773      /* fit wavelengths to the corresponding found positions for each column */
03774      k = 0 ;
03775      for ( i = 0 ; i < ilx ; i++ )
03776      {
03777          zeroind = 0 ;
03778          if ( FLT_MAX == (chisq_poly = sinfo_new_polyfit( par, i, 
03779                                                          n_found_lines[i], 
03780                                                          ily, dispersion,
03781                                                          max_residual, acoefs,
03782                                                          dacoefs, &n_reject, 
03783                                                          n_a_fitcoefs)) )
03784          {
03785              sinfo_msg_warning (" error in sinfo_polyfit in column: %d\n", i) ;
03786              for ( j = 0 ; j < n_a_fitcoefs ; j++ )
03787              {
03788                  acoefs[j] = ZERO ;
03789                  dacoefs[j] = ZERO ;
03790              }
03791          }
03792 
03793          for ( j = 0 ; j < n_a_fitcoefs ; j++ )
03794          {
03795 
03796              if ( acoefs[0] <= 0. || acoefs[1] ==0. ||
03797                   dacoefs[j] == 0. || isnan(acoefs[j]) )
03798              {
03799                  zeroind = 1 ;
03800              }
03801          }
03802          for ( j = 0 ; j < n_a_fitcoefs ; j++ )
03803          {
03804              if ( zeroind == 0 )
03805              {
03806                  abuf[j][i]  = acoefs[j] ;
03807                  dabuf[j][i] = dacoefs[j] ;
03808              }
03809              else
03810              {
03811                  abuf[j][i]  = ZERO ;
03812                  dabuf[j][i] = ZERO ;
03813              }
03814          }
03815      }
03816 
03817      /* allocate memory for the fitting coefficients */
03818      if ( NULL == ( bco = sinfo_new_b_coeffs( n_slitlets, 
03819                                               n_a_fitcoefs, n_b_fitcoefs)) )
03820      {
03821          sinfo_msg_error (" cannot allocate memory for the bcoeffs\n") ;
03822          for ( i = 0 ; i < n_a_fitcoefs ; i++ )
03823          {
03824              cpl_free (dabuf[i]) ;
03825          }
03826          cpl_free (dabuf) ;
03827          cpl_free ( acoefs ) ;
03828          cpl_free ( dacoefs ) ;
03829          cpl_free ( chisq_cross ) ;
03830          return NULL ;
03831      }
03832 
03833      /* fit each acoefs across the slitlets to smooth the result */
03834      if ( -1 == ( crossInd = sinfo_new_spred_coeffs_cross_slit_fit( ilx, abuf, 
03835                                                                     dabuf,
03836                                                              bco, sigmaFactor,
03837                                                              dispersion, 
03838                                                              pixel_dist, 
03839                                                              chisq_cross,
03840                                                              sinfo_slit_pos )) )
03841      {
03842          sinfo_msg_error (" cannot carry out the fitting of "
03843                           "coefficients across the columns\n") ;
03844          for ( i = 0 ; i < n_a_fitcoefs ; i++ )
03845          {
03846              cpl_free (dabuf[i]) ;
03847          }
03848 
03849          cpl_free (dabuf) ;
03850          cpl_free ( acoefs ) ;
03851          cpl_free ( dacoefs ) ;
03852          sinfo_new_destroy_b_coeffs(bco) ;
03853          cpl_free ( chisq_cross ) ;
03854          return NULL ;
03855      }
03856 
03857      if ( NULL == (wavemap = sinfo_new_wave_map_slit (abuf, n_a_fitcoefs, 
03858                                                       ily, ilx)))
03859      {
03860          sinfo_msg_error (" cannot carry out wavemap creation\n") ;
03861          for ( i = 0 ; i < n_a_fitcoefs ; i++ )
03862          {
03863              cpl_free (dabuf[i]) ;
03864          }
03865 
03866          cpl_free (dabuf) ;
03867          cpl_free ( acoefs ) ;
03868          cpl_free ( dacoefs ) ;
03869          sinfo_new_destroy_b_coeffs(bco) ;
03870          cpl_free ( chisq_cross ) ;
03871          return NULL ;
03872      }
03873 
03874      /* free all allocated memory */
03875      for ( i = 0 ; i < n_a_fitcoefs ; i++ )
03876      {
03877          cpl_free (dabuf[i]) ;
03878      }
03879      cpl_free (dabuf) ;
03880      cpl_free ( acoefs ) ;
03881      cpl_free ( dacoefs ) ;
03882      sinfo_new_destroy_b_coeffs(bco) ;
03883      cpl_free ( chisq_cross ) ;
03884 
03885      return wavemap ;
03886  }
03887 
03889 /*___oOo___*/

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