LALPulsar  6.1.0.1-b72065a
GenerateSpinOrbitCW.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton, Teviet Creighton
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 #include <lal/LALStdio.h>
21 #include <lal/LALStdlib.h>
22 #include <lal/LALConstants.h>
23 #include <lal/Units.h>
24 #include <lal/AVFactories.h>
25 #include <lal/SeqFactories.h>
26 #include <lal/PulsarSimulateCoherentGW.h>
27 #include <lal/GenerateTaylorCW.h>
28 #include <lal/GenerateSpinOrbitCW.h>
29 
30 /**
31  * FIXME: Temporary XLAL-wapper to LAL-function LALGenerateSpinOrbitCW()
32  *
33  * NOTE: This violates the current version of the XLAL-spec, but is unavoidable at this time,
34  * as LALGenerateSpinOrbitCW() hasn't been properly XLALified yet, and doing this would be beyond
35  * the scope of this patch.
36  * However, doing it here in this way is better than calling LALGenerateSpinOrbitCW() from various
37  * far-flung XLAL-functions, as in this way the "violation" is localized in one place, and serves
38  * as a reminder for future XLAL-ification at the same time.
39  */
40 int
41 XLALGenerateSpinOrbitCW( PulsarCoherentGW *sourceSignal, ///< [out] output signal
42  SpinOrbitCWParamStruc *sourceParams ///< [in] input parameters
43  )
44 {
45  XLAL_CHECK( sourceSignal != NULL, XLAL_EINVAL );
46  XLAL_CHECK( sourceParams != NULL, XLAL_EINVAL );
47 
49 
50  LALGenerateSpinOrbitCW( &status, sourceSignal, sourceParams );
51 
52  XLAL_CHECK( status.statusCode == 0, XLAL_EFAILED, "LALGenerateSpinOrbitCW() failed with code=%d, msg='%s'\n", status.statusCode, status.statusDescription );
53 
54  return XLAL_SUCCESS;
55 
56 } // XLALGenerateSpinOrbitCW()
57 
58 
59 
60 /* First, define a function to compute C(a,b) = (a!)/[(b!)*(a-b)!] */
61 static UINT4
62 choose( UINT4 a, UINT4 b );
63 static UINT4
65 {
66  UINT4 numer = 1;
67  UINT4 denom = 1;
68  UINT4 myindex = b + 1;
69  while ( --myindex ) {
70  numer *= a - b + myindex;
71  denom *= myindex;
72  }
73  return numer / denom;
74 }
75 
76 
77 /**
78  * \author Creighton, T. D.
79  *
80  * \brief Computes a spindown- and Doppler-modulated continuous waveform.
81  *
82  * This function computes a quasiperiodic waveform using the spindown and
83  * orbital parameters in <tt>*params</tt>, storing the result in
84  * <tt>*output</tt>.
85  *
86  * In the <tt>*params</tt> structure, the routine uses all the "input"
87  * fields specified in \ref GenerateSpinOrbitCW_h, and sets all of the
88  * "output" fields. If <tt>params->f</tt>=\c NULL, no spindown
89  * modulation is performed. If <tt>params->rPeriNorm</tt>=0, no Doppler
90  * modulation is performed.
91  *
92  * In the <tt>*output</tt> structure, the field <tt>output->h</tt> is
93  * ignored, but all other pointer fields must be set to \c NULL. The
94  * function will create and allocate space for <tt>output->a</tt>,
95  * <tt>output->f</tt>, and <tt>output->phi</tt> as necessary. The
96  * <tt>output->shift</tt> field will remain set to \c NULL.
97  *
98  * ### Algorithm ###
99  *
100  * This routine calls <tt>LALGenerateCircularSpinOrbitCW()</tt>,
101  * <tt>LALGenerateCircularSpinOrbitCW()</tt>,
102  * <tt>LALGenerateCircularSpinOrbitCW()</tt>, or
103  * <tt>LALGenerateCircularSpinOrbitCW()</tt>, depending on the value of
104  * <tt>params->oneMinusEcc</tt>. See the other modules under
105  * \ref GenerateSpinOrbitCW_h for descriptions of these routines'
106  * algorithms.
107  *
108  * If <tt>params->rPeriNorm</tt>=0, this routine will call
109  * <tt>LALGenerateTaylorCW()</tt> to generate the waveform. It creates a
110  * \c TaylorCWParamStruc from the values in <tt>*params</tt>, adjusting
111  * the values of <tt>params->phi0</tt>, <tt>params->f0</tt>, and
112  * <tt>params->f</tt> from the reference time <tt>params->spinEpoch</tt> to
113  * the time <tt>params->epoch</tt>, as follows: Let \f$ \Delta
114  * t=t^{(2)}-t^{(1)} \f$ be the time between the old epoch \f$ t^{(1)} \f$ and the
115  * new one \f$ t^{(2)} \f$ . Then the phase, base frequency, and spindown
116  * parameters for the new epoch are:
117  * \f{eqnarray}{
118  * \phi_0^{(2)} & = & \phi_0^{(1)} + 2\pi f_0^{(1)}t \left( 1 +
119  * \sum_{k=1}^N \frac{1}{k+1}f_k^{(1)} \Delta t^k \right) \\
120  * f_0^{(2)} & = & f_0^{(1)} \left( 1 +
121  * \sum_{k=1}^N f_k^{(1)} \Delta t^k \right) \\
122  * f_k^{(2)} & = & \frac{f_0^{(1)}}{f_0^{(2)}} \left( f_k^{(1)} +
123  * \sum_{j=k+1}{N} \binom{j}{k} f_j^{(1)}\Delta t^{j-k} \right)
124  * \f}
125  * The phase function \f$ \phi(t)=\phi_0^{(i)}+2\pi
126  * f_0^{(i)}\left[t-t^{(i)}+\sum_{k=1}^N
127  * \frac{f_k^{(i)}}{k+1}\left(t-t^{(i)}\right)^{k+1}\right] \f$ then has the
128  * same functional dependence on \f$ t \f$ for either \f$ i=1 \f$ or~2.
129  */
130 void
134 {
135 
136  INITSTATUS( stat );
138 
139  /* Make sure parameter structure exists (output structure will be
140  tested by subroutine). */
142  GENERATESPINORBITCWH_MSGENUL );
143 
144  /* If there is no orbital motion, use LALGenerateTaylorCW() to
145  compute the waveform. */
146  if ( params->rPeriNorm == 0.0 ) {
147  TaylorCWParamStruc taylorParams; /* subroutine parameters */
148  REAL8 t; /* time shift */
149  memset( &taylorParams, 0, sizeof( TaylorCWParamStruc ) );
150  taylorParams.position = params->position;
151  taylorParams.psi = params->psi;
152  taylorParams.epoch = params->epoch;
153  taylorParams.deltaT = params->deltaT;
154  taylorParams.length = params->length;
155  taylorParams.aPlus = params->aPlus;
156  taylorParams.aCross = params->aCross;
157  taylorParams.phi0 = params->phi0;
158  taylorParams.f0 = params->f0;
159  t = ( REAL8 )( params->epoch.gpsSeconds -
160  params->spinEpoch.gpsSeconds );
161  t += ( 1.0e-9 ) * ( REAL8 )( params->epoch.gpsNanoSeconds -
162  params->spinEpoch.gpsNanoSeconds );
163 
164  /* Adjust epochs. */
165  if ( params->f ) {
166  UINT4 length = params->f->length; /* number of coefficients */
167  UINT4 i, j; /* indecies over coefficients */
168  REAL8 tN = 1.0; /* t raised to various powers */
169  REAL8 fFac = 1.0; /* fractional change in frequency */
170  REAL8 tFac = 1.0; /* time integral of fFac */
171  REAL8 *f1Data = params->f->data; /* pointer to coeficients */
172  REAL8 *f2Data; /* pointer to corrected coeficients */
173 
174  TRY( LALDCreateVector( stat->statusPtr, &( taylorParams.f ),
175  length ), stat );
176  f2Data = taylorParams.f->data;
177  memcpy( f2Data, f1Data, length * sizeof( REAL8 ) );
178  for ( i = 0; i < length; i++ ) {
179  REAL8 tM = 1.0; /* t raised to various powers */
180  fFac += f1Data[i] * ( tN *= t );
181  tFac += f1Data[i] * tN / ( i + 2.0 );
182  for ( j = i + 1; j < length; j++ ) {
183  f2Data[i] += choose( j + 1, i + 1 ) * f1Data[j] * ( tM *= t );
184  }
185  }
186  taylorParams.phi0 += LAL_TWOPI * taylorParams.f0 * t * tFac;
187  taylorParams.f0 *= fFac;
188  for ( i = 0; i < length; i++ ) {
189  f2Data[i] /= fFac;
190  }
191  } else {
192  taylorParams.phi0 += LAL_TWOPI * taylorParams.f0 * t;
193  }
194 
195  /* Generate waveform. */
196  LALGenerateTaylorCW( stat->statusPtr, output, &taylorParams );
197  BEGINFAIL( stat ) {
198  if ( taylorParams.f ) {
199  TRY( LALDDestroyVector( stat->statusPtr, &( taylorParams.f ) ),
200  stat );
201  }
202  }
203  ENDFAIL( stat );
204  if ( taylorParams.f ) {
205  TRY( LALDDestroyVector( stat->statusPtr, &( taylorParams.f ) ),
206  stat );
207  }
208  params->dfdt = taylorParams.dfdt;
209  }
210 
211  /* If there is orbital motion, call the appropriate subroutine. */
212 
213  /* e < 0 is out of range. */
214  else if ( params->oneMinusEcc > 1.0 ) {
216  GENERATESPINORBITCWH_MSGEECC );
217  }
218 
219  /* 0 <= e < 1 is elliptic. */
220  else if ( params->oneMinusEcc > 0.0 ) {
222  params ), stat );
223  }
224 
225  /* e = 1 is parabolic. */
226  else if ( params->oneMinusEcc == 0.0 ) {
228  params ), stat );
229  }
230 
231  /* e > 1 is hyperbolic. */
232  else {
234  params ), stat );
235  }
236 
237  /* That is all. */
239  RETURN( stat );
240 }
static UINT4 choose(UINT4 a, UINT4 b)
int j
#define ABORT(statusptr, code, mesg)
#define ENDFAIL(statusptr)
#define TRY(func, statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define BEGINFAIL(statusptr)
const WeaveSearchTimingDenominator denom
Definition: SearchTiming.c:95
#define GENERATESPINORBITCWH_EECC
Eccentricity out of range.
void LALGenerateHyperbolicSpinOrbitCW(LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params)
Computes a continuous waveform with frequency drift and Doppler modulation from a hyperbolic orbital ...
void LALGenerateEllipticSpinOrbitCW(LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params)
Computes a continuous waveform with frequency drift and Doppler modulation from an elliptical orbital...
void LALGenerateSpinOrbitCW(LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params)
Computes a spindown- and Doppler-modulated continuous waveform.
#define GENERATESPINORBITCWH_ENUL
Unexpected null pointer in arguments.
void LALGenerateParabolicSpinOrbitCW(LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params)
Computes a continuous waveform with frequency drift and Doppler modulation from a parabolic orbital t...
int XLALGenerateSpinOrbitCW(PulsarCoherentGW *sourceSignal, SpinOrbitCWParamStruc *sourceParams)
FIXME: Temporary XLAL-wapper to LAL-function LALGenerateSpinOrbitCW()
void LALGenerateTaylorCW(LALStatus *stat, PulsarCoherentGW *output, TaylorCWParamStruc *params)
Computes a Taylor-parametrized continuous waveform.
#define LAL_TWOPI
double REAL8
#define XLAL_INIT_DECL(var,...)
uint32_t UINT4
static const INT4 a
void LALDCreateVector(LALStatus *, REAL8Vector **, UINT4)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
#define XLAL_CHECK(assertion,...)
XLAL_SUCCESS
XLAL_EINVAL
XLAL_EFAILED
INT4 gpsNanoSeconds
This structure stores a representation of a plane gravitational wave propagating from a particular po...
REAL8 * data
This structure stores the parameters for constructing a gravitational waveform with both a Taylor-pol...
This structure stores the parameters for constructing a gravitational waveform with a Taylor-polynomi...
REAL8 deltaT
The requested sampling interval of the waveform, in s.
SkyPosition position
The location of the source on the sky, normally in equatorial coordinates.
REAL8Vector * f
The spin-normalized Taylor parameters , as defined in Eq.
REAL4 dfdt
The maximum value of encountered over any timestep used in generating the waveform.
REAL8 phi0
The wave phase at time , in radians.
LIGOTimeGPS epoch
The start time of the output series.
UINT4 length
The number of samples in the generated waveform.
REAL4 psi
The polarization angle of the source, in radians.
REAL8 f0
The wave frequency at time , in Hz.
REAL4 aCross
The polarization amplitudes , , in dimensionless strain units.
LIGOTimeGPS epoch
double psi