SimulateSB.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Sukanta Bose, Jolien Creighton, Tania Regimbau, Teviet Creighton, John Whelan
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="SimulateSBCV">
00021 Author: Sukanta Bose (Adapted from a non-LAL code written by Bruce Allen)
00022 $Id: SimulateSB.c,v 1.12 2007/06/08 14:41:47 bema Exp $
00023 ************************************* </lalVerbatim> */
00024 
00025 /********************************************************** <lalLaTeX>
00026 \subsection{Module \texttt{SimulateSB.c}}
00027 \label{inject:ss:SimulateSB.c}
00028 
00029 Simulates whitened time-domain signal in a pair 
00030 of detectors that arises purely from  an isotropic and
00031 unpolarized stochastic background of gravitational radiation with the
00032 desired power spectrum, $\Omega_{\scriptstyle{\rm GW}}(f)$. This module 
00033 will evolve beyond its present funtionality to produce only \texttt{real} 
00034 time-series signal for a pair of interferometric detectors. 
00035 
00036 
00037 \subsubsection*{Prototypes}
00038 \input{SimulateSBCP}
00039 \idx{LALSimulateSB()}
00040 
00041 \subsubsection*{Description}
00042 
00043 The frequency domain strains $\widetilde{h}_1(f_i)$ 
00044 and $\widetilde{h}_2(f_j)$ caused by
00045 the stochastic background in two detectors are random variables that have
00046 zero mean and that obey  \cite{inject:Allen:1999}:
00047   \begin{equation}
00048     \langle\widetilde{h}_1^*(f_i)\widetilde{h}_1(f_j)\rangle
00049     = \frac{3H_0^2T}{20\pi^2}\delta_{ij}f_i^{-3}\gamma_{11}(f_i)
00050     \Omega_{\scriptstyle{\rm GW}}(|f_i|)
00051   \end{equation}
00052   and
00053    \begin{equation}
00054     \langle\widetilde{h}_2^*(f_i)\widetilde{h}_2(f_j)\rangle
00055     = \frac{3H_0^2T}{20\pi^2}\delta_{ij}f_i^{-3}\gamma_{22}(f_i)
00056     \Omega_{\scriptstyle{\rm GW}}(|f_i|)
00057   \end{equation}
00058   and
00059   \begin{equation}
00060     \langle\widetilde{h}_1^*(f_i)\widetilde{h}_2(f_j)\rangle
00061     = \frac{3H_0^2T}{20\pi^2}\delta_{ij}f_i^{-3}\gamma_{12}(f_i)
00062     \Omega_{\scriptstyle{\rm GW}}(|f_i|) \ ,
00063   \end{equation}
00064 where $\langle\rangle$ denotes ensemble average, $T$ is the time of
00065 observation, and $\gamma_{AB}$ is the overlap reduction function
00066 \cite{inject:Flanagan:1993} of the detector pair comprising detectors $A$ 
00067 and $B$. Above, $\widetilde{h}_1(f_i)$ and 
00068 $\widetilde{h}_2(f_j)$ are the Fourier components of the gravitational strains
00069 $h_1(t)$ and $h_2(t)$ at the two detectors. 
00070 
00071 The Fourier components that 
00072 obey the above relations are
00073   \begin{equation}
00074     \widetilde{h}_1(f_i) = \sqrt{3H_0^2T \over 40\pi^2}f_i^{-3/2}
00075     \Omega^{1/2}_{\scriptstyle{\rm GW}}(|f_i|) \sqrt{\gamma_{11}(f_i)}
00076 (x_{1i} + i y_{1i})
00077     \,
00078   \end{equation}
00079   and
00080   \begin{equation}
00081     \widetilde{h}_2(f_i) = \widetilde{h}_1(f_i)\frac{\gamma_{12}(f_i)}
00082 {\gamma_{11}(f_i)} +
00083     \sqrt{3H_0^2T \over 40\pi^2}f_i^{-3/2}
00084     \Omega^{1/2}_{\scriptstyle{\rm GW}}(|f_i|) 
00085     \sqrt{\gamma_{22}(f_i)-\frac{\gamma^2_{12}(f_i)}{\gamma_{11}(f_i)}} 
00086 (x_{2i} + i y_{2i})
00087     \,
00088   \end{equation}
00089 where $x_{1i}$, $y_{1i}$, $x_{2i}$, and $y_{2i}$ are statistically 
00090 independent real Gaussian random variables, each of zero mean and unit 
00091 variance. 
00092 
00093 The routine assumes as inputs the data sample length, temporal spacing,
00094 stochastic background characteristics, detector locations, the appropriate 
00095 representations of the detector response function in each detector, etc.
00096 The (frequency domain) response functions, $\widetilde{R}_1(f_i)$ and
00097 $\widetilde{R}_2(f_i)$  are used to whiten the strains
00098 $\widetilde{h}_1(f_i)$ and 
00099 $\widetilde{h}_2(f_i)$, respectively, to obtain the whitened 
00100 Fourier components:
00101   \begin{equation}
00102     \widetilde{o}_1(f_i) = \widetilde{R}_1(f_i)\widetilde{h}_1(f_i)
00103     \,
00104   \end{equation}
00105   and
00106   \begin{equation}
00107     \widetilde{o}_2(f_i) = \widetilde{R}_2(f_i)\widetilde{h}_2(f_i)
00108     \ .
00109   \end{equation}
00110 To obtain the whitened (real) 
00111 outputs $o_1(t_i)$ and $o_2(t_i)$ in the time domain, the inverse 
00112 Fourier transforms of the above frequency series are taken.
00113 
00114 \subsubsection*{Algorithm}
00115 
00116 The routine \texttt{LALSSSimStochBGTimeSeries()} produces only \texttt{real} 
00117 time-series signal for a pair of interferometric detectors. It
00118 first inputs the frequency 
00119 series describing the power spectrum of the stochastic background,
00120 $\Omega_{\scriptstyle{\rm GW}}(|f|)$, which the simulated 
00121 signal is required to represent. It also inputs two \texttt{COMPLEX8}
00122 frequency series corresponding, respectively, to the two detector
00123 response functions. As parameters, it takes the two \texttt{LALDetector}
00124 structures corresponding to the two detectors in which the signal is to be 
00125 mimicked. It also takes the time length (given in terms of the number of 
00126 time data samples), the time spacing, a seed (for generating random
00127 numbers), and a couple of \texttt{LALUnit} structures for specifying the
00128 units of the two time-series signals that the routine outputs.
00129 
00130 Using the specified power
00131 spectrum for the stochastic background, and a random number generator (of
00132 zero mean, unit variance Gaussian distributions), the routine produces 
00133 $\widetilde{h}_1(f_i)$ and $\widetilde{h}_2(f_i)$. The 
00134 response functions of the two detectors are then used to whiten the two 
00135 strains in the Fourier domain. Their inverse transform is then taken to obtain
00136 at each detector the whitened simulated signal in the time domain.
00137 
00138 \subsubsection*{Uses}
00139 
00140 \begin{verbatim}
00141 LALStochasticOmegaGW()
00142 LALReverseRealFFT()
00143 LALNormalDeviates()
00144 \end{verbatim}
00145 
00146 \subsubsection*{Notes}
00147 
00148 \begin{itemize}
00149 \item This routine does not yet support non-zero heterodyning frequencies.
00150 \end{itemize}
00151 
00152 \vfill{\footnotesize\input{SimulateSBCV}}
00153 
00154 ******************************************************* </lalLaTeX> */ 
00155 
00156 /**************************** <lalLaTeX file="SimulateSBCB">
00157 \bibitem{inject:Allen:1999}
00158   B.~Allen and J.~D.~Romano, ``Detecting a stochastic background of
00159   gravitational radiation: Signal processing strategies and
00160   sensitivities''
00161   Phys.\ Rev.\ D {\bf 59}, 102001 (1999);
00162   \href{http://www.arXiv.org/abs/gr-qc/9710117}{gr-qc/9710117}
00163   \bibitem{inject:Flanagan:1993}
00164   E.~Flanagan, ``The sensitivity of the laser interferometer gravitational 
00165   wave observatory (LIGO) to a stochastic background, and its dependence on
00166   the detector orientations''
00167   Phys.\ Rev.\ D {\bf 48}, 2389 (1993);
00168   \href{http://www.arXiv.org/abs/astro-ph/9305029}{astro-ph/9305029}
00169 ******************************************************* </lalLaTeX> */
00170 
00171 #include <math.h>
00172 #include <string.h>
00173 #include <stdio.h>
00174 #include <lal/LALStdlib.h>
00175 #include <lal/LALConstants.h>
00176 #include <lal/StochasticCrossCorrelation.h> 
00177 #include <lal/AVFactories.h>
00178 #include <lal/RealFFT.h>
00179 #include <lal/ComplexFFT.h>
00180 #include <lal/Units.h>
00181 #include <lal/Random.h>
00182 #include <lal/SimulateSB.h>
00183 #include <lal/DetectorSite.h>
00184 
00185 NRCSID (SIMULATESBC, "$Id: SimulateSB.c,v 1.12 2007/06/08 14:41:47 bema Exp $");
00186 
00187 /* <lalVerbatim file="SimulateSBCP"> */
00188 void
00189 LALSSSimStochBGTimeSeries( LALStatus                    *status,
00190                            SSSimStochBGOutput           *output,
00191                            SSSimStochBGInput            *input,
00192                            SSSimStochBGParams           *params 
00193                )
00194      /* </lalVerbatim> */
00195 {
00196   /* parameters */
00197   UINT4             length;   /* (time) length of output vector data samples */
00198   UINT4             freqlen;
00199   REAL8             deltaT;   /* time spacing */
00200   REAL8             f0;       /* start frequency */
00201   
00202   /* counters */ 
00203   UINT4             i;
00204   
00205   /* other variables used */
00206   REAL8             deltaF;
00207   RandomParams     *randParams=NULL;
00208   
00209   /* vector for storing random numbers */ 
00210   REAL4Vector      *gaussdevsX1=NULL;
00211   REAL4Vector      *gaussdevsY1=NULL;
00212   REAL4Vector      *gaussdevsX2=NULL;
00213   REAL4Vector      *gaussdevsY2=NULL;
00214   
00215   /* LAL structure needed as input/output for computing overlap 
00216      reduction function */
00217   LALDetectorPair                    detectors;
00218   REAL4FrequencySeries               overlap11,overlap12,overlap22;
00219   OverlapReductionFunctionParameters ORFparameters;
00220   
00221   
00222   /* IFO output counts in freq domain : */
00223   COMPLEX8Vector   *ccounts[2]={NULL,NULL};
00224   COMPLEX8Vector   *ccountsTmp[2]={NULL,NULL};
00225   
00226   /* Plan for reverse FFTs */ 
00227   RealFFTPlan      *invPlan=NULL;  
00228   
00229   /* initialize status pointer */
00230   INITSTATUS(status, "LALSSSimStochBGTimeSeries", SIMULATESBC);
00231   ATTATCHSTATUSPTR(status);
00232   
00233   
00234   /*
00235    *
00236    *ERROR CHECKING
00237    *
00238    */
00239   
00240   /***** check input/output structures exist *****/
00241 
00242   /* output structure */
00243   ASSERT(output !=NULL, status, 
00244          SIMULATESBH_ENULLP,
00245          SIMULATESBH_MSGENULLP);
00246   ASSERT(output->SSimStochBG1->data !=NULL, status, 
00247          SIMULATESBH_ENULLP,
00248          SIMULATESBH_MSGENULLP);
00249   ASSERT(output->SSimStochBG2->data !=NULL, status, 
00250          SIMULATESBH_ENULLP,
00251          SIMULATESBH_MSGENULLP);
00252   ASSERT(output->SSimStochBG1->data->data !=NULL, status, 
00253          SIMULATESBH_ENULLP,
00254          SIMULATESBH_MSGENULLP);
00255   ASSERT(output->SSimStochBG2->data->data !=NULL, status, 
00256          SIMULATESBH_ENULLP,
00257          SIMULATESBH_MSGENULLP);
00258   
00259   /* input structure */
00260   ASSERT(input != NULL, status, 
00261          SIMULATESBH_ENULLP,
00262          SIMULATESBH_MSGENULLP);
00263   
00264   /* omega member of input */
00265   ASSERT(input->omegaGW != NULL, status, 
00266          SIMULATESBH_ENULLP,
00267          SIMULATESBH_MSGENULLP);
00268   
00269   /* First detector's complex response (whitening filter) part of input */
00270   ASSERT(input->whiteningFilter1 != NULL, status, 
00271          SIMULATESBH_ENULLP,
00272          SIMULATESBH_MSGENULLP);
00273 
00274   /* Second detector's complex response (whitening filter) part of input */
00275   ASSERT(input->whiteningFilter2 != NULL, status, 
00276          SIMULATESBH_ENULLP,
00277          SIMULATESBH_MSGENULLP);
00278 
00279   /* data member of omega */
00280   ASSERT(input->omegaGW->data != NULL, status, 
00281          SIMULATESBH_ENULLP,
00282          SIMULATESBH_MSGENULLP);
00283 
00284   /* data member of first detector's response (whitening filter) */
00285   ASSERT(input->whiteningFilter1->data != NULL, status, 
00286          SIMULATESBH_ENULLP,
00287          SIMULATESBH_MSGENULLP);
00288 
00289   /* data member of second detector's response (whitening filter) */
00290   ASSERT(input->whiteningFilter2->data != NULL, status, 
00291          SIMULATESBH_ENULLP,
00292          SIMULATESBH_MSGENULLP);
00293 
00294   /* data-data member of first detector's response (whitening filter) */
00295   ASSERT(input->whiteningFilter1->data->data != NULL, status, 
00296          SIMULATESBH_ENULLP,
00297          SIMULATESBH_MSGENULLP);
00298 
00299   /* data-data member of second detector's response (whitening filter) */
00300   ASSERT(input->whiteningFilter2->data->data != NULL, status, 
00301          SIMULATESBH_ENULLP,
00302          SIMULATESBH_MSGENULLP);
00303 
00304   /************* check parameter structures ***********/
00305 
00306   /*No. of discrete time samples (length) is non-zero in each detector output*/
00307   ASSERT(params->length > 0, status, 
00308          SIMULATESBH_ENONPOSLEN,
00309          SIMULATESBH_MSGENONPOSLEN);
00310 
00311   /* time-interval between successive samples is non-zero in each output */
00312   ASSERT(params->deltaT > 0, status, 
00313          SIMULATESBH_ENONPOSLEN,
00314          SIMULATESBH_MSGENONPOSLEN);
00315 
00316   /************* done with null pointers *****************/
00317   
00318   
00319   /**** check for legality ****/
00320   
00321   /* start frequency must not be negative */
00322   f0 = input->omegaGW->f0;
00323   if (f0 < 0)
00324     {
00325       ABORT( status,
00326              SIMULATESBH_ENEGFMIN,
00327              SIMULATESBH_MSGENEGFMIN );
00328     }
00329   
00330   
00331   /** check for mismatches **/
00332   /* frequency length = length/2 +1  */
00333   length = params->length;
00334   freqlen = length/2 +1;
00335 
00336   if (input->omegaGW->data->length != (length/2 +1)) 
00337     {
00338       ABORT(status,
00339             SIMULATESBH_EMMLEN,
00340             SIMULATESBH_MSGEMMLEN);
00341     }
00342   if (input->whiteningFilter1->data->length != (length/2 +1)) 
00343     {
00344       ABORT(status,
00345             SIMULATESBH_EMMLEN,
00346             SIMULATESBH_MSGEMMLEN);
00347     }
00348   if (input->whiteningFilter2->data->length != (length/2 +1)) 
00349     {
00350       ABORT(status,
00351             SIMULATESBH_EMMLEN,
00352             SIMULATESBH_MSGEMMLEN);
00353     }
00354   if (input->whiteningFilter1->f0 != f0) 
00355     {
00356       ABORT(status,
00357             SIMULATESBH_EMMFMIN,
00358             SIMULATESBH_MSGEMMFMIN);
00359     }
00360   if (input->whiteningFilter2->f0 != f0) 
00361     {
00362       ABORT(status,
00363             SIMULATESBH_EMMFMIN,
00364             SIMULATESBH_MSGEMMFMIN);
00365     }
00366 
00367   /* frequency spacing */
00368   deltaT = params->deltaT;
00369   deltaF = 1/(deltaT*length);
00370   if (input->whiteningFilter1->deltaF != deltaF) 
00371     {
00372       ABORT(status,
00373             SIMULATESBH_EMMDELTAF,
00374             SIMULATESBH_MSGEMMDELTAF);
00375     }
00376   if (input->whiteningFilter2->deltaF != deltaF) 
00377     {
00378       ABORT(status,
00379             SIMULATESBH_EMMDELTAF,
00380             SIMULATESBH_MSGEMMDELTAF);
00381     }
00382   
00383   
00384   /*
00385    *
00386    *EVERYHTING OKAY HERE 
00387    *
00388    */
00389   
00390 
00391   /******** create fft plans and workspace vectors *****/
00392 
00393   LALCreateReverseRealFFTPlan(status->statusPtr,&invPlan,length,0);
00394   CHECKSTATUSPTR( status ); 
00395 
00396   LALSCreateVector( status->statusPtr, 
00397                     &gaussdevsX1, freqlen ); 
00398   BEGINFAIL( status )
00399     {
00400       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00401                                   &invPlan ), status );
00402     }
00403   ENDFAIL( status );
00404   
00405 
00406   LALSCreateVector( status->statusPtr, 
00407                     &gaussdevsY1, freqlen ); 
00408   BEGINFAIL( status )
00409     {
00410       TRY( LALSDestroyVector( status->statusPtr, 
00411                               &gaussdevsX1), status ); 
00412       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00413                                   &invPlan ), status );
00414     }
00415   ENDFAIL( status );
00416   
00417   LALSCreateVector( status->statusPtr, 
00418                     &gaussdevsX2, freqlen ); 
00419   BEGINFAIL( status )
00420     {
00421       TRY( LALSDestroyVector( status->statusPtr, 
00422                               &gaussdevsY1), status ); 
00423       TRY( LALSDestroyVector( status->statusPtr, 
00424                               &gaussdevsX1), status ); 
00425       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00426                                   &invPlan ), status );
00427     }
00428   ENDFAIL( status );
00429   
00430   LALSCreateVector( status->statusPtr, 
00431                     &gaussdevsY2, freqlen ); 
00432   BEGINFAIL( status )
00433     {
00434       TRY( LALSDestroyVector( status->statusPtr, 
00435                               &gaussdevsX2), status ); 
00436       TRY( LALSDestroyVector( status->statusPtr, 
00437                               &gaussdevsY1), status ); 
00438       TRY( LALSDestroyVector( status->statusPtr, 
00439                               &gaussdevsX1), status ); 
00440       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00441                                   &invPlan ), status );
00442     }
00443   ENDFAIL( status );
00444   
00445   /* create parameters for generating random numbers from seed */
00446   LALCreateRandomParams( status->statusPtr, 
00447                          &randParams, params->seed ); 
00448   BEGINFAIL( status )
00449     {
00450       TRY( LALSDestroyVector( status->statusPtr, 
00451                               &gaussdevsY2), status ); 
00452       TRY( LALSDestroyVector( status->statusPtr, 
00453                               &gaussdevsX2), status ); 
00454       TRY( LALSDestroyVector( status->statusPtr, 
00455                               &gaussdevsY1), status ); 
00456       TRY( LALSDestroyVector( status->statusPtr, 
00457                               &gaussdevsX1), status ); 
00458       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00459                                   &invPlan ), status );
00460     }
00461   ENDFAIL( status );
00462   
00463   LALCCreateVector(status->statusPtr, &ccounts[0],freqlen);
00464   BEGINFAIL( status )
00465     {
00466       TRY( LALDestroyRandomParams( status->statusPtr, 
00467                                    &randParams), status ); 
00468       TRY( LALSDestroyVector( status->statusPtr, 
00469                               &gaussdevsY2), status ); 
00470       TRY( LALSDestroyVector( status->statusPtr, 
00471                               &gaussdevsX2), status ); 
00472       TRY( LALSDestroyVector( status->statusPtr, 
00473                               &gaussdevsY1), status ); 
00474       TRY( LALSDestroyVector( status->statusPtr, 
00475                               &gaussdevsX1), status ); 
00476       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00477                                   &invPlan ), status );
00478     }  
00479   ENDFAIL( status );
00480   
00481   LALCCreateVector(status->statusPtr, &ccounts[1],freqlen);
00482   BEGINFAIL( status )
00483     {
00484       TRY( LALCDestroyVector(status->statusPtr, &ccounts[0]), status);
00485       TRY( LALDestroyRandomParams( status->statusPtr, 
00486                                    &randParams), status ); 
00487       TRY( LALSDestroyVector( status->statusPtr, 
00488                               &gaussdevsY2), status ); 
00489       TRY( LALSDestroyVector( status->statusPtr, 
00490                               &gaussdevsX2), status ); 
00491       TRY( LALSDestroyVector( status->statusPtr, 
00492                               &gaussdevsY1), status ); 
00493       TRY( LALSDestroyVector( status->statusPtr, 
00494                               &gaussdevsX1), status ); 
00495       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00496                                   &invPlan ), status );
00497     }  
00498   ENDFAIL( status );
00499   
00500   LALCCreateVector(status->statusPtr, &ccountsTmp[0],freqlen);
00501   BEGINFAIL( status )
00502     {
00503       TRY( LALCDestroyVector(status->statusPtr, &ccounts[1]), status);
00504       TRY( LALCDestroyVector(status->statusPtr, &ccounts[0]), status);
00505       TRY( LALDestroyRandomParams( status->statusPtr, 
00506                                    &randParams), status ); 
00507       TRY( LALSDestroyVector( status->statusPtr, 
00508                               &gaussdevsY2), status ); 
00509       TRY( LALSDestroyVector( status->statusPtr, 
00510                               &gaussdevsX2), status ); 
00511       TRY( LALSDestroyVector( status->statusPtr, 
00512                               &gaussdevsY1), status ); 
00513       TRY( LALSDestroyVector( status->statusPtr, 
00514                               &gaussdevsX1), status ); 
00515       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00516                                   &invPlan ), status );
00517     }  
00518   ENDFAIL( status );
00519   
00520   LALCCreateVector(status->statusPtr, &ccountsTmp[1],freqlen);
00521   BEGINFAIL( status )
00522     {
00523       TRY( LALCDestroyVector(status->statusPtr, &ccountsTmp[0]), status);
00524       TRY( LALCDestroyVector(status->statusPtr, &ccounts[1]), status);
00525       TRY( LALCDestroyVector(status->statusPtr, &ccounts[0]), status);
00526       TRY( LALDestroyRandomParams( status->statusPtr, 
00527                                    &randParams), status ); 
00528       TRY( LALSDestroyVector( status->statusPtr, 
00529                               &gaussdevsY2), status ); 
00530       TRY( LALSDestroyVector( status->statusPtr, 
00531                               &gaussdevsX2), status ); 
00532       TRY( LALSDestroyVector( status->statusPtr, 
00533                               &gaussdevsY1), status ); 
00534       TRY( LALSDestroyVector( status->statusPtr, 
00535                               &gaussdevsX1), status ); 
00536       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00537                                   &invPlan ), status );
00538     }  
00539   ENDFAIL( status );
00540 
00541   overlap11.data = NULL;
00542   LALSCreateVector(status->statusPtr, &(overlap11.data),freqlen);
00543   BEGINFAIL( status )
00544     {
00545       TRY( LALCDestroyVector(status->statusPtr, &ccountsTmp[1]), status);
00546       TRY( LALCDestroyVector(status->statusPtr, &ccountsTmp[0]), status);
00547       TRY( LALCDestroyVector(status->statusPtr, &ccounts[1]), status);
00548       TRY( LALCDestroyVector(status->statusPtr, &ccounts[0]), status);
00549       TRY( LALDestroyRandomParams( status->statusPtr, 
00550                                    &randParams), status ); 
00551       TRY( LALSDestroyVector( status->statusPtr, 
00552                               &gaussdevsY2), status ); 
00553       TRY( LALSDestroyVector( status->statusPtr, 
00554                               &gaussdevsX2), status ); 
00555       TRY( LALSDestroyVector( status->statusPtr, 
00556                               &gaussdevsY1), status ); 
00557       TRY( LALSDestroyVector( status->statusPtr, 
00558                               &gaussdevsX1), status ); 
00559       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00560                                   &invPlan ), status );
00561     }  
00562   ENDFAIL( status );
00563     
00564   overlap12.data = NULL;
00565   LALSCreateVector(status->statusPtr, &(overlap12.data),freqlen);
00566   BEGINFAIL( status )
00567     {
00568       TRY( LALSDestroyVector(status->statusPtr, &(overlap11.data)), status);
00569       TRY( LALCDestroyVector(status->statusPtr, &ccountsTmp[1]), status);
00570       TRY( LALCDestroyVector(status->statusPtr, &ccountsTmp[0]), status);
00571       TRY( LALCDestroyVector(status->statusPtr, &ccounts[1]), status);
00572       TRY( LALCDestroyVector(status->statusPtr, &ccounts[0]), status);
00573       TRY( LALDestroyRandomParams( status->statusPtr, 
00574                                    &randParams), status ); 
00575       TRY( LALSDestroyVector( status->statusPtr, 
00576                               &gaussdevsY2), status ); 
00577       TRY( LALSDestroyVector( status->statusPtr, 
00578                               &gaussdevsX2), status ); 
00579       TRY( LALSDestroyVector( status->statusPtr, 
00580                               &gaussdevsY1), status ); 
00581       TRY( LALSDestroyVector( status->statusPtr, 
00582                               &gaussdevsX1), status ); 
00583       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00584                                   &invPlan ), status );
00585     }  
00586   ENDFAIL( status );
00587     
00588   overlap22.data = NULL;
00589   LALSCreateVector(status->statusPtr, &(overlap22.data),freqlen);
00590   BEGINFAIL( status )
00591     {
00592       TRY( LALSDestroyVector(status->statusPtr, &(overlap12.data)), status);
00593       TRY( LALSDestroyVector(status->statusPtr, &(overlap11.data)), status);
00594       TRY( LALCDestroyVector(status->statusPtr, &ccountsTmp[1]), status);
00595       TRY( LALCDestroyVector(status->statusPtr, &ccountsTmp[0]), status);
00596       TRY( LALCDestroyVector(status->statusPtr, &ccounts[1]), status);
00597       TRY( LALCDestroyVector(status->statusPtr, &ccounts[0]), status);
00598       TRY( LALDestroyRandomParams( status->statusPtr, 
00599                                    &randParams), status ); 
00600       TRY( LALSDestroyVector( status->statusPtr, 
00601                               &gaussdevsY2), status ); 
00602       TRY( LALSDestroyVector( status->statusPtr, 
00603                               &gaussdevsX2), status ); 
00604       TRY( LALSDestroyVector( status->statusPtr, 
00605                               &gaussdevsY1), status ); 
00606       TRY( LALSDestroyVector( status->statusPtr, 
00607                               &gaussdevsX1), status ); 
00608       TRY( LALDestroyRealFFTPlan( status->statusPtr, 
00609                                   &invPlan ), status );
00610     }  
00611   ENDFAIL( status );
00612     
00613   /* create random numbers from parameters */
00614   LALNormalDeviates( status->statusPtr, 
00615                      gaussdevsX1, randParams ); 
00616   CHECKSTATUSPTR( status);
00617 
00618   LALDestroyRandomParams(status->statusPtr,&randParams);
00619 
00620   LALCreateRandomParams(status->statusPtr,&randParams, params->seed +1);
00621   
00622   LALNormalDeviates( status->statusPtr, 
00623                      gaussdevsY1, randParams ); 
00624   CHECKSTATUSPTR( status);
00625   
00626   LALDestroyRandomParams(status->statusPtr,&randParams);
00627   
00628   LALCreateRandomParams(status->statusPtr,&randParams, params->seed +2);
00629   
00630   LALNormalDeviates( status->statusPtr, 
00631                      gaussdevsX2, randParams ); 
00632   CHECKSTATUSPTR( status);
00633  
00634   LALDestroyRandomParams(status->statusPtr,&randParams);
00635   
00636   LALCreateRandomParams(status->statusPtr,&randParams, params->seed +3);
00637   
00638   LALNormalDeviates( status->statusPtr, 
00639                      gaussdevsY2, randParams ); 
00640   CHECKSTATUSPTR( status);
00641   
00642   LALDestroyRandomParams(status->statusPtr,&randParams);
00643 
00644   ORFparameters.length   = length/2 + 1;
00645   ORFparameters.f0       = f0;
00646   ORFparameters.deltaF   = deltaF;
00647   detectors.detectorOne  = params->detectorOne;
00648   detectors.detectorTwo  = params->detectorOne;
00649 
00650   LALOverlapReductionFunction( status->statusPtr, &overlap11, 
00651                                &detectors, &ORFparameters);
00652   CHECKSTATUSPTR( status);
00653 
00654   detectors.detectorOne  = params->detectorOne;
00655   detectors.detectorTwo  = params->detectorTwo;
00656 
00657   LALOverlapReductionFunction( status->statusPtr, &overlap12, 
00658                                &detectors, &ORFparameters);
00659   CHECKSTATUSPTR( status);
00660 
00661   detectors.detectorOne  = params->detectorTwo;
00662   detectors.detectorTwo  = params->detectorTwo;
00663 
00664   LALOverlapReductionFunction( status->statusPtr, &overlap22, 
00665                                &detectors, &ORFparameters);
00666   CHECKSTATUSPTR( status);
00667   
00668   if (f0 == 0) 
00669     {
00670       REAL4    gamma11,gamma12,gamma22;
00671       REAL4    omega;
00672       REAL8    freq;
00673       REAL8    factor;
00674       REAL8    factor2,factor3;
00675       COMPLEX8 wFilter1;
00676       COMPLEX8 wFilter2;
00677        
00678       /* loop over frequencies; will do DC and Nyquist below */
00679       for (i = 1; i < freqlen; ++i)
00680         {
00681           freq  = i*deltaF;       
00682 
00683           gamma11 = overlap11.data->data[i];
00684           gamma12 = overlap12.data->data[i];
00685           gamma22 = overlap22.data->data[i];
00686 
00687           omega = input->omegaGW->data->data[i];
00688           
00689           factor = deltaF * sqrt(3.0L * length * deltaT * omega / 
00690                                  (40.0L *freq*freq*freq)
00691                                  )* LAL_H0FAC_SI / LAL_PI;
00692           factor2 = sqrt(gamma22-gamma12*gamma12/gamma11)*factor;
00693           factor3 = sqrt(gamma11)*factor;
00694 
00695           wFilter1 = input->whiteningFilter1->data->data[i];
00696           wFilter2 = input->whiteningFilter2->data->data[i];
00697           
00698           ccountsTmp[0]->data[i].re=factor3*gaussdevsX1->data[i];
00699           ccountsTmp[0]->data[i].im=factor3*gaussdevsY1->data[i];
00700           ccountsTmp[1]->data[i].re=ccountsTmp[0]->data[i].re*gamma12/gamma11+factor2*gaussdevsX2->data[i];
00701           ccountsTmp[1]->data[i].im=ccountsTmp[0]->data[i].im*gamma12/gamma11+factor2*gaussdevsY2->data[i];
00702           
00703           ccounts[0]->data[i].re = wFilter1.re * ccountsTmp[0]->data[i].re -
00704             wFilter1.im * ccountsTmp[0]->data[i].im;
00705           ccounts[0]->data[i].im = wFilter1.re * ccountsTmp[0]->data[i].im +
00706             wFilter1.im * ccountsTmp[0]->data[i].re;
00707           ccounts[1]->data[i].re = wFilter2.re * ccountsTmp[1]->data[i].re -
00708             wFilter2.im * ccountsTmp[1]->data[i].im;
00709           ccounts[1]->data[i].im = wFilter2.re * ccountsTmp[1]->data[i].im +
00710             wFilter2.im * ccountsTmp[1]->data[i].re;
00711         }
00712       
00713       /* Set DC, Nyquist (imaginary) components to zero */
00714       for (i=0;i<2;++i)
00715         {
00716           ccounts[i]->data[0].re=0.0;
00717           ccounts[i]->data[0].im=0.0;
00718           ccountsTmp[i]->data[length/2].im=0.0;
00719         }
00720       
00721       /* Compute the whitened Nyquist (real) component */
00722       gamma11 = overlap11.data->data[length/2];
00723       gamma12 = overlap12.data->data[length/2];
00724       gamma22 = overlap22.data->data[length/2];
00725       
00726       omega = input->omegaGW->data->data[length/2];
00727       freq = deltaF*length/2;
00728       
00729       wFilter1 = input->whiteningFilter1->data->data[length/2];
00730       wFilter2 = input->whiteningFilter2->data->data[length/2];
00731       
00732       /* check that whitening filter is real in time domain */
00733       if (wFilter1.im != 0) 
00734         {
00735           ABORT(status,
00736                 SIMULATESBH_ECOMPTIME,
00737                 SIMULATESBH_MSGECOMPTIME);
00738         };
00739       if (wFilter2.im != 0) 
00740         {
00741           ABORT(status,
00742                 SIMULATESBH_ECOMPTIME,
00743                 SIMULATESBH_MSGECOMPTIME);
00744         };
00745       
00746       factor = deltaF * sqrt(3.0L * length * deltaT * omega / 
00747                              (40.0L *freq<