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, &M2, 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, &M2), 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
1.5.2