LALSimulation  5.4.0.1-fe68b98
LALSimSphHarmMode.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Jolien 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/LALStdlib.h>
21 #include <lal/LALSimSphHarmMode.h>
22 #include <lal/SphericalHarmonics.h>
23 #include <lal/TimeSeries.h>
24 #include "check_series_macros.h"
25 
26 
27 /**
28  * @addtogroup LALSimSphHarmMode_h
29  * @{
30  */
31 
32 /**
33  * Multiplies a mode h(l,m) by a spin-2 weighted spherical harmonic
34  * to obtain hplus - i hcross, which is added to the time series.
35  *
36  * Implements the sum of a single term of Eq. (11) of:
37  * Lawrence E. Kidder, \"Using Full Information When Computing Modes of
38  * Post-Newtonian Waveforms From Inspiralling Compact Binaries in Circular
39  * Orbit\", Physical Review D 77, 044016 (2008), arXiv:0710.0614v1 [gr-qc].
40  *
41  * If sym is non-zero, symmetrically add the m and -m terms assuming
42  * that \f$h(l,-m) = (-1)^l h(l,m)*\f$; see Eq. (78) ibid.
43  */
45  REAL8TimeSeries *hplus, /**< +-polarization waveform */
46  REAL8TimeSeries *hcross, /**< x-polarization waveform */
47  COMPLEX16TimeSeries *hmode, /**< complex mode h(l,m) */
48  REAL8 theta, /**< polar angle (rad) */
49  REAL8 phi, /**< azimuthal angle (rad) */
50  int l, /**< mode number l */
51  int m, /**< mode number m */
52  int sym /**< flag to add -m mode too */
53  )
54 {
55  COMPLEX16 Y;
56  UINT4 j;
57 
63 
65  for ( j = 0; j < hmode->data->length; ++j ) {
66  COMPLEX16 hpc;
67  hpc = Y * hmode->data->data[j];
68  hplus->data->data[j] += creal(hpc);
69  hcross->data->data[j] += -cimag(hpc);
70  }
71  if ( sym ) { /* equatorial symmetry: add in -m mode */
72  Y = XLALSpinWeightedSphericalHarmonic(theta, phi, -2, l, -m);
73  if ( l % 2 ) /* l is odd */
74  Y = -Y;
75  for ( j = 0; j < hmode->data->length; ++j ) {
76  COMPLEX16 hpc;
77  hpc = Y * conj(hmode->data->data[j]);
78  hplus->data->data[j] += creal(hpc);
79  hcross->data->data[j] += -cimag(hpc);
80  }
81  }
82  return 0;
83 }
84 
85 /**
86  * Multiplies a mode h(l,m) by a spin-2 weighted spherical harmonic
87  * to obtain hplus - i hcross, which is added to the time series for
88  * TimeSeries of angles.
89  *
90  * Implements the sum of Eq. (11) of:
91  * Lawrence E. Kidder, \"Using Full Information When Computing Modes of
92  * Post-Newtonian Waveforms From Inspiralling Compact Binaries in Circular
93  * Orbit\", Physical Review D 77, 044016 (2008), arXiv:0710.0614v1 [gr-qc].
94  */
96  REAL8TimeSeries *hplus, /**< +-polarization waveform */
97  REAL8TimeSeries *hcross, /**< x-polarization waveform */
98  COMPLEX16TimeSeries *hmode, /**< complex mode h(l,m) */
99  REAL8TimeSeries *theta, /**< polar angle (rad) */
100  REAL8TimeSeries *phi, /**< azimuthal angle (rad) */
101  int l, /**< mode number l */
102  int m, /**< mode number m */
103  int sym /**< flag to add -m mode too */
104  )
105 {
106  COMPLEX16 Y;
107  UINT4 j;
108 
118 
119 
120  for ( j = 0; j < hmode->data->length; ++j ) {
121  COMPLEX16 hpc;
122  Y = XLALSpinWeightedSphericalHarmonic(theta->data->data[j], phi->data->data[j], -2, l, m);
123  hpc = Y * hmode->data->data[j];
124  hplus->data->data[j] += creal(hpc);
125  hcross->data->data[j] += -cimag(hpc);
126  }
127  if ( sym ) { /* equatorial symmetry: add in -m mode */
128  if ( l % 2 ) /* l is odd */
129  Y = -Y;
130  for ( j = 0; j < hmode->data->length; ++j ) {
131  COMPLEX16 hpc;
132  Y = XLALSpinWeightedSphericalHarmonic(theta->data->data[j], phi->data->data[j], -2, l, -m);
133  hpc = Y * conj(hmode->data->data[j]);
134  hplus->data->data[j] += creal(hpc);
135  hcross->data->data[j] += -cimag(hpc);
136  }
137  }
138  return 0;
139 }
140 
141 
142 /**
143  * Helper function to add a mode to hplus, hcross in Fourier domain
144  * copies the function XLALSimAddMode, which was done only for TD structures
145  *
146  * If sym is non-zero, symmetrically add the m and -m terms assuming
147  * that \f$h(l,-m)(f) = (-1)^l h(l,m)*(-f) with f > 0 *\f$.
148  * Since the output is an array with positive frequencies, in the case of
149  * sym = 1 the modes that are passed should be the modes with negative m
150  * that have support for positive frequencies
151  */
153  COMPLEX16FrequencySeries *hptilde,
154  COMPLEX16FrequencySeries *hctilde,
155  COMPLEX16FrequencySeries *hlmtilde,
156  REAL8 theta,
157  REAL8 phi,
158  INT4 l,
159  INT4 m,
160  INT4 sym)
161 {
162  COMPLEX16 Y;
163  UINT4 j;
164  COMPLEX16 hlm; /* helper variable that contain a single point of hlmtilde */
165 
166 
167 
168  INT4 minus1l; /* (-1)^l */
169  if (l % 2)
170  minus1l = -1;
171  else
172  minus1l = 1;
173  if (sym)
174  { /* Equatorial symmetry: add in -m mode */
175  Y = XLALSpinWeightedSphericalHarmonic(theta, phi, -2, l, m);
176  COMPLEX16 Ymstar = conj(XLALSpinWeightedSphericalHarmonic(theta, phi, -2, l, -m));
177  COMPLEX16 factorp = 0.5 * (Y + minus1l * Ymstar);
178  COMPLEX16 factorc = I * 0.5 * (Y - minus1l * Ymstar);
179  for (j = 0; j < hlmtilde->data->length; ++j)
180  {
181  hlm = (hlmtilde->data->data[j]);
182  hptilde->data->data[j] += factorp * hlm;
183  hctilde->data->data[j] += factorc * hlm;
184  }
185  }
186  else
187  { /* not adding in the -m mode */
188  Y = XLALSpinWeightedSphericalHarmonic(theta, phi, -2, l, m);
189  COMPLEX16 factorp = 0.5 * Y;
190  COMPLEX16 factorc = I * factorp;
191  for (j = 0; j < hlmtilde->data->length; ++j)
192  {
193  hlm = (hlmtilde->data->data[j]);
194  hptilde->data->data[j] += factorp * hlm;
195  hctilde->data->data[j] += factorc * hlm;
196  }
197  }
198 
199  return XLAL_SUCCESS;
200 }
201 
202 
203 /**
204  * For all valid TimeSeries contained within hmode structure,
205  * multiplies a mode h(l,m) by a spin-2 weighted spherical harmonic
206  * to obtain hplus - i hcross, which is added to the time series.
207  *
208  * Implements the sum of Eq. (11) of:
209  * Lawrence E. Kidder, \"Using Full Information When Computing Modes of
210  * Post-Newtonian Waveforms From Inspiralling Compact Binaries in Circular
211  * Orbit\", Physical Review D 77, 044016 (2008), arXiv:0710.0614v1 [gr-qc].
212  */
214  REAL8TimeSeries *hplus, /**< +-polarization waveform */
215  REAL8TimeSeries *hcross, /**< x-polarization waveform */
216  SphHarmTimeSeries *hmode, /**< complex modes h(l,m) */
217  REAL8 theta, /**< polar angle (rad) */
218  REAL8 phi /**< azimuthal angle (rad) */
219  )
220 {
221  SphHarmTimeSeries* this = hmode;
222 
223  while ( this ) {
224  if ( !this->tdata ) {
225  this = this->next;
226  continue;
227  }
228 
229  XLALSimAddMode(hplus, hcross, hmode->mode, theta, phi, this->l, this->m, 1);
230  this = this->next;
231  }
232  return 0;
233 }
234 
235 /**
236  * For all valid TimeSeries contained within hmode structure,
237  * multiplies a mode h(l,m) by a spin-2 weighted spherical harmonic
238  * to obtain hplus - i hcross, which is added to the time series.
239  * Angles are TimeSeries too.
240  *
241  * Implements the sum of Eq. (11) of:
242  * Lawrence E. Kidder, \"Using Full Information When Computing Modes of
243  * Post-Newtonian Waveforms From Inspiralling Compact Binaries in Circular
244  * Orbit\", Physical Review D 77, 044016 (2008), arXiv:0710.0614v1 [gr-qc].
245  *
246  * @sa XLALSimAddModeAngleTimeSeries()
247  *
248  */
250  REAL8TimeSeries *hplus, /**< +-polarization waveform */
251  REAL8TimeSeries *hcross, /**< x-polarization waveform */
252  SphHarmTimeSeries *hmode, /**< complex modes h(l,m) */
253  REAL8TimeSeries *theta, /**< polar angle (rad) */
254  REAL8TimeSeries *phi /**< azimuthal angle (rad) */
255  )
256 {
257  SphHarmTimeSeries* this = hmode;
258 
259  while ( this ) {
260  if ( !this->tdata ) {
261  this = this->next;
262  continue;
263  }
264 
265  XLALSimAddModeAngleTimeSeries(hplus, hcross, hmode->mode, theta, phi, this->l, this->m, 1);
266  this = this->next;
267  }
268  return 0;
269 }
270 
271 /**
272  * Returns the h+, hx waveforms constructed from all valid TimeSeries
273  * contained within hmode structure.
274  *
275  * @sa XLALSimAddModeFromModes() and XLALSimAddMode()
276  */
278  REAL8TimeSeries **hplus, /**< +-polarization waveform */
279  REAL8TimeSeries **hcross, /**< x-polarization waveform */
280  SphHarmTimeSeries *hmode, /**< complex modes h(l,m) */
281  REAL8 theta, /**< polar angle (rad) */
282  REAL8 phi /**< azimuthal angle (rad) */
283  )
284 {
285 
286  if (!hmode) {
287  XLALPrintError("NULL mode structure passed.\n");
289  }
290  if (*hplus || *hcross) {
291  XLALPrintError("hplus and hcross time series must be NULL.\n");
293  }
294 
295  *hplus = XLALCreateREAL8TimeSeries("hplus", &(hmode->mode->epoch),
296  hmode->mode->f0, hmode->mode->deltaT, &lalStrainUnit,
297  hmode->mode->data->length);
298  *hcross = XLALCreateREAL8TimeSeries("hplus", &(hmode->mode->epoch),
299  hmode->mode->f0, hmode->mode->deltaT, &lalStrainUnit,
300  hmode->mode->data->length);
301  memset((*hplus)->data->data, 0, (*hplus)->data->length*sizeof(REAL8));
302  memset((*hcross)->data->data, 0, (*hcross)->data->length*sizeof(REAL8));
303 
304  XLALSimAddModeFromModes(*hplus, *hcross, hmode, theta, phi);
305 
306  return 0;
307 }
308 
309 /**
310  * Returns the h+, hx waveforms constructed from all valid TimeSeries
311  * contained within hmode structure. Angles are TimeSeries too.
312  *
313  * @sa XLALSimAddModeFromModesAngleTimeSeries() and XLALSimAddModeAngleTimeSeries()
314  */
316  REAL8TimeSeries **hplus, /**< +-polarization waveform */
317  REAL8TimeSeries **hcross, /**< x-polarization waveform */
318  SphHarmTimeSeries *hmode, /**< complex modes h(l,m) */
319  REAL8TimeSeries *theta, /**< polar angle (rad) */
320  REAL8TimeSeries *phi /**< azimuthal angle (rad) */
321  )
322 {
323 
324  if (!hmode) {
325  XLALPrintError("NULL mode structure passed.\n");
327  }
328  if (*hplus || *hcross) {
329  XLALPrintError("hplus and hcross time series must be NULL.\n");
331  }
332 
333  *hplus = XLALCreateREAL8TimeSeries("hplus", &(hmode->mode->epoch),
334  hmode->mode->f0, hmode->mode->deltaT, &lalStrainUnit,
335  hmode->mode->data->length);
336  *hcross = XLALCreateREAL8TimeSeries("hplus", &(hmode->mode->epoch),
337  hmode->mode->f0, hmode->mode->deltaT, &lalStrainUnit,
338  hmode->mode->data->length);
339  memset((*hplus)->data->data, 0, (*hplus)->data->length*sizeof(REAL8));
340  memset((*hcross)->data->data, 0, (*hcross)->data->length*sizeof(REAL8));
341 
342  XLALSimAddModeFromModesAngleTimeSeries(*hplus, *hcross, hmode, theta, phi);
343 
344  return 0;
345 }
346 
347 /** @} */
int l
Definition: bh_qnmode.c:135
double theta
Definition: bh_sphwf.c:118
#define LAL_CHECK_VALID_SERIES(s, val)
#define LAL_CHECK_CONSISTENT_TIME_SERIES(s1, s2, val)
#define LAL_CHECK_COMPATIBLE_BUT_UNIT_TIME_SERIES(s1, s2, val)
double complex COMPLEX16
double REAL8
uint32_t UINT4
int32_t INT4
int XLALSimAddModeAngleTimeSeries(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, COMPLEX16TimeSeries *hmode, REAL8TimeSeries *theta, REAL8TimeSeries *phi, int l, int m, int sym)
Multiplies a mode h(l,m) by a spin-2 weighted spherical harmonic to obtain hplus - i hcross,...
int XLALSimAddModeFromModesAngleTimeSeries(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, SphHarmTimeSeries *hmode, REAL8TimeSeries *theta, REAL8TimeSeries *phi)
For all valid TimeSeries contained within hmode structure, multiplies a mode h(l,m) by a spin-2 weigh...
int XLALSimAddModeFD(COMPLEX16FrequencySeries *hptilde, COMPLEX16FrequencySeries *hctilde, COMPLEX16FrequencySeries *hlmtilde, REAL8 theta, REAL8 phi, INT4 l, INT4 m, INT4 sym)
Helper function to add a mode to hplus, hcross in Fourier domain copies the function XLALSimAddMode,...
int XLALSimNewTimeSeriesFromModesAngleTimeSeries(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, SphHarmTimeSeries *hmode, REAL8TimeSeries *theta, REAL8TimeSeries *phi)
Returns the h+, hx waveforms constructed from all valid TimeSeries contained within hmode structure.
int XLALSimAddMode(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, COMPLEX16TimeSeries *hmode, REAL8 theta, REAL8 phi, int l, int m, int sym)
Multiplies a mode h(l,m) by a spin-2 weighted spherical harmonic to obtain hplus - i hcross,...
int XLALSimNewTimeSeriesFromModes(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, SphHarmTimeSeries *hmode, REAL8 theta, REAL8 phi)
Returns the h+, hx waveforms constructed from all valid TimeSeries contained within hmode structure.
int XLALSimAddModeFromModes(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, SphHarmTimeSeries *hmode, REAL8 theta, REAL8 phi)
For all valid TimeSeries contained within hmode structure, multiplies a mode h(l,m) by a spin-2 weigh...
static const INT4 m
COMPLEX16 XLALSpinWeightedSphericalHarmonic(REAL8 theta, REAL8 phi, int s, int l, int m)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
const LALUnit lalStrainUnit
#define XLAL_ERROR(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_EINVAL
XLAL_FAILURE
COMPLEX16Sequence * data
COMPLEX16Sequence * data
COMPLEX16 * data
REAL8Sequence * data
REAL8 * data
Structure to carry a collection of spherical harmonic modes in COMPLEX16 time series.
COMPLEX16TimeSeries * mode
The sequences of sampled data.