00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if 0
00021
00022 <lalVerbatim file="SpecBufferCV">
00023 $Id: SpecBuffer.c,v 1.12 2007/06/08 14:41:46 bema Exp $
00024 </lalVerbatim>
00025
00026 <lalLaTeX>
00027 \subsection{Module \texttt{SpecBuffer.c}}
00028 \label{ss:SpecBuffer.c}
00029
00030 Functions for root finding.
00031
00032 \subsubsection*{Prototypes}
00033 \vspace{0.1in}
00034 \idx{LALComputeSpectrum()}
00035 \idx{LALCreateSpectrumBuffer()}
00036 \idx{LALDestroySpectrumBuffer()}
00037 \idx{LALAddSpectrum()}
00038 \idx{LALAverageSpectrum()}
00039
00040 \input{SpecBufferCP}
00041
00042 \subsubsection*{Description}
00043
00044 The routine \texttt{LALComputeSpectrum()} computes the spectrum of a
00045 \texttt{INT2TimeSeries} to produce an \texttt{REAL4FrequencySeries} power
00046 spectrum. It requires parameters including the forward real FFT plan and an
00047 appropriate window. This routine is used by the routine
00048 \texttt{LALAddSpectrum()}.
00049
00050 The routine \texttt{LALCreateSpectrumBuffer()} creates a spectrum buffer. This
00051 requires a parameter input that specifies the number of points in each time
00052 series that will be used to construct the spectra, the number of spectra to
00053 store, the window type to be used when constructing the spectra, and the real
00054 FFT plan to be used. The spectrum buffer is destroyed using the routine
00055 \texttt{LALDestroySpectrumBuffer()}.
00056
00057 The routine \texttt{LALAddSpectrum()} adds the spectrum of time series data to a
00058 spectrum buffer. The routine \texttt{LALAverageSpectrum()} outputs the power
00059 spectrum frequency series consisting of the average of the (most recent)
00060 spectra that have been stored so far.
00061
00062 \subsubsection*{Operating Instructions}
00063
00064 \begin{verbatim}
00065 const UINT4 numSpec = 8;
00066 const UINT4 numPoints = 1024;
00067 static LALStatus status;
00068 static SpectrumBufferPar buffPar;
00069 static SpectrumBuffer buff;
00070 static INT2TimeSeries data;
00071 static REAL4FrequencySeries spec;
00072
00073 UINT4 i;
00074
00075 buffPar.numSpec = numSpec;
00076 buffPar.numPoints = numPoints;
00077 buffPar.windowType = Welch;
00078 LALCreateForwardRealFFTPlan( &status, &buffPar.plan, numPoints, 0 );
00079 LALCreateSpectrumBuffer( &status, &buff, &buffPar );
00080 LALI2CreateVector( &status, &data.data, numPoints );
00081 LALSCreateVector( &status, &spec.data, numPoints/2 + 1 );
00082
00083 for ( i = 0; i < numSpec; ++i )
00084 {
00085
00086
00087
00088 LALAddSpectrum (&status, buff, &data);
00089 }
00090
00091 LALAverageSpectrum( &status, &spec, buff );
00092
00093
00094
00095 LALSDestroyVector( &status, &spec.data );
00096 LALI2DestroyVector( &status, &data.data );
00097 LALDestroySpectrumBuffer( &status, &buff );
00098 LALDestroyRealFFTPlan( &status, &buffPar.plan );
00099 \end{verbatim}
00100
00101 \subsubsection*{Algorithm}
00102
00103 \subsubsection*{Uses}
00104
00105 \subsubsection*{Notes}
00106 \vfill{\footnotesize\input{SpecBufferCV}}
00107
00108 </lalLaTeX>
00109
00110 #endif
00111
00112
00113 #include <math.h>
00114 #include <lal/LALStdlib.h>
00115 #include <lal/AVFactories.h>
00116 #include <lal/RealFFT.h>
00117 #include <lal/Window.h>
00118 #include <lal/VectorOps.h>
00119 #include <lal/SpecBuffer.h>
00120
00121 NRCSID (SPECBUFFERC, "$Id: SpecBuffer.c,v 1.12 2007/06/08 14:41:46 bema Exp $");
00122
00123
00124 void
00125 LALComputeSpectrum (
00126 LALStatus *status,
00127 REAL4FrequencySeries *spectrum,
00128 INT2TimeSeries *timeSeries,
00129 ComputeSpectrumPar *parameters
00130 )
00131 {
00132 REAL4Vector *tmp = NULL;
00133 REAL4 fac;
00134 UINT4 i;
00135 UINT4 n;
00136
00137 INITSTATUS (status, "LALComputeSpectrum", SPECBUFFERC);
00138 ATTATCHSTATUSPTR (status);
00139
00140
00141 ASSERT (spectrum, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00142 ASSERT (timeSeries, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00143 ASSERT (parameters, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00144
00145
00146 n = timeSeries->data->length;
00147 ASSERT (n > 0, status, SPECBUFFERH_ESIZE, SPECBUFFERH_MSGESIZE);
00148 ASSERT (spectrum->data->length == n/2 + 1, status,
00149 SPECBUFFERH_ESZMM, SPECBUFFERH_MSGESZMM);
00150 ASSERT (parameters->window->length == n, status,
00151 SPECBUFFERH_ESZMM, SPECBUFFERH_MSGESZMM);
00152
00153
00154 LALCreateVector (status->statusPtr, &tmp, timeSeries->data->length);
00155 CHECKSTATUSPTR (status);
00156
00157 spectrum->epoch = timeSeries->epoch;
00158 spectrum->f0 = timeSeries->f0;
00159
00160
00161 ASSERT (timeSeries->deltaT, status, SPECBUFFERH_EZERO, SPECBUFFERH_MSGEZERO);
00162 ASSERT (parameters->wss, status, SPECBUFFERH_EZERO, SPECBUFFERH_MSGEZERO);
00163 spectrum->deltaF = 1/(timeSeries->deltaT*timeSeries->data->length);
00164 fac = sqrt( timeSeries->deltaT/parameters->wss );
00165
00166 for (i = 0; i < n; ++i)
00167 {
00168 tmp->data[i] = fac*timeSeries->data->data[i]*parameters->window->data[i];
00169 }
00170
00171 LALRealPowerSpectrum (status->statusPtr, spectrum->data, tmp, parameters->plan);
00172 CHECKSTATUSPTR (status);
00173
00174 LALDestroyVector (status->statusPtr, &tmp);
00175 CHECKSTATUSPTR (status);
00176
00177
00178 DETATCHSTATUSPTR (status);
00179 RETURN (status);
00180 }
00181
00182
00183
00184 void
00185 LALCreateSpectrumBuffer (
00186 LALStatus *status,
00187 SpectrumBuffer **buffer,
00188 SpectrumBufferPar *params
00189 )
00190 {
00191 LALWindowParams winparams;
00192 INT4 specSize;
00193 INT4 spec;
00194
00195 INITSTATUS (status, "LALCreateSpectrumBuffer", SPECBUFFERC);
00196 ATTATCHSTATUSPTR (status);
00197
00198
00199 ASSERT (buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00200 ASSERT (params, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00201
00202
00203 ASSERT (*buffer == NULL, status, SPECBUFFERH_ENNUL, SPECBUFFERH_MSGENNUL);
00204
00205
00206 ASSERT (params->numSpec > 0, status, SPECBUFFERH_ESIZE, SPECBUFFERH_MSGESIZE);
00207 ASSERT (params->numPoints > 0, status, SPECBUFFERH_ESIZE, SPECBUFFERH_MSGESIZE);
00208 ASSERT (params->plan, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00209
00210 specSize = params->numPoints/2 + 1;
00211
00212
00213 *buffer = (SpectrumBuffer *) LALMalloc (sizeof (SpectrumBuffer));
00214
00215
00216 ASSERT (*buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00217
00218
00219 (*buffer)->numSpec = params->numSpec;
00220 (*buffer)->specBuffer = (REAL4FrequencySeries *)
00221 LALMalloc (params->numSpec*sizeof(REAL4FrequencySeries));
00222
00223 ASSERT ((*buffer)->specBuffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00224
00225 (*buffer)->specParams = (ComputeSpectrumPar *)
00226 LALMalloc (sizeof (ComputeSpectrumPar));
00227
00228 ASSERT ((*buffer)->specBuffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00229
00230
00231 for (spec = 0; spec < params->numSpec; ++spec)
00232 {
00233 REAL4FrequencySeries *thisSpec = (*buffer)->specBuffer + spec;
00234
00235 thisSpec->data = NULL;
00236 LALCreateVector (status->statusPtr, &thisSpec->data, specSize);
00237 CHECKSTATUSPTR (status);
00238 }
00239
00240
00241 (*buffer)->specParams->window = NULL;
00242 LALCreateVector (
00243 status->statusPtr,
00244 &(*buffer)->specParams->window,
00245 params->numPoints
00246 );
00247 CHECKSTATUSPTR (status);
00248
00249 winparams.length = params->numPoints;
00250 winparams.type = params->windowType;
00251 LALWindow (status->statusPtr, (*buffer)->specParams->window, &winparams);
00252 CHECKSTATUSPTR (status);
00253 (*buffer)->specParams->windowType = winparams.type;
00254 (*buffer)->specParams->wss = winparams.sumofsquares;
00255 (*buffer)->specParams->plan = params->plan;
00256
00257
00258 (*buffer)->specFilled = 0;
00259
00260
00261 DETATCHSTATUSPTR (status);
00262 RETURN (status);
00263 }
00264
00265
00266
00267 void
00268 LALDestroySpectrumBuffer (
00269 LALStatus *status,
00270 SpectrumBuffer **buffer
00271 )
00272 {
00273 INT4 spec;
00274
00275 INITSTATUS (status, "LALDestroySpectrumBuffer", SPECBUFFERC);
00276 ATTATCHSTATUSPTR (status);
00277
00278
00279 ASSERT (buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00280 ASSERT (*buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00281
00282
00283 for (spec = 0; spec < (*buffer)->numSpec; ++spec)
00284 {
00285 REAL4FrequencySeries *thisSpec = (*buffer)->specBuffer + spec;
00286 LALDestroyVector (status->statusPtr, &thisSpec->data);
00287 CHECKSTATUSPTR (status);
00288 }
00289
00290 LALFree ((*buffer)->specBuffer);
00291
00292
00293 LALDestroyVector (status->statusPtr, &(*buffer)->specParams->window);
00294 CHECKSTATUSPTR (status);
00295
00296 LALFree ((*buffer)->specParams);
00297
00298 LALFree (*buffer);
00299 *buffer = NULL;
00300
00301
00302 DETATCHSTATUSPTR (status);
00303 RETURN (status);
00304 }
00305
00306
00307
00308 void
00309 LALAddSpectrum (
00310 LALStatus *status,
00311 SpectrumBuffer *specBuffer,
00312 INT2TimeSeries *timeSeries
00313 )
00314 {
00315 INT4 whichSpec;
00316
00317 INITSTATUS (status, "LALAddSpectrum", SPECBUFFERC);
00318 ATTATCHSTATUSPTR (status);
00319
00320
00321 ASSERT (specBuffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00322 ASSERT (timeSeries, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00323
00324
00325 whichSpec = specBuffer->specFilled % specBuffer->numSpec;
00326
00327
00328 LALComputeSpectrum (
00329 status->statusPtr,
00330 specBuffer->specBuffer + whichSpec,
00331 timeSeries,
00332 specBuffer->specParams
00333 );
00334 CHECKSTATUSPTR (status);
00335
00336 ++(specBuffer->specFilled);
00337
00338
00339 DETATCHSTATUSPTR (status);
00340 RETURN (status);
00341 }
00342
00343
00344
00345 void
00346 LALAverageSpectrum (
00347 LALStatus *status,
00348 REAL4FrequencySeries *spectrum,
00349 SpectrumBuffer *buffer
00350 )
00351 {
00352 UINT4 i;
00353 INT4 spec;
00354 INT4 nspec;
00355 REAL4 fac;
00356
00357 INITSTATUS (status, "LALAverageSpectrum", SPECBUFFERC);
00358
00359
00360 ASSERT (spectrum, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00361 ASSERT (buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00362
00363
00364 ASSERT (spectrum->data, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00365 ASSERT (spectrum->data->data, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00366 ASSERT (buffer->specBuffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00367 ASSERT (buffer->specParams, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00368
00369 if (buffer->specFilled > buffer->numSpec)
00370 nspec = buffer->numSpec;
00371 else
00372 nspec = buffer->specFilled;
00373
00374 ASSERT (nspec, status, SPECBUFFERH_ENONE, SPECBUFFERH_MSGENONE);
00375 ASSERT (spectrum->data->length > 0, status,
00376 SPECBUFFERH_ESIZE, SPECBUFFERH_MSGESIZE);
00377
00378 fac = 1/(REAL4)nspec;
00379 for (spec = 0; spec < nspec; ++spec)
00380 {
00381 REAL4FrequencySeries *thisSpec = buffer->specBuffer + spec;
00382
00383 ASSERT (thisSpec->data, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00384 ASSERT (thisSpec->data->data, status,
00385 SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00386 ASSERT (thisSpec->data->length == spectrum->data->length, status,
00387 SPECBUFFERH_ESZMM, SPECBUFFERH_MSGESZMM);
00388 for (i = 0; i < spectrum->data->length; ++i)
00389 if (spec == 0)
00390 spectrum->data->data[i] = thisSpec->data->data[i];
00391 else
00392 spectrum->data->data[i] += thisSpec->data->data[i];
00393 }
00394
00395 for (i = 0; i < spectrum->data->length; ++i)
00396 spectrum->data->data[i] *= fac;
00397
00398 spectrum->deltaF = buffer->specBuffer->deltaF;
00399 spectrum->f0 = buffer->specBuffer->f0;
00400
00401
00402 RETURN (status);
00403 }