LALInspiralWaveTaper.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 David McKechan, Thomas Cokelaer
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 /*  <lalVerbatim file="LALInspiralWaveTaperCV">
00021  *  Author:  McKechan D J A
00022  *  </lalVerbatim>  */
00023 
00024 /*  <lalLaTeX>
00025  *
00026  *  \subsection{Module \texttt{LALInspiralWaveTaper.c} }
00027  *
00028  *  The code \texttt{LALInspiralWaveTaper} imposes a smooth time tapering at
00029  *  the beginning and/or the end of waves in the time domain. 
00030  *
00031  *  It takes in a Real4Vector and searches for the beginning and end points 
00032  *  of the signal, in case there are null data points at either end. It then
00033  *  tapers the wave from the ends to the second maxima from each end 
00034  *  in the waveform, according to formula 3.35 of gr-qc/0001023.
00035  *
00036  *  If the waveform does has less than 4 maxima,  such that it cannot be tapered
00037  *  from the each end to the second peak then the waveform is tapered from the 
00038  *  ends to the centre of the instead.
00039  *
00040  *  The bookends option allows the user to specify whether just the start, 
00041  *  just the end or both the start and end of the signal are tapered. 
00042  *  This corresponds to bookends = 1, 2 or 3 respectively. If bookends does 
00043  *  not equal 1, 2 or 3 then option 3 is assumed.
00044  *
00045  *  The function \texttt{XLALInspiralWaveTaper} is the XLAL version of the code
00046  *  described above. In this case, instead of passing an integer to give the tapering
00047  *  method, we use one of the options in the \texttt{InspiralApplyTaper} enumeration.
00048  *  These options are \texttt{INSPIRAL\_TAPER\_START}, \texttt{INSPIRAL\_TAPER\_END}
00049  *  and \texttt{INSPIRAL\_TAPER\_BOTH}.
00050  *
00051  *  \subsubsection*{Prototypes}
00052  *  \vspace{0.1in}
00053  *  \input{LALInspiralWaveTaperCP}
00054  *  \index{\verb&LALInspiralWaveTaper()&}
00055  *
00056  *  \subsubsection*{Description}
00057  *
00058  *
00059  *  \subsubsection*{Uses}
00060  *
00061  *   
00062  *
00063  *   \subsubsection*{Notes}
00064  *
00065  *   \vfill{\footnotesize\input{LALInspiralWaveTaperCV}}
00066  *
00067  *   </lalLaTeX>  */
00068 
00069 #include <lal/LALInspiral.h>
00070 #include <stdio.h>
00071 #include <math.h>
00072 
00073 NRCSID(LALINSPIRALWAVETAPERC, 
00074                   "$Id: LALInspiralWaveTaper.c,v 1.11 2008/09/21 07:29:01 mckechan Exp $"); 
00075 
00076 
00077 /*  <lalVerbatim file="LALInspiralWaveTaperCP"> */
00078 void LALInspiralWaveTaper(
00079                    LALStatus   *status,
00080                    REAL4Vector *signal,
00081                    UINT4       bookends)
00082 { /* </lalVerbatim>  */
00083 
00084   InspiralApplyTaper taperType;
00085 
00086   INITSTATUS(status, "LALInspiralWaveTaper",LALINSPIRALWAVETAPERC);
00087 
00088   XLALPrintDeprecationWarning( "LALInspiralWaveTaper", "XLALInspiralWaveTaper" );
00089 
00090   if ( bookends == 0 )
00091   {
00092     /* No taper specified */
00093     LALWarning( status, "No taper specified; not tapering" );
00094     RETURN( status );
00095   }
00096   else if ( bookends == 1 )
00097   {
00098     taperType = INSPIRAL_TAPER_START;
00099   }
00100   else if ( bookends == 2 )
00101   {
00102     taperType = INSPIRAL_TAPER_END;
00103   }
00104   else if ( bookends == 3 )
00105   {
00106     taperType = INSPIRAL_TAPER_BOTH;
00107   }
00108   else
00109   {
00110     ABORT( status, LALINSPIRALH_ECHOICE, LALINSPIRALH_MSGECHOICE );
00111   }
00112 
00113   if ( XLALInspiralWaveTaper( signal, taperType ) == XLAL_FAILURE )
00114   {
00115     ABORTXLAL( status );
00116   }
00117 
00118   RETURN( status );
00119 }
00120 
00121 /*  <lalVerbatim file="LALInspiralWaveTaperCP"> */
00122 int XLALInspiralWaveTaper(
00123                    REAL4Vector         *signal,
00124                    InspiralApplyTaper  bookends)
00125 { /* </lalVerbatim>  */
00126  
00127   const static char *func = "XLALInspiralWaveTaper";
00128 
00129   UINT4 i, start, end, mid, n; /* indices */
00130   UINT4 flag, safe = 1;
00131   UINT4 length;   
00132   REAL4 z, sigma;          
00133   REAL4 realN, realI;  /* REAL4 values of n & i used for the calculations */
00134 
00135 #ifndef LAL_NDEBUG
00136   if ( !signal )
00137     XLAL_ERROR( func, XLAL_EFAULT );
00138 
00139   if ( !signal->data )
00140     XLAL_ERROR( func, XLAL_EFAULT );
00141 #endif
00142 
00143   /* Check we have chosen a valid tapering method */
00144   if ( (UINT4) bookends >= (UINT4) INSPIRAL_TAPER_NUM_OPTS )
00145     XLAL_ERROR( func, XLAL_EINVAL );
00146 
00147   length = signal->length;
00148 
00149   if( bookends == INSPIRAL_TAPER_NONE )    
00150   {
00151     XLALPrintWarning( "No taper specified; not tapering.\n" );
00152     return XLAL_SUCCESS;
00153   }
00154   
00155   /* Search for start and end of signal */
00156   flag = 0;
00157   i = 0;
00158   while(flag == 0 && i < length )
00159   {
00160     if( signal->data[i] != 0.)
00161     {
00162       start = i;
00163       flag = 1;
00164     }
00165     i++;
00166   }  
00167   if ( flag == 0 )
00168   {
00169     XLALPrintWarning( "No signal found in the vector. Cannot taper.\n" );
00170     return XLAL_SUCCESS;
00171   }
00172     
00173   flag = 0;
00174   i = length - 1;
00175   while(flag == 0)
00176   {
00177     if( signal->data[i] != 0.)
00178     {
00179       end = i;
00180       flag = 1;
00181     }
00182     i--;
00183   }        
00184   
00185 
00186   /* Check we have more than 2 data points */
00187   if((end - start) <= 1)
00188   {
00189     XLALPrintWarning( "Data less than 3 points, cannot taper!\n" );
00190     safe = 0;
00191   }
00192 
00193   if( safe == 1)
00194   {
00195     /* Calculate middle point in case of short waveform */    
00196     mid = (start+end)/2;
00197 
00198     /* If requested search for second peak from start and taper */
00199     if( bookends != INSPIRAL_TAPER_END )
00200     {
00201       flag = 0;
00202       i = start+1;
00203       while( flag < 2 && i != mid)
00204       {
00205         if( fabs(signal->data[i]) >= fabs(signal->data[i-1]) )
00206           if( fabs(signal->data[i]) >= fabs(signal->data[i+1]) )
00207           {
00208             if( fabs(signal->data[i]) == fabs(signal->data[i+1]) )
00209               i++;
00210             flag++;
00211             n = i - start;
00212           }
00213         i++;
00214       }
00215       /* Have we reached the middle? */
00216       if( flag < 2)
00217         n = mid - start;
00218 
00219       /* Taper to that point */
00220       realN = (REAL4)(n);
00221       signal->data[start] = 0.0;
00222       for(i=start+1; i < start + n - 1; i++)
00223       {
00224         realI = (REAL4)(i - start);
00225         z = (realN - 1.0)/realI + (realN - 1.0)/(realI - (realN - 1.0));
00226         sigma = 1.0/(exp(z) + 1.0);
00227         signal->data[i] = signal->data[i]*sigma;
00228       }
00229     }     
00230   
00231     /* If requested search for second peak from end */
00232     if( bookends == INSPIRAL_TAPER_END || bookends == INSPIRAL_TAPER_BOTH )
00233     {    
00234       i = end - 1;
00235       flag = 0;
00236       while( flag < 2 && i != mid )
00237       {
00238         if( fabs(signal->data[i]) >= fabs(signal->data[i+1]) )
00239           if( fabs(signal->data[i]) >= fabs(signal->data[i-1]) )
00240           {
00241             if( fabs(signal->data[i]) == fabs(signal->data[i-1]) )
00242               i--;
00243             flag++;
00244             n = end - i;
00245           }
00246         i--;
00247       }     
00248       /* Have we reached the middle? */
00249       if( flag < 2)
00250       {
00251         n = end - mid;
00252       }
00253 
00254       /* Taper to that point */
00255       realN = (REAL4)(n);
00256       signal->data[end] = 0.0;   
00257       for(i=end-1; i > end-n+1; i--)
00258       {
00259         realI = (REAL4)(end - i);
00260         z = (realN - 1.0)/realI + (realN - 1.0)/(realI - (realN-1.0));
00261         sigma = 1.0/(exp(z) + 1.0);
00262         signal->data[i] = signal->data[i]*sigma;
00263       }
00264     }
00265   }
00266 
00267   return XLAL_SUCCESS;
00268 }
00269 
00270 

Generated on Mon Oct 6 02:31:47 2008 for LAL by  doxygen 1.5.2