SpecBuffer.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 #if 0  /* autodoc block */
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   /* get data here; break out if end of data */
00087 
00088   LALAddSpectrum (&status, buff, &data);
00089 }
00090 
00091 LALAverageSpectrum( &status, &spec, buff );
00092 
00093 /* do something with the spectrum */
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 /* autodoc block */
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 /* <lalVerbatim file="SpecBufferCP"> */
00124 void
00125 LALComputeSpectrum (
00126     LALStatus            *status,
00127     REAL4FrequencySeries *spectrum,
00128     INT2TimeSeries       *timeSeries,
00129     ComputeSpectrumPar   *parameters
00130     )
00131 { /* </lalVerbatim> */
00132   REAL4Vector *tmp = NULL;
00133   REAL4        fac;
00134   UINT4        i;
00135   UINT4        n;
00136 
00137   INITSTATUS (status, "LALComputeSpectrum", SPECBUFFERC);
00138   ATTATCHSTATUSPTR (status);
00139 
00140   /* make sure that arguments are not NULL */
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   /* make sure sizes are reasonable and agree */
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   /* create temporary vector */
00154   LALCreateVector (status->statusPtr, &tmp, timeSeries->data->length);
00155   CHECKSTATUSPTR (status);
00156 
00157   spectrum->epoch = timeSeries->epoch;
00158   spectrum->f0    = timeSeries->f0;
00159 
00160   /* make sure that these do not divide by zero... */
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   /* normal exit */
00178   DETATCHSTATUSPTR (status);
00179   RETURN (status);
00180 }
00181 
00182 
00183 /* <lalVerbatim file="SpecBufferCP"> */
00184 void
00185 LALCreateSpectrumBuffer (
00186     LALStatus          *status,
00187     SpectrumBuffer    **buffer,
00188     SpectrumBufferPar  *params
00189     )
00190 { /* </lalVerbatim> */
00191   LALWindowParams winparams;
00192   INT4 specSize;
00193   INT4 spec;
00194 
00195   INITSTATUS (status, "LALCreateSpectrumBuffer", SPECBUFFERC);
00196   ATTATCHSTATUSPTR (status);
00197 
00198   /* make sure that arguments are not NULL */
00199   ASSERT (buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00200   ASSERT (params, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00201 
00202   /* make sure that buffer does not exist */
00203   ASSERT (*buffer == NULL, status, SPECBUFFERH_ENNUL, SPECBUFFERH_MSGENNUL);
00204   
00205   /* make sure that parameters are reasonable */
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   /* assign memory for buffer */
00213   *buffer = (SpectrumBuffer *) LALMalloc (sizeof (SpectrumBuffer));
00214 
00215   /* make sure that the allocation was successful */
00216   ASSERT (*buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00217 
00218   /* assign memory for buffer fields */
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   /* allocate memory for spectra */
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   /* create window and assign specParams fields */
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   /* no spectra have been added yet */
00258   (*buffer)->specFilled = 0;
00259 
00260   /* normal exit */
00261   DETATCHSTATUSPTR (status);
00262   RETURN (status);
00263 }
00264 
00265 
00266 /* <lalVerbatim file="SpecBufferCP"> */
00267 void
00268 LALDestroySpectrumBuffer (
00269     LALStatus       *status,
00270     SpectrumBuffer **buffer
00271     )
00272 { /* </lalVerbatim> */
00273   INT4 spec;
00274 
00275   INITSTATUS (status, "LALDestroySpectrumBuffer", SPECBUFFERC);
00276   ATTATCHSTATUSPTR (status);
00277 
00278   /* make sure that arguments are not NULL */
00279   ASSERT (buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00280   ASSERT (*buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00281 
00282   /* destroy spectra */
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   /* destroy window */
00293   LALDestroyVector (status->statusPtr, &(*buffer)->specParams->window);
00294   CHECKSTATUSPTR (status);
00295   
00296   LALFree ((*buffer)->specParams);
00297 
00298   LALFree (*buffer);
00299   *buffer = NULL;
00300 
00301   /* normal exit */
00302   DETATCHSTATUSPTR (status);
00303   RETURN (status);
00304 }
00305 
00306 
00307 /* <lalVerbatim file="SpecBufferCP"> */
00308 void
00309 LALAddSpectrum (
00310     LALStatus      *status,
00311     SpectrumBuffer *specBuffer,
00312     INT2TimeSeries *timeSeries
00313     )
00314 { /* </lalVerbatim> */
00315   INT4 whichSpec;
00316 
00317   INITSTATUS (status, "LALAddSpectrum", SPECBUFFERC);
00318   ATTATCHSTATUSPTR (status);
00319 
00320   /* make sure that arguments are not NULL */
00321   ASSERT (specBuffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00322   ASSERT (timeSeries, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00323  
00324   /* the next spectrum to fill */
00325   whichSpec = specBuffer->specFilled % specBuffer->numSpec;
00326 
00327   /* fill it */
00328   LALComputeSpectrum (
00329       status->statusPtr,
00330       specBuffer->specBuffer + whichSpec,
00331       timeSeries,
00332       specBuffer->specParams
00333       );
00334   CHECKSTATUSPTR (status);
00335 
00336   ++(specBuffer->specFilled);
00337 
00338   /* normal exit */
00339   DETATCHSTATUSPTR (status);
00340   RETURN (status);
00341 }
00342 
00343 
00344 /* <lalVerbatim file="SpecBufferCP"> */
00345 void
00346 LALAverageSpectrum (
00347     LALStatus            *status,
00348     REAL4FrequencySeries *spectrum,
00349     SpectrumBuffer       *buffer
00350     )
00351 { /* </lalVerbatim> */
00352   UINT4 i;
00353   INT4  spec;
00354   INT4  nspec;
00355   REAL4 fac;
00356 
00357   INITSTATUS (status, "LALAverageSpectrum", SPECBUFFERC);
00358 
00359   /* make sure that arguments are not NULL */
00360   ASSERT (spectrum, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00361   ASSERT (buffer, status, SPECBUFFERH_ENULL, SPECBUFFERH_MSGENULL);
00362 
00363   /* make sure that fields are not NULL */
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     /* should check sample rates, f0, and average epochs ... */
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   /* normal exit */
00402   RETURN (status);
00403 }

Generated on Tue Oct 14 02:32:21 2008 for LAL by  doxygen 1.5.2