CleanAll.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Jolien Creighton
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 /*----------------------------------------------------------------------- 
00021  * 
00022  * File Name: CleanAll.c
00023  * 
00024  * Author: Sintes, A. M.
00025  * 
00026  * Revision: $Id: 
00027  * 
00028  *----------------------------------------------------------------------- 
00029  * 
00030  * NAME 
00031  *  CleanAll.c
00032  * 
00033  * SYNOPSIS 
00034  *
00035  *
00036  * DESCRIPTION 
00037  *   Given the data and a reference signal, removes all the harmonics
00038  * 
00039  * DIAGNOSTICS 
00040  *
00041  * CALLS
00042  * 
00043  * NOTES
00044  * 
00045  *
00046  *-----------------------------------------------------------------------
00047  */
00048 
00049 
00050 /************************************ <lalVerbatim file="CleanAllCV">
00051 Author: Sintes, A. M. 
00052 $Id: CleanAll.c,v 1.3 2007/06/08 14:41:43 bema Exp $
00053 ************************************* </lalVerbatim> */
00054 
00055 
00056 /* <lalLaTeX>
00057 
00058 \subsection{Module \texttt{CleanAll.c}}
00059 \label{ss:CleanAll.c}
00060 Gets data cleaned from line harmonic interference given  a time domain
00061 reference signal.
00062 
00063 
00064 \subsubsection*{Prototypes}
00065 \vspace{0.1in}
00066 \input{CleanAllD}
00067 \idx{LALCleanAll()}
00068 
00069 \subsubsection*{Description}
00070 This routine cleans data in the time domain from line harmonic interference
00071 (from the first harmonic up to the Nyquist frequency). The inputs are:
00072 
00073 \verb@*in1@ the time domain data of type  \verb@REAL4TVectorCLR@, 
00074 containing also the interference fundamental frequency $f_0$ and the 
00075 sampling spacing. This information is needed in order to obtain 
00076 the total  number of harmonics contained in the data. 
00077 \begin{description}
00078 \item[\texttt{in1->length}] The number of elements in \texttt{in1->data} $=n$.
00079 \item[\texttt{in1->data}]   The (real) time domain data,  $x(t)$.
00080 \item[\texttt{in1->deltaT}] The sample spacing in seconds.
00081 \item[\texttt{in1->fLine}]  The interference fundamental frequency $f_0$ 
00082        (in Hz), e.g., 60 Hz.
00083 \end{description}
00084 
00085 \verb@*in2@ the time domain reference signal (a complex vector).
00086 \begin{description}
00087 \item[\texttt{in2->length}] The number of elements in 
00088             \texttt{in2->data} $=n$.
00089 \item[\texttt{in2->data}]    The $M(t)$ complex data.
00090 \end{description}
00091 
00092 The output \verb@*out@ is a real vector containing the clean data.
00093 \begin{description}
00094 \item[\texttt{out->length}] The number of elements in 
00095             \texttt{out->data} $=n$.
00096 \item[\texttt{out->data}]    The clean (real) time domain data.
00097 \end{description}
00098 
00099 \subsubsection*{Algorithm}
00100 It takes the reference signal $M(t)$ and, for all possible harmonics
00101 $j$ 
00102 ($j=1,\ldots,$\texttt{floor(1.0/fabs( 2.02* in1->deltaT * in1->fLine))} ),
00103 from the fundamental frequency up to the Nyquist frequency,
00104 constructs $M(t)^j$,  performs a least-squares fit, i.e., 
00105 minimizes the power $\vert x(t) -\rho_j M(t)^j\vert^2$ with
00106 respect to $\rho_j$, and  subtracts $\rho_j M(t)^j$ from the
00107 original data, $x(t)$.
00108 
00109 \subsubsection*{Uses}
00110 \begin{verbatim}
00111 LALDCreateVector()
00112 LALZCreateVector()
00113 LALDDestroyVector()
00114 LALZDestroyVector()
00115 \end{verbatim}
00116 
00117 \subsubsection*{Notes}
00118 
00119 \vfill{\footnotesize\input{CleanAllCV}}
00120 
00121 </lalLaTeX> */
00122 
00123 
00124 
00125 #include <lal/CLR.h>
00126 
00127 NRCSID (CLEANALLC, "$Id: CleanAll.c,v 1.3 2007/06/08 14:41:43 bema Exp $");
00128 
00129 /* <lalVerbatim file="CleanAllD"> */
00130 void LALCleanAll (LALStatus     *status,
00131                REAL4Vector      *out,  /* clean data */
00132                COMPLEX8Vector   *in2,  /* M(t), ref. interference */
00133                REAL4TVectorCLR  *in1)  /* x(t), data + information */
00134 { /* </lalVerbatim> */
00135 
00136   INT4    n;
00137   INT4    i,j;
00138   INT4    maxH;
00139 
00140 
00141   REAL4      *x;
00142   REAL4      *xc;
00143   COMPLEX8   *m;
00144 
00145   COMPLEX16  rho,rhon;
00146   REAL8      rhod;
00147   REAL8      mr,mi;
00148   REAL8      amj,phj;
00149    
00150   COMPLEX16Vector *mj    = NULL;
00151   REAL8Vector     *ampM2 = NULL;
00152   REAL8Vector     *phaM  = NULL;
00153     
00154 /* --------------------------------------------- */
00155 
00156   INITSTATUS (status, "LALCleanAll", CLEANALLC);
00157   ATTATCHSTATUSPTR (status); 
00158 
00159   /*   Make sure the arguments are not NULL: */ 
00160   ASSERT (out, status, CLRH_ENULL, CLRH_MSGENULL);
00161   ASSERT (in1, status, CLRH_ENULL, CLRH_MSGENULL);
00162   ASSERT (in2, status, CLRH_ENULL, CLRH_MSGENULL);
00163 
00164   /*   Make sure the data pointers are not NULL: */ 
00165   ASSERT (out->data, status, CLRH_ENULL, CLRH_MSGENULL);
00166   ASSERT (in1->data, status, CLRH_ENULL, CLRH_MSGENULL);
00167   ASSERT (in2->data, status, CLRH_ENULL, CLRH_MSGENULL);
00168 
00169   /*   Make sure that the size is correct:  */
00170   ASSERT (out->length > 0, status, CLRH_ESIZE, CLRH_MSGESIZE);
00171 
00172   /*   Make sure that the lengths are correct (size mismatch): */  
00173   ASSERT (in1->length == out->length, status, CLRH_ESZMM, CLRH_MSGESZMM);
00174   ASSERT (in2->length == out->length, status, CLRH_ESZMM, CLRH_MSGESZMM);
00175 
00176   /*   Make sure the arguments are not pointing to the same memory location */
00177   /*   ASSERT (out != in2, status, CLRH_ESAME, CLRH_MSGESAME); */
00178 
00179   /*   Make sure F_Nyquist > fLine  */
00180   ASSERT (fabs(in1->deltaT * in1->fLine) < 0.495,
00181                 status, CLRH_EFREQ, CLRH_MSGEFREQ);
00182 
00183   /* margin 0.495 and not 0.5 in order to avoid errors */
00184 
00185 
00186   /* -------------------------------------------   */
00187  
00188   n  = out->length;
00189   m  = in2->data;
00190   x  = in1->data;
00191   xc = out->data;
00192  
00193   /* -------------------------------------------   */
00194   /*     Removing the fundamental harmonic         */
00195   /* -------------------------------------------   */
00196  
00197   rhon.re = 0.0;
00198   rhon.im = 0.0;
00199   rhod    = 0.0;
00200 
00201   for (i=0; i<n; ++i) {
00202     mr = m[i].re;
00203     mi = m[i].im;
00204     
00205     rhon.re +=  x[i]*mr;
00206     rhon.im += -x[i]*mi;
00207     rhod    +=  mr*mr + mi*mi;
00208   }
00209 
00210   rho.re = rhon.re / rhod;
00211   rho.im = rhon.im / rhod;
00212   
00213   for (i=0; i<n; ++i) {
00214     xc[i] = x[i] - 2.0*(rho.re * m[i].re - rho.im * m[i].im );
00215   }
00216   
00217   
00218   /* -------------------------------------------   */
00219   /*     Removing the other harmonics              */
00220   /* -------------------------------------------   */
00221   
00222   maxH= floor(1.0/fabs( 2.02* in1->deltaT * in1->fLine));
00223   
00224   if (maxH > 1) /* in case there are more harmonics */
00225   {
00226 
00227     /* Create Vectors amplitude and phase m(t) */
00228     TRY(LALDCreateVector(status->statusPtr, &ampM2, n), status);
00229     TRY(LALDCreateVector(status->statusPtr, &phaM,  n), status);
00230     /* reserve space for m^j(t) */
00231     TRY(LALZCreateVector(status->statusPtr, &mj  ,n), status);
00232     
00233     for (i=0; i<n; ++i) {
00234       /* calculation of amplitude^2 and phase of m(t)  */
00235       mr = m[i].re;
00236       mi = m[i].im;
00237       
00238       ampM2->data[i] = mr*mr+ mi*mi;
00239       
00240       if( ampM2->data[i] < LAL_REAL4_MIN)
00241         {  phaM->data[i] = 0.0; /* to avoid NaN */ }
00242       else
00243         {  phaM->data[i] = atan2(mi,mr);  }
00244     }
00245     
00246     for(j=2; j<= maxH; ++j) {
00247       rhon.re = 0.0;
00248       rhon.im = 0.0;
00249       rhod    = 0.0;
00250       
00251       for (i=0; i<n; ++i) {
00252         /* calculation of m^j(t) for a fixed t */
00253         amj = pow( ampM2->data[i], 0.5*j);
00254         phj = j * phaM->data[i];
00255         mj->data[i].re = amj * cos(phj);
00256         mr =  mj->data[i].re;
00257         mj->data[i].im = amj * sin(phj);
00258         mi =  mj->data[i].im;
00259         
00260         rhon.re +=  xc[i]*mr;
00261         rhon.im += -xc[i]*mi;
00262         rhod    +=  mr*mr + mi*mi;
00263       }
00264       
00265       rho.re = rhon.re / rhod;
00266       rho.im = rhon.im / rhod;
00267       
00268      for (i=0; i<n; ++i) {
00269        xc[i] += - 2.0*(rho.re * mj->data[i].re - rho.im * mj->data[i].im );
00270      }
00271 
00272     } /* closes for all harmonics */
00273     
00274     /* Destroy Vectors  */
00275     TRY(LALDDestroyVector(status->statusPtr, &ampM2), status);
00276     TRY(LALDDestroyVector(status->statusPtr, &phaM), status);
00277     TRY(LALZDestroyVector(status->statusPtr, &mj), status);
00278     
00279   } /* closes if */
00280   
00281   /* -------------------------------------------   */
00282   
00283   DETATCHSTATUSPTR (status);
00284   
00285   /* normal exit */
00286   RETURN (status);
00287 }
00288 

Generated on Tue Oct 7 02:39:25 2008 for LAL by  doxygen 1.5.2