sinfo_resampling.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    
00021    File name     :    resampling.c
00022    Author         :    Nicolas Devillard
00023    Created on    :    Jan 04, 1996
00024    Description    :    resampling routines
00025 
00026  ---------------------------------------------------------------------------*/
00027 
00028 /*
00029     $Id: sinfo_resampling.c,v 1.5 2007/06/06 07:10:45 amodigli Exp $
00030     $Author: amodigli $
00031     $Date: 2007/06/06 07:10:45 $
00032     $Revision: 1.5 $
00033  */
00034 
00035 #ifdef HAVE_CONFIG_H
00036 #  include <config.h>
00037 #endif
00038 /*---------------------------------------------------------------------------
00039                                   Includes
00040  ---------------------------------------------------------------------------*/
00041 #include <string.h>
00042 #include "sinfo_resampling.h"
00043 #include <math.h>
00044 #include "sinfo_globals.h"
00045 /*---------------------------------------------------------------------------
00046                               Private functions
00047  ---------------------------------------------------------------------------*/
00048 static void reverse_tanh_kernel(double * data, int nn) ;
00049 static double * sinfo_generate_tanh_kernel(double steep);
00050 
00060 /*---------------------------------------------------------------------------
00061                               Function codes
00062  ---------------------------------------------------------------------------*/
00063 
00088 double   *
00089 sinfo_generate_interpolation_kernel(const char * kernel_type)
00090 {
00091     double  *    tab ;
00092     int         i ;
00093     double      x ;
00094     double        alpha ;
00095     double        inv_norm ;
00096     int         samples = KERNEL_SAMPLES ;
00097 
00098     if (kernel_type==NULL) {
00099         tab = sinfo_generate_interpolation_kernel("tanh") ;
00100     } else if (!strcmp(kernel_type, "default")) {
00101         tab = sinfo_generate_interpolation_kernel("tanh") ;
00102     } else if (!strcmp(kernel_type, "sinc")) {
00103         tab = cpl_malloc(samples * sizeof(double)) ;
00104         tab[0] = 1.0 ;
00105         tab[samples-1] = 0.0 ;
00106         for (i=1 ; i<samples ; i++) {
00107             x = (double)KERNEL_WIDTH * (double)i/(double)(samples-1) ;
00108             tab[i] = sinfo_sinc(x) ;
00109         }
00110     } else if (!strcmp(kernel_type, "sinc2")) {
00111         tab = cpl_malloc(samples * sizeof(double)) ;
00112         tab[0] = 1.0 ;
00113         tab[samples-1] = 0.0 ;
00114         for (i=1 ; i<samples ; i++) {
00115             x = 2.0 * (double)i/(double)(samples-1) ;
00116             tab[i] = sinfo_sinc(x) ;
00117             tab[i] *= tab[i] ;
00118         }
00119     } else if (!strcmp(kernel_type, "lanczos")) {
00120         tab = cpl_malloc(samples * sizeof(double)) ;
00121         for (i=0 ; i<samples ; i++) {
00122             x = (double)KERNEL_WIDTH * (double)i/(double)(samples-1) ;
00123             if (fabs(x)<2) {
00124                 tab[i] = sinfo_sinc(x) * sinfo_sinc(x/2) ;
00125             } else {
00126                 tab[i] = 0.00 ;
00127             }
00128         }
00129     } else if (!strcmp(kernel_type, "hamming")) {
00130         tab = cpl_malloc(samples * sizeof(double)) ;
00131         alpha = 0.54 ;
00132         inv_norm  = 1.00 / (double)(samples - 1) ;
00133         for (i=0 ; i<samples ; i++) {
00134             x = (double)i ;
00135             if (i<(samples-1)/2) {
00136                 tab[i] = alpha + (1-alpha) * cos(2.0*PI_NUMB*x*inv_norm) ;
00137             } else {
00138                 tab[i] = 0.0 ;
00139             }
00140         }
00141     } else if (!strcmp(kernel_type, "hann")) {
00142         tab = cpl_malloc(samples * sizeof(double)) ;
00143         alpha = 0.50 ;
00144         inv_norm  = 1.00 / (double)(samples - 1) ;
00145         for (i=0 ; i<samples ; i++) {
00146             x = (double)i ;
00147             if (i<(samples-1)/2) {
00148                 tab[i] = alpha + (1-alpha) * cos(2.0*PI_NUMB*x*inv_norm) ;
00149             } else {
00150                 tab[i] = 0.0 ;
00151             }
00152         }
00153     } else if (!strcmp(kernel_type, "tanh")) {
00154         tab = sinfo_generate_tanh_kernel(TANH_STEEPNESS) ;
00155     } else {
00156         sinfo_msg_error("unrecognized kernel type [%s]: aborting generation",
00157                 kernel_type) ;
00158         return NULL ;
00159     }
00160 
00161     return tab ;
00162 }
00163 
00175 double
00176 sinfo_sinc(double x)
00177 {
00178     if (fabs(x)<1e-4)
00179         return (double)1.00 ;
00180     else
00181         return ((sin(x * (double)PI_NUMB)) / (x * (double)PI_NUMB)) ;
00182 }
00183 
00205 #define hk_gen(x,s) (((tanh(s*(x+0.5))+1)/2)*((tanh(s*(-x+0.5))+1)/2))
00206 
00207 static double * 
00208 sinfo_generate_tanh_kernel(double steep)
00209 {
00210     double  *   kernel ;
00211     double  *   x ;
00212     double      width ;
00213     double      inv_np ;
00214     double      ind ;
00215     int         i ;
00216     int         np ;
00217     int         samples ;
00218 
00219     width   = (double)TABSPERPIX / 2.0 ; 
00220     samples = KERNEL_SAMPLES ;
00221     np      = 32768 ; /* Hardcoded: should never be changed */
00222     inv_np  = 1.00 / (double)np ;
00223 
00224     /*
00225      * Generate the kernel expression in Fourier space
00226      * with a correct frequency ordering to allow standard FT
00227      */
00228     x = cpl_malloc((2*np+1)*sizeof(double)) ;
00229     for (i=0 ; i<np/2 ; i++) {
00230         ind      = (double)i * 2.0 * width * inv_np ;
00231         x[2*i]   = hk_gen(ind, steep) ;
00232         x[2*i+1] = 0.00 ;
00233     }
00234     for (i=np/2 ; i<np ; i++) {
00235         ind      = (double)(i-np) * 2.0 * width * inv_np ;
00236         x[2*i]   = hk_gen(ind, steep) ;
00237         x[2*i+1] = 0.00 ;
00238     }
00239 
00240     /* 
00241      * Reverse Fourier to come back to image space
00242      */
00243     reverse_tanh_kernel(x, np) ;
00244 
00245     /*
00246      * Allocate and fill in returned array
00247      */
00248     kernel = cpl_malloc(samples * sizeof(double)) ;
00249     for (i=0 ; i<samples ; i++) {
00250         kernel[i] = 2.0 * width * x[2*i] * inv_np ;
00251     }
00252     cpl_free(x) ;
00253     return kernel ;
00254 }
00255 
00268 #define KERNEL_SW(a,b) tempr=(a);(a)=(b);(b)=tempr
00269 static void 
00270 reverse_tanh_kernel(double * data, int nn)
00271 {
00272     unsigned long   n,
00273                     mmax,
00274                     m,
00275                     i, j,
00276                     istep ;
00277     double  wtemp,
00278             wr,
00279             wpr,
00280             wpi,
00281             wi,
00282             theta;
00283     double  tempr,
00284             tempi;
00285 
00286     n = (unsigned long)nn << 1;
00287     j = 1;
00288     for (i=1 ; i<n ; i+=2) {
00289         if (j > i) {
00290             KERNEL_SW(data[j-1],data[i-1]);
00291             KERNEL_SW(data[j],data[i]);
00292         }
00293         m = n >> 1;
00294         while (m>=2 && j>m) {
00295             j -= m;
00296             m >>= 1;
00297         }
00298         j += m;
00299     }
00300     mmax = 2;
00301     while (n > mmax) {
00302         istep = mmax << 1;
00303         theta = 2 * PI_NUMB / mmax;
00304         wtemp = sin(0.5 * theta);
00305         wpr = -2.0 * wtemp * wtemp;
00306         wpi = sin(theta);
00307         wr  = 1.0;
00308         wi  = 0.0;
00309         for (m=1 ; m<mmax ; m+=2) {
00310             for (i=m ; i<=n ; i+=istep) {
00311                 j = i + mmax;
00312                 tempr = wr * data[j-1] - wi * data[j];
00313                 tempi = wr * data[j]   + wi * data[j-1];
00314                 data[j-1] = data[i-1] - tempr;
00315                 data[j]   = data[i]   - tempi;
00316                 data[i-1] += tempr;
00317                 data[i]   += tempi;
00318             }
00319             wr = (wtemp = wr) * wpr - wi * wpi + wr;
00320             wi = wi * wpr + wtemp * wpi + wi;
00321         }
00322         mmax = istep;
00323     }
00324 }
00325 #undef KERNEL_SW
00326 
00364 double *
00365 sinfo_invert_linear_transform(double *trans)
00366 {
00367     double   *    i_trans ;
00368     double       det ;
00369 
00370     if (trans==NULL) return NULL ;
00371     det = (trans[0] * trans[4]) - (trans[1] * trans[3]) ;
00372     if (fabs(det) < 1e-6) {
00373         sinfo_msg_error("NULL determinant: cannot sinfo_invert transform") ;
00374         return NULL ;
00375     }
00376 
00377     i_trans = cpl_calloc(6, sizeof(double)) ;
00378 
00379     i_trans[0] =  trans[4] / det ; 
00380     i_trans[1] = -trans[1] / det ;
00381     i_trans[2] = ((trans[1] * trans[5]) - (trans[2] * trans[4])) / det ;
00382     i_trans[3] = -trans[3] / det ;
00383     i_trans[4] =  trans[0] / det ;
00384     i_trans[5] = ((trans[2] * trans[3]) - (trans[0] * trans[5])) / det ;
00385 
00386     return i_trans ;
00387 }

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