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

Generated on 8 Mar 2011 for SINFONI Pipeline Reference Manual by  doxygen 1.6.1