Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALPulsar 7.1.1.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ppe_models.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2014 Matthew Pitkin, Colin Gill, 2016 Max Isi
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
21/**
22 * \file
23 * \ingroup lalpulsar_bin_HeterodyneSearch
24 * \author Matthew Pitkin, Colin Gill, Max Isi
25 *
26 * \brief Pulsar model functions for use in parameter estimation codes for targeted pulsar searches.
27 */
28
29#include "config.h"
30#include "ppe_models.h"
31#include <lal/SinCosLUT.h>
32
33#define SQUARE(x) ( (x) * (x) )
34
35/******************************************************************************/
36/* MODEL FUNCTIONS */
37/******************************************************************************/
38
39/**
40 * \brief Defines the pulsar model/template to use
41 *
42 * This function is the wrapper for functions defining the pulsar model template to be used in the analysis.
43 * It places them into a \c PulsarParameters structure.
44 *
45 * Note: Any additional models should be added into this function.
46 *
47 * \param model [in] The model structure hold model information and current parameter info
48 *
49 * \sa add_pulsar_parameter
50 * \sa pulsar_model
51 */
53{
54 PulsarParameters *pars = XLALCalloc( sizeof( *pars ), 1 );
55
56 /* set model parameters (including rescaling) */
57 add_pulsar_parameter( model->params, pars, "PSI" );
58
59 if ( ( LALInferenceCheckVariableNonFixed( model->params, "H0" ) || LALInferenceCheckVariableNonFixed( model->params, "Q22" ) || LALInferenceCheckVariable( model->ifo->params, "source_model" ) ) && !LALInferenceCheckVariable( model->ifo->params, "nonGR" ) ) {
60 /* if searching in mass quadrupole, Q22, then check for distance and f0 and convert to h0 */
61 if ( LALInferenceCheckVariableNonFixed( model->params, "Q22" ) && !LALInferenceCheckVariableNonFixed( model->params, "H0" ) ) {
62 if ( LALInferenceCheckVariable( model->params, "F0" ) && LALInferenceCheckVariable( model->params, "DIST" ) ) {
63 /* convert Q22, distance and frequency into strain h0 using eqn 3 of Aasi et al, Ap. J., 785, 119 (2014) */
64 REAL8 Q22 = LALInferenceGetREAL8Variable( model->params, "Q22" );
67 REAL8 h0val = Q22 * sqrt( 8.*LAL_PI / 15. ) * 16.*LAL_PI * LAL_PI * LAL_G_SI * f0 * f0 / ( LAL_C_SI * LAL_C_SI * LAL_C_SI * LAL_C_SI * dist );
68 PulsarAddREAL8Param( pars, "H0", h0val );
69 } else {
70 XLAL_ERROR_VOID( XLAL_EINVAL, "Error... using mass quadrupole, Q22, but no distance or frequency given!" );
71 }
72 } else if ( LALInferenceCheckVariableNonFixed( model->params, "Q22" ) && LALInferenceCheckVariableNonFixed( model->params, "H0" ) ) {
73 XLAL_ERROR_VOID( XLAL_EINVAL, "Error... cannot have both h0 and Q22 as variables." );
74 } else if ( LALInferenceCheckVariableNonFixed( model->params, "H0" ) ) {
75 add_pulsar_parameter( model->params, pars, "H0" );
76 }
77
78 /* use parameterisation from Ian Jones's original model */
79 add_pulsar_parameter( model->params, pars, "I21" );
80 add_pulsar_parameter( model->params, pars, "I31" );
81 add_pulsar_parameter( model->params, pars, "LAMBDA" );
82
83 /* check whether using cos(theta) or theta as the variable (defaulting to cos(theta) being the value that is set */
84 if ( LALInferenceCheckVariableNonFixed( model->params, "THETA" ) ) {
85 REAL8 costheta = cos( LALInferenceGetREAL8Variable( model->params, "THETA" ) );
86 PulsarAddREAL8Param( pars, "COSTHETA", costheta );
87 } else {
88 add_pulsar_parameter( model->params, pars, "COSTHETA" );
89 }
90 add_pulsar_parameter( model->params, pars, "PHI0" ); /* note that this is the rotational phase */
91
92 /* check whether using cos(iota) or iota as the variable (defaulting to cos(iota) being the value that is set) */
93 if ( LALInferenceCheckVariableNonFixed( model->params, "IOTA" ) ) {
94 REAL8 cosiota = cos( LALInferenceGetREAL8Variable( model->params, "IOTA" ) );
95 PulsarAddREAL8Param( pars, "COSIOTA", cosiota );
96 } else {
97 add_pulsar_parameter( model->params, pars, "COSIOTA" );
98 }
99
100 invert_source_params( pars );
101 } else if ( LALInferenceCheckVariable( model->ifo->params, "nonGR" ) ) {
102 /* speed of GWs as (1 - fraction of speed of light LAL_C_SI) */
103 add_pulsar_parameter( model->params, pars, "CGW" );
104
105 /* amplitudes for use with non-GR searches (with emission at twice the rotation frequency) */
106 /* tensor modes */
107 add_pulsar_parameter( model->params, pars, "HPLUS" );
108 add_pulsar_parameter( model->params, pars, "HCROSS" );
109 /* scalar modes */
110 add_pulsar_parameter( model->params, pars, "HSCALARB" );
111 add_pulsar_parameter( model->params, pars, "HSCALARL" );
112 /* vector modes */
113 add_pulsar_parameter( model->params, pars, "HVECTORX" );
114 add_pulsar_parameter( model->params, pars, "HVECTORY" );
115
116 add_pulsar_parameter( model->params, pars, "PHI0SCALAR" );
117 add_pulsar_parameter( model->params, pars, "PSISCALAR" );
118 add_pulsar_parameter( model->params, pars, "PHI0VECTOR" );
119 add_pulsar_parameter( model->params, pars, "PSIVECTOR" );
120 add_pulsar_parameter( model->params, pars, "PHI0TENSOR" );
121 add_pulsar_parameter( model->params, pars, "PSITENSOR" );
122
123 /* amplitudes for use in non-GR searches with emission at the rotation frequency */
124 /* tensor modes */
125 add_pulsar_parameter( model->params, pars, "HPLUS_F" );
126 add_pulsar_parameter( model->params, pars, "HCROSS_F" );
127 /* scalar modes */
128 add_pulsar_parameter( model->params, pars, "HSCALARB_F" );
129 add_pulsar_parameter( model->params, pars, "HSCALARL_F" );
130 /* vector modes */
131 add_pulsar_parameter( model->params, pars, "HVECTORX_F" );
132 add_pulsar_parameter( model->params, pars, "HVECTORY_F" );
133
134 add_pulsar_parameter( model->params, pars, "PHI0SCALAR_F" );
135 add_pulsar_parameter( model->params, pars, "PSISCALAR_F" );
136 add_pulsar_parameter( model->params, pars, "PHI0VECTOR_F" );
137 add_pulsar_parameter( model->params, pars, "PSIVECTOR_F" );
138 add_pulsar_parameter( model->params, pars, "PHI0TENSOR_F" );
139 add_pulsar_parameter( model->params, pars, "PSITENSOR_F" );
140
141 /* parameters that might be needed for particular models */
142 add_pulsar_parameter( model->params, pars, "H0" );
143 add_pulsar_parameter( model->params, pars, "H0_F" );
144 add_pulsar_parameter( model->params, pars, "IOTA" );
145 add_pulsar_parameter( model->params, pars, "COSIOTA" );
146
147 /* check whether a specific nonGR model was requested */
148 if ( LALInferenceCheckVariable( model->ifo->params, "nonGRmodel" ) ) {
149 char *nonGRmodel;
150 nonGRmodel = *( char ** )LALInferenceGetVariable( model->ifo->params, "nonGRmodel" );
151 set_nonGR_model_parameters( pars, nonGRmodel );
152 }
153 } else {
154 /* amplitude for usual GR search */
155 add_pulsar_parameter( model->params, pars, "C21" );
156 add_pulsar_parameter( model->params, pars, "C22" );
157 add_pulsar_parameter( model->params, pars, "PHI21" );
158
159 /* check whether using cos(theta) or theta as the variable (defaulting to cos(theta) being the value that is set */
160 if ( LALInferenceCheckVariableNonFixed( model->params, "IOTA" ) ) {
161 REAL8 cosiota = cos( LALInferenceGetREAL8Variable( model->params, "IOTA" ) );
162 PulsarAddREAL8Param( pars, "COSIOTA", cosiota );
163 } else {
164 add_pulsar_parameter( model->params, pars, "COSIOTA" );
165 }
166
167 if ( LALInferenceCheckVariable( model->ifo->params, "biaxial" ) ) {
168 /* use complex amplitude parameterisation, but set up for a biaxial star */
169 REAL8 phi22 = 2.*LALInferenceGetREAL8Variable( model->params, "PHI21" );
170 PulsarAddREAL8Param( pars, "PHI22", phi22 );
171 } else {
172 add_pulsar_parameter( model->params, pars, "PHI22" );
173 }
174 }
175
176 /* set the potentially variable parameters */
177 add_pulsar_parameter( model->params, pars, "PEPOCH" );
178 add_pulsar_parameter( model->params, pars, "POSEPOCH" );
179
180 add_pulsar_parameter( model->params, pars, "RA" );
181 add_pulsar_parameter( model->params, pars, "PMRA" );
182 add_pulsar_parameter( model->params, pars, "DEC" );
183 add_pulsar_parameter( model->params, pars, "PMDEC" );
184 add_pulsar_parameter( model->params, pars, "PX" );
185
186 /* check the number of frequency and frequency derivative parameters */
187 if ( LALInferenceCheckVariable( model->params, "FREQNUM" ) ) {
188 UINT4 freqnum = LALInferenceGetUINT4Variable( model->params, "FREQNUM" );
189 REAL8Vector *freqs = XLALCreateREAL8Vector( freqnum );
190 REAL8Vector *deltafreqs = XLALCreateREAL8Vector( freqnum );
191 for ( UINT4 i = 0; i < freqnum; i++ ) {
192 CHAR varname[256];
193 snprintf( varname, sizeof( varname ), "F%u", i );
194 REAL8 f0new = LALInferenceGetREAL8Variable( model->params, varname );
195 freqs->data[i] = f0new; /* current frequency (derivative) */
196 snprintf( varname, sizeof( varname ), "F%u_FIXED", i );
197 REAL8 f0fixed = LALInferenceGetREAL8Variable( model->params, varname );
198 deltafreqs->data[i] = f0new - f0fixed; /* frequency (derivative) difference */
199 }
200 PulsarAddREAL8VectorParam( pars, "F", ( const REAL8Vector * )freqs );
201 PulsarAddREAL8VectorParam( pars, "DELTAF", ( const REAL8Vector * )deltafreqs );
202 XLALDestroyREAL8Vector( freqs );
203 XLALDestroyREAL8Vector( deltafreqs );
204 }
205
206 /* check if there are glitch parameters */
207 if ( LALInferenceCheckVariable( model->ifo->params, "GLITCHES" ) ) {
208 if ( LALInferenceCheckVariable( model->params, "GLNUM" ) ) { /* number of glitches */
209 UINT4 glnum = LALInferenceGetUINT4Variable( model->params, "GLNUM" );
210 for ( UINT4 i = 0; i < NUMGLITCHPARS; i++ ) {
211 REAL8Vector *gl = NULL;
212 gl = XLALCreateREAL8Vector( glnum );
213 for ( UINT4 j = 0; j < glnum; j++ ) {
214 CHAR varname[300];
215 snprintf( varname, sizeof( varname ), "%s_%u", glitchpars[i], j + 1 );
216 if ( LALInferenceCheckVariable( model->params, varname ) ) {
217 gl->data[j] = LALInferenceGetREAL8Variable( model->params, varname );
218 } else {
219 gl->data[j] = 0.;
220 }
221 }
222 PulsarAddREAL8VectorParam( pars, glitchpars[i], ( const REAL8Vector * )gl );
224 }
225 }
226 }
227
228 /* check if there are binary parameters */
229 if ( LALInferenceCheckVariable( model->ifo->params, "BINARY" ) ) {
230 /* binary system model - NOT pulsar model */
231 CHAR binary[PULSAR_PARNAME_MAX];
232 snprintf( binary, PULSAR_PARNAME_MAX * sizeof( CHAR ), "%s", *( CHAR ** )LALInferenceGetVariable( model->ifo->params, "BINARY" ) );
233 PulsarAddStringParam( pars, "BINARY", binary );
234
235 add_pulsar_parameter( model->params, pars, "ECC" );
236 add_pulsar_parameter( model->params, pars, "OM" );
237 add_pulsar_parameter( model->params, pars, "PB" );
238 add_pulsar_parameter( model->params, pars, "A1" );
239 add_pulsar_parameter( model->params, pars, "T0" );
240
241 add_pulsar_parameter( model->params, pars, "ECC_2" );
242 add_pulsar_parameter( model->params, pars, "OM_2" );
243 add_pulsar_parameter( model->params, pars, "PB_2" );
244 add_pulsar_parameter( model->params, pars, "A1_2" );
245 add_pulsar_parameter( model->params, pars, "T0_2" );
246
247 add_pulsar_parameter( model->params, pars, "ECC_3" );
248 add_pulsar_parameter( model->params, pars, "OM_3" );
249 add_pulsar_parameter( model->params, pars, "PB_3" );
250 add_pulsar_parameter( model->params, pars, "A1_3" );
251 add_pulsar_parameter( model->params, pars, "T0_3" );
252
253 add_pulsar_parameter( model->params, pars, "XPBDOT" );
254 add_pulsar_parameter( model->params, pars, "EPS1" );
255 add_pulsar_parameter( model->params, pars, "EPS2" );
256 add_pulsar_parameter( model->params, pars, "EPS1DOT" );
257 add_pulsar_parameter( model->params, pars, "EPS2DOT" );
258 add_pulsar_parameter( model->params, pars, "TASC" );
259
260 add_pulsar_parameter( model->params, pars, "OMDOT" );
261 add_pulsar_parameter( model->params, pars, "GAMMA" );
262 add_pulsar_parameter( model->params, pars, "PBDOT" );
263 add_pulsar_parameter( model->params, pars, "XDOT" );
264 add_pulsar_parameter( model->params, pars, "EDOT" );
265
266 add_pulsar_parameter( model->params, pars, "SINI" );
267 add_pulsar_parameter( model->params, pars, "DR" );
268 add_pulsar_parameter( model->params, pars, "DTHETA" );
269 add_pulsar_parameter( model->params, pars, "A0" );
270 add_pulsar_parameter( model->params, pars, "B0" );
271
272 add_pulsar_parameter( model->params, pars, "MTOT" );
273 add_pulsar_parameter( model->params, pars, "M2" );
274
275 if ( LALInferenceCheckVariable( model->params, "FBNUM" ) ) {
276 UINT4 fbnum = LALInferenceGetUINT4Variable( model->params, "FBNUM" );
277 REAL8Vector *fb = NULL;
278 fb = XLALCreateREAL8Vector( fbnum );
279 for ( UINT4 i = 0; i < fbnum; i++ ) {
280 CHAR varname[256];
281 snprintf( varname, sizeof( varname ), "FB%u", i );
282 fb->data[i] = LALInferenceGetREAL8Variable( model->params, varname );
283 }
284 PulsarAddREAL8VectorParam( pars, "FB", ( const REAL8Vector * )fb );
286 }
287 }
288
289 pulsar_model( pars, model->ifo );
290
291 PulsarFreeParams( pars ); /* free memory */
292}
293
294/**
295 * \brief Set amplitude parameters for specific non-GR models.
296 *
297 * Turns physical parameters from a particular nonGR model into the corresponding antenna pattern amplitudes and phases. All nonGR models must be included here.
298 * \param pars [in] parameter structure
299 * \param nonGRmodel [in] name of model requested
300 */
301void set_nonGR_model_parameters( PulsarParameters *pars, char *nonGRmodel )
302{
303 /* determine what model was requested */
304 int isG4v = strcmp( nonGRmodel, "G4v" ) * strcmp( nonGRmodel, "g4v" ) * strcmp( nonGRmodel, "G4V" );
305 int isEGR = strcmp( nonGRmodel, "enhanced-GR" ) * strcmp( nonGRmodel, "EGR" ) * strcmp( nonGRmodel, "egr" ) * strcmp( nonGRmodel, "eGR" );
306 REAL8 h0 = PulsarGetREAL8ParamOrZero( pars, "H0" );
307 REAL8 h0_F = PulsarGetREAL8ParamOrZero( pars, "H0_F" );
308
309 REAL8 iota = PulsarGetREAL8ParamOrZero( pars, "IOTA" );
310 REAL8 cosiota = cos( iota );
311 REAL8 siniota = sin( iota );
312
313 /* check if COSIOTA was passed directly instead */
314 if ( PulsarGetREAL8ParamOrZero( pars, "COSIOTA" ) != 0 ) {
315 cosiota = PulsarGetREAL8ParamOrZero( pars, "COSIOTA" );
316 siniota = sin( acos( cosiota ) );
317 }
318
319 if ( isG4v == 0 ) {
320 /* \f$ h_{\rm x} = h_0 \sin \iota~,~\phi_{\rm x} = -\pi/2 \f$ */
321 /* \f$ h_{\rm y} = h_0 \sin \iota \cos \iota~,~\phi_{\rm y} = 0 \f$ */
322 REAL8 hVectorX = h0 * siniota;
323 REAL8 hVectorY = h0 * siniota * cosiota;
324 REAL8 psiVector = LAL_PI_2;
325 PulsarAddREAL8Param( pars, "HVECTORX", hVectorX );
326 PulsarAddREAL8Param( pars, "HVECTORY", hVectorY );
327 PulsarAddREAL8Param( pars, "PSIVECTOR", psiVector );
328 } else if ( isEGR == 0 ) {
329 /** GR plus unconstrained non-GR modes
330 * With different priors, this can be used to obtain GR+scalar (i.e.
331 * scalar-tensor), GR+vector, or GR+scalar+vector. Note: this mode used to
332 be called just "ST".*/
333 REAL8 psiTensor = -LAL_PI_2;
334 /* Set 1F components */
335 REAL8 hPlus_F = 0.25 * h0_F * siniota * cosiota;
336 REAL8 hCross_F = 0.5 * h0_F * siniota;
337 PulsarAddREAL8Param( pars, "HPLUS_F", hPlus_F );
338 PulsarAddREAL8Param( pars, "HCROSS_F", hCross_F );
339 PulsarAddREAL8Param( pars, "PSITENSOR_F", psiTensor );
340 /* Set 2F components */
341 REAL8 hPlus = 0.5 * h0 * ( 1. + cosiota * cosiota );
342 REAL8 hCross = h0 * cosiota;
343 PulsarAddREAL8Param( pars, "HPLUS", hPlus );
344 PulsarAddREAL8Param( pars, "HCROSS", hCross );
345 PulsarAddREAL8Param( pars, "PSITENSOR", psiTensor );
346 } else {
347 XLAL_ERROR_VOID( XLAL_EINVAL, "Unrecognized non-GR model. Currently supported: enhanced GR (EGR), G4v, or no argument for full search." );
348 }
349}
350
351
352/**
353 * \brief Add a \c REAL8 parameter from a \c LALInferenceVariable into a \c PulsarParameters variable
354 *
355 * \param var [in] \c LALInferenceVariable structure
356 * \param params [in] \c PulsarParameters structure
357 * \param parname [in] name of the parameter
358 */
360{
361 REAL8 par = LALInferenceGetREAL8Variable( var, parname );
362 PulsarAddREAL8Param( params, parname, par );
363}
364
365
366/**
367 * \brief Add a \c REAL8 parameter from a \c PulsarParameters variable into a \c LALInferenceVariable
368 *
369 * This function will rescale a parameter to its true value using the scale factor and minimum scale value.
370 *
371 * \param params [in] \c PulsarParameters structure
372 * \param var [in] \c LALInferenceVariable structure
373 * \param parname [in] name of the parameter
374 * \param vary [in] the parameter \c LALInferenceParamVaryType
375 */
377{
379 LALInferenceAddVariable( var, parname, &par, LALINFERENCE_REAL8_t, vary );
380}
381
382
383/**
384 * \brief Generate the model of the neutron star signal
385 *
386 * The function requires that the pulsar model is set using the \c model-type command line argument (this is set in \c
387 * main, and if not specified defaults to a \c triaxial model). Currently the model can be \c triaxial for quadrupole
388 * emission from a triaxial star at twice the rotation freqeuncy, or \c pinsf for a two component emission model with
389 * emission at the rotation frequency <i>and</i> twice the rotation frequency. Depending on the specified model the
390 * function calls the appropriate model function.
391 *
392 * Firstly the time varying amplitude of the signal will be calculated based on the antenna pattern and amplitude
393 * parameters. Then, if searching over phase parameters, the phase evolution of the signal will be calculated. The
394 * difference between the new phase model, \f$ \phi(t)_n \f$ , and that used to heterodyne the data, \f$ \phi(t)_h \f$ ,
395 * will be calculated and the complex signal model, \f$ M \f$ , modified accordingly:
396 * \f[
397 * M'(t) = M(t)\exp{i((\phi(t)_n - \phi(t)_h))}.
398 * \f]
399 * This does not try to undo the signal modulation in the data, but instead replicates the modulation in the model,
400 * hence the positive phase difference rather than a negative phase in the exponential function.
401 *
402 * \param params [in] A \c PulsarParameters structure containing the model parameters
403 * \param ifo [in] The ifo model structure containing the detector paramters and buffers
404 *
405 * \sa get_amplitude_model
406 * \sa get_phase_model
407 */
409{
410 INT4 i = 0, length = 0;
411 UINT4 j = 0;
412 LALInferenceIFOModel *ifomodel1 = ifo, *ifomodel2 = ifo;
413
414 /* get the amplitude model */
415 get_amplitude_model( params, ifomodel1 );
416
417 /* check whether to search over the phase parameters or not - this only needs to be set for the
418 * first ifo linked list in at set for a given detector (i.e. it doesn't need to be set for
419 * different frequency streams */
420 if ( LALInferenceCheckVariable( ifomodel2->params, "varyphase" ) ) {
421 /* get difference in phase for f component and perform extra heterodyne */
422 REAL8Vector *freqFactors = NULL;
423 freqFactors = *( REAL8Vector ** )LALInferenceGetVariable( ifo->params, "freqfactors" );
424
425 while ( ifomodel2 ) {
426 for ( j = 0; j < freqFactors->length; j++ ) {
427 REAL8Vector *dphi = NULL;
428 COMPLEX16 M = 0., expp = 0.;
429
430 length = ifomodel2->compTimeSignal->data->length;
431
432 /* reheterodyne with the phase */
433 if ( ( dphi = get_phase_model( params, ifomodel2, freqFactors->data[j] ) ) != NULL ) {
434 for ( i = 0; i < length; i++ ) {
435 /* phase factor by which to multiply the (almost) DC signal model. NOTE: this does not try to undo
436 * the signal modulation in the data, but instead replicates it in the model, hence the positive
437 * phase rather than a negative phase in the cexp function. */
438 expp = cexp( LAL_TWOPI * I * dphi->data[i] );
439
440 M = ifomodel2->compTimeSignal->data->data[i];
441
442 /* heterodyne */
443 ifomodel2->compTimeSignal->data->data[i] = M * expp;
444 }
445
447 }
448
449 ifomodel2 = ifomodel2->next;
450 }
451 }
452 }
453}
454
455
456/**
457 * \brief The phase evolution of a source
458 *
459 * This function will calculate the difference in the phase evolution of a source at a particular sky location as
460 * observed at Earth compared with that used to heterodyne (or SpectralInterpolate) the data. If the phase
461 * evolution is described by a Taylor expansion:
462 * \f[
463 * \phi(T) = \sum_{k=1}^n \frac{f^{(k-1)}}{k!} T^k,
464 * \f]
465 * where \f$ f^(x) \f$ is the xth time derivative of the gravitational wave frequency, and \f$ T \f$ is the pulsar proper
466 * time, then the phase difference is given by
467 * \f[
468 * \Delta\phi(t) = \sum_{k=1}^n \left( \frac{\Delta f^{(k-1)}}{k!}(t+\delta t_1)^k + \frac{f^{(k-1)}_2}{k!} \sum_{i=0}^{i<k} \left(\begin{array}{c}k \\ i\end{array}\right) (\Delta t)^{k-i} (t+\delta t_1)^i \right),
469 * \f]
470 * where \f$ t \f$ is the signal arrival time at the detector minus the given pulsar period epoch, \f$ \delta t_1 \f$ is the barycentring time delay
471 * (from both solar system and binary orbital effects) calculated at the heterodyned values, \f$ \Delta f^{(x)} = f_2^{(x)}-f1^{(x)} \f$
472 * is the diffence in frequency (derivative) between the current value ( \f$ f_2^{(x)} \f$ ) and the heterodyne value ( \f$ \f_1^{(x)} \f$ ),
473 * and \f$ \Delta t = \delta t_2 - \delta t_1 \f$ is the difference between the barycentring time delay calculated at the
474 * current values ( \f$ \delta t_1 \f$ ) and the heterodyned values.
475 * Frequency time derivatives are currently allowed up to the tenth derivative. The pulsar proper time is
476 * calculated by correcting the time of arrival at Earth, \f$ t \f$ to the solar system barycentre and if necessary the
477 * binary system barycenter, so \f$ T = t + \delta{}t_{\rm SSB} + \delta{}t_{\rm BSB} \f$ .
478 *
479 * In this function the time delay needed to correct to the solar system barycenter is only calculated if
480 * required, i.e., if an update is required due to a change in the sky position.
481 * The same is true for the binary system time delay, which is only calculated if it
482 * needs updating due to a change in the binary system parameters.
483 *
484 * \param params [in] A set of pulsar parameters
485 * \param ifo [in] The ifo model structure containing the detector parameters and buffers
486 * \param freqFactor [in] the multiplicative factor on the pulsar frequency for a particular model
487 *
488 * \return A vector of rotational phase difference values
489 *
490 * \sa get_ssb_delay
491 * \sa get_bsb_delay
492 */
494{
495 UINT4 i = 0, j = 0, k = 0, length = 0, isbinary = 0;
496
497 REAL8 DT = 0., deltat = 0., deltatpow = 0., deltatpowinner = 1., taylorcoeff = 1., Ddelay = 0., Ddelaypow = 0.;
498
499 REAL8Vector *phis = NULL, *dts = NULL, *fixdts = NULL, *bdts = NULL, *fixbdts = NULL, *glitchphase = NULL, *fixglitchphase = NULL;
500 LIGOTimeGPSVector *datatimes = NULL;
501
502 REAL8 pepoch = PulsarGetREAL8ParamOrZero( params, "PEPOCH" ); /* time of ephem info */
503 REAL8 cgw = PulsarGetREAL8ParamOrZero( params, "CGW" );
504 REAL8 T0 = pepoch;
505
506 /* check if we want to calculate the phase at a the downsampled rate */
507 datatimes = IFO_XTRA_DATA( ifo )->times;
508
509 /* if edat is NULL then return a NULL pointer */
510 if ( IFO_XTRA_DATA( ifo )->ephem == NULL ) {
511 return NULL;
512 }
513
514 length = datatimes->length;
515
516 /* allocate memory for phases */
517 phis = XLALCreateREAL8Vector( length );
518
519 /* get time delays */
520 fixdts = LALInferenceGetREAL8VectorVariable( ifo->params, "ssb_delays" );
521 if ( LALInferenceCheckVariable( ifo->params, "varyskypos" ) ) {
522 dts = get_ssb_delay( params, datatimes, IFO_XTRA_DATA( ifo )->ephem, IFO_XTRA_DATA( ifo )->tdat, IFO_XTRA_DATA( ifo )->ttype, ifo->detector );
523 }
524
525 if ( LALInferenceCheckVariable( ifo->params, "varybinary" ) ) {
526 /* get binary system time delays */
527 if ( dts != NULL ) {
528 bdts = get_bsb_delay( params, datatimes, dts, IFO_XTRA_DATA( ifo )->ephem );
529 } else {
530 bdts = get_bsb_delay( params, datatimes, fixdts, IFO_XTRA_DATA( ifo )->ephem );
531 }
532 }
533 if ( LALInferenceCheckVariable( ifo->params, "bsb_delays" ) ) {
534 fixbdts = LALInferenceGetREAL8VectorVariable( ifo->params, "bsb_delays" );
535 }
536
537 /* get vector of frequencies and frequency differences */
538 const REAL8Vector *freqs = PulsarGetREAL8VectorParam( params, "F" );
539 const REAL8Vector *deltafs = PulsarGetREAL8VectorParam( params, "DELTAF" );
540
541 if ( PulsarCheckParam( params, "BINARY" ) ) {
542 isbinary = 1; /* see if pulsar is in binary */
543 }
544
545 if ( LALInferenceCheckVariable( ifo->params, "varyglitch" ) ) {
546 /* get the phase (in cycles due to glitch parameters */
547 if ( dts != NULL ) {
548 if ( LALInferenceCheckVariable( ifo->params, "varybinary" ) ) {
549 glitchphase = get_glitch_phase( params, datatimes, dts, bdts );
550 } else {
551 glitchphase = get_glitch_phase( params, datatimes, dts, fixbdts );
552 }
553 } else {
554 if ( LALInferenceCheckVariable( ifo->params, "varybinary" ) ) {
555 glitchphase = get_glitch_phase( params, datatimes, fixdts, bdts );
556 } else {
557 glitchphase = get_glitch_phase( params, datatimes, fixdts, fixbdts );
558 }
559 }
560 }
561 if ( LALInferenceCheckVariable( ifo->params, "glitch_phase" ) ) {
562 fixglitchphase = LALInferenceGetREAL8VectorVariable( ifo->params, "glitch_phase" );
563 }
564
565 for ( i = 0; i < length; i++ ) {
566 REAL8 deltaphi = 0., innerphi = 0.; /* change in phase */
567 Ddelay = 0.; /* change in SSB/BSB delay */
568
569 REAL8 realT = XLALGPSGetREAL8( &datatimes->data[i] ); /* time of data */
570 DT = realT - T0; /* time diff between data and start of data */
571
572 /* get difference in solar system barycentring time delays */
573 if ( dts != NULL ) {
574 Ddelay += ( dts->data[i] - fixdts->data[i] );
575 }
576 deltat = DT + fixdts->data[i];
577
578 if ( isbinary ) {
579 /* get difference in binary system barycentring time delays */
580 if ( bdts != NULL && fixbdts != NULL ) {
581 Ddelay += ( bdts->data[i] - fixbdts->data[i] );
582 }
583 deltat += fixbdts->data[i];
584 }
585
586 /* correct for speed of GW compared to speed of light */
587 if ( cgw > 0.0 && cgw < 1. ) {
588 deltat /= cgw;
589 Ddelay /= cgw;
590 }
591
592 /* get the change in phase (compared to the heterodyned phase) */
593 deltatpow = deltat;
594 for ( j = 0; j < freqs->length; j++ ) {
595 taylorcoeff = gsl_sf_fact( j + 1 );
596 deltaphi += deltafs->data[j] * deltatpow / taylorcoeff;
597 if ( Ddelay != 0. ) {
598 innerphi = 0.;
599 deltatpowinner = 1.; /* this starts as one as it is first raised to the power of zero */
600 Ddelaypow = pow( Ddelay, j + 1 );
601 for ( k = 0; k < j + 1; k++ ) {
602 innerphi += gsl_sf_choose( j + 1, k ) * Ddelaypow * deltatpowinner;
603 deltatpowinner *= deltat; /* raise power */
604 Ddelaypow /= Ddelay; /* reduce power */
605 }
606 deltaphi += innerphi * freqs->data[j] / taylorcoeff;
607 }
608 deltatpow *= deltat;
609 }
610
611 /* get the differences for glitch phases */
612 if ( glitchphase != NULL ) {
613 deltaphi += ( glitchphase->data[i] - fixglitchphase->data[i] );
614 }
615
616 deltaphi *= freqFactor; /* multiply by frequency factor */
617 phis->data[i] = deltaphi - floor( deltaphi ); /* only need to keep the fractional part of the phase */
618 }
619
620 /* free memory */
621 if ( dts != NULL ) {
623 }
624 if ( bdts != NULL ) {
626 }
627 if ( glitchphase != NULL ) {
628 XLALDestroyREAL8Vector( glitchphase );
629 }
630
631 return phis;
632}
633
634
635/**
636 * \brief Computes the delay between a GPS time at Earth and the solar system barycentre
637 *
638 * This function calculate the time delay between a GPS time at a specific location (e.g. a gravitational wave detector)
639 * on Earth and the solar system barycentre. The delay consists of three components: the geometric time delay (Roemer
640 * delay) \f$ t_R = \mathbf{r}(t)\hat{n}/c \f$ (where \f$ \mathbf{r}(t) \f$ is the detector's position vector at time
641 * \f$ t \f$ ), the special relativistic Einstein delay \f$ t_E \f$ , and the general relativistic Shapiro delay \f$ t_S \f$ .
642 *
643 * Rather than computing the time delay at every time stamp passed to the function it is instead (if requested) able to
644 * perform linear interpolation to a point within a range given by \c interptime.
645 *
646 * \param pars [in] A set of pulsar parameters
647 * \param datatimes [in] A vector of GPS times at Earth
648 * \param ephem [in] Information on the solar system ephemeris
649 * \param detector [in] Information on the detector position on the Earth
650 * \param tdat *UNDOCUMENTED*
651 * \param ttype *UNDOCUMENTED*
652 * \return A vector of time delays in seconds
653 *
654 * \sa XLALBarycenter
655 * \sa XLALBarycenterEarth
656 */
659{
660 INT4 i = 0, length = 0;
661
662 BarycenterInput bary;
663
664 REAL8Vector *dts = NULL;
665
666 /* if edat is NULL then return a NULL poniter */
667 if ( ephem == NULL ) {
668 return NULL;
669 }
670
671 /* copy barycenter and ephemeris data */
672 bary.site.location[0] = detector->location[0] / LAL_C_SI;
673 bary.site.location[1] = detector->location[1] / LAL_C_SI;
674 bary.site.location[2] = detector->location[2] / LAL_C_SI;
675
676 REAL8 ra = 0.;
677 if ( PulsarCheckParam( pars, "RA" ) ) {
678 ra = PulsarGetREAL8Param( pars, "RA" );
679 } else if ( PulsarCheckParam( pars, "RAJ" ) ) {
680 ra = PulsarGetREAL8Param( pars, "RAJ" );
681 } else {
682 XLAL_ERROR_NULL( XLAL_EINVAL, "No source right ascension specified!" );
683 }
684 REAL8 dec = 0.;
685 if ( PulsarCheckParam( pars, "DEC" ) ) {
686 dec = PulsarGetREAL8Param( pars, "DEC" );
687 } else if ( PulsarCheckParam( pars, "DECJ" ) ) {
688 dec = PulsarGetREAL8Param( pars, "DECJ" );
689 } else {
690 XLAL_ERROR_NULL( XLAL_EINVAL, "No source declination specified!" );
691 }
692 REAL8 pmra = PulsarGetREAL8ParamOrZero( pars, "PMRA" );
693 REAL8 pmdec = PulsarGetREAL8ParamOrZero( pars, "PMDEC" );
694 REAL8 pepoch = PulsarGetREAL8ParamOrZero( pars, "PEPOCH" );
695 REAL8 posepoch = PulsarGetREAL8ParamOrZero( pars, "POSEPOCH" );
696 REAL8 px = PulsarGetREAL8ParamOrZero( pars, "PX" ); /* parallax */
697
698 /* set the position and frequency epochs if not already set */
699 if ( pepoch == 0. && posepoch != 0. ) {
700 pepoch = posepoch;
701 } else if ( posepoch == 0. && pepoch != 0. ) {
702 posepoch = pepoch;
703 }
704
705 length = datatimes->length;
706
707 /* allocate memory for times delays */
708 dts = XLALCreateREAL8Vector( length );
709
710 /* set 1/distance if parallax value is given (1/sec) */
711 if ( px != 0. ) {
712 bary.dInv = px * ( LAL_C_SI / LAL_AU_SI );
713 } else {
714 bary.dInv = 0.;
715 }
716
717 /* make sure ra and dec are wrapped within 0--2pi and -pi.2--pi/2 respectively */
718 ra = fmod( ra, LAL_TWOPI );
719 REAL8 absdec = fabs( dec );
720 if ( absdec > LAL_PI_2 ) {
721 UINT4 nwrap = floor( ( absdec + LAL_PI_2 ) / LAL_PI );
722 dec = ( dec > 0 ? 1. : -1. ) * ( nwrap % 2 == 1 ? -1. : 1. ) * ( fmod( absdec + LAL_PI_2, LAL_PI ) - LAL_PI_2 );
723 ra = fmod( ra + ( REAL8 )nwrap * LAL_PI, LAL_TWOPI ); /* move RA by pi */
724 }
725
726 EarthState earth;
727 EmissionTime emit;
728 for ( i = 0; i < length; i++ ) {
729 REAL8 realT = XLALGPSGetREAL8( &datatimes->data[i] );
730
731 bary.tgps = datatimes->data[i];
732 bary.delta = dec + ( realT - posepoch ) * pmdec;
733 bary.alpha = ra + ( realT - posepoch ) * pmra / cos( bary.delta );
734
735 /* call barycentring routines */
736 XLAL_CHECK_NULL( XLALBarycenterEarthNew( &earth, &bary.tgps, ephem, tdat, ttype ) == XLAL_SUCCESS, XLAL_EFUNC, "Barycentring routine failed" );
737 XLAL_CHECK_NULL( XLALBarycenter( &emit, &bary, &earth ) == XLAL_SUCCESS, XLAL_EFUNC, "Barycentring routine failed" );
738
739 dts->data[i] = emit.deltaT;
740 }
741
742 return dts;
743}
744
745
746/**
747 * \brief Computes the delay between a pulsar in a binary system and the barycentre of the system
748 *
749 * This function uses \c XLALBinaryPulsarDeltaT to calculate the time delay between for a pulsar in a binary system
750 * between the time at the pulsar and the time at the barycentre of the system. This includes Roemer delays and
751 * relativistic delays. The orbit may be described by different models and can be purely Keplarian or include various
752 * relativistic corrections.
753 *
754 * \param pars [in] A set of pulsar parameters
755 * \param datatimes [in] A vector of GPS times
756 * \param dts [in] A vector of solar system barycentre time delays
757 * \param edat *UNDOCUMENTED*
758 * \return A vector of time delays in seconds
759 *
760 * \sa XLALBinaryPulsarDeltaT
761 */
763{
764 REAL8Vector *bdts = NULL;
765 BinaryPulsarInput binput;
766 BinaryPulsarOutput boutput;
767 EarthState earth;
768
769 INT4 i = 0, length = datatimes->length;
770
771 /* check whether there's a binary model */
772 if ( PulsarCheckParam( pars, "BINARY" ) ) {
773 bdts = XLALCreateREAL8Vector( length );
774
775 for ( i = 0; i < length; i++ ) {
776 binput.tb = XLALGPSGetREAL8( &datatimes->data[i] ) + dts->data[i];
777
778 get_earth_pos_vel( &earth, edat, &datatimes->data[i] );
779
780 binput.earth = earth; /* current Earth state */
781 XLALBinaryPulsarDeltaTNew( &boutput, &binput, pars );
782 bdts->data[i] = boutput.deltaT;
783 }
784 }
785 return bdts;
786}
787
788
789/**
790 * \brief Computes the phase from the glitch model.
791 *
792 * \param pars [in] A set of pulsar parameters
793 * \param datatimes [in] A vector of GPS times
794 * \param dts [in] A vector of solar system barycentre time delays
795 * \param bdts [in] A vector of binary system barycentre time delays
796 * \return A vector of phases in cycles
797 */
799{
800 REAL8Vector *glphase = NULL;
801
802 /* glitch parameters */
803 REAL8 *glep = NULL, *glph = NULL, *glf0 = NULL, *glf1 = NULL, *glf2 = NULL, *glf0d = NULL, *gltd = NULL;
804 UINT4 glnum = 0;
805
806 UINT4 i = 0, j = 0, length = datatimes->length;
807
808 REAL8 pepoch = PulsarGetREAL8ParamOrZero( pars, "PEPOCH" ); /* time of ephem info */
809 REAL8 cgw = PulsarGetREAL8ParamOrZero( pars, "CGW" );
810 REAL8 T0 = pepoch;
811
812 if ( PulsarCheckParam( pars, "GLEP" ) ) { /* see if pulsar has glitch parameters */
813 const REAL8Vector *gleppars = PulsarGetREAL8VectorParam( pars, "GLEP" );
814 glnum = gleppars->length;
815
816 /* get epochs */
817 glep = XLALCalloc( glnum, sizeof( REAL8 ) ); /* initialise to zeros */
818 for ( i = 0; i < gleppars->length; i++ ) {
819 glep[i] = gleppars->data[i];
820 }
821
822 /* get phase offsets */
823 glph = XLALCalloc( glnum, sizeof( REAL8 ) ); /* initialise to zeros */
824 if ( PulsarCheckParam( pars, "GLPH" ) ) {
825 const REAL8Vector *glpars = PulsarGetREAL8VectorParam( pars, "GLPH" );
826 for ( i = 0; i < glpars->length; i++ ) {
827 glph[i] = glpars->data[i];
828 }
829 }
830
831 /* get frequencies offsets */
832 glf0 = XLALCalloc( glnum, sizeof( REAL8 ) ); /* initialise to zeros */
833 if ( PulsarCheckParam( pars, "GLF0" ) ) {
834 const REAL8Vector *glpars = PulsarGetREAL8VectorParam( pars, "GLF0" );
835 for ( i = 0; i < glpars->length; i++ ) {
836 glf0[i] = glpars->data[i];
837 }
838 }
839
840 /* get frequency derivative offsets */
841 glf1 = XLALCalloc( glnum, sizeof( REAL8 ) ); /* initialise to zeros */
842 if ( PulsarCheckParam( pars, "GLF1" ) ) {
843 const REAL8Vector *glpars = PulsarGetREAL8VectorParam( pars, "GLF1" );
844 for ( i = 0; i < glpars->length; i++ ) {
845 glf1[i] = glpars->data[i];
846 }
847 }
848
849 /* get second frequency derivative offsets */
850 glf2 = XLALCalloc( glnum, sizeof( REAL8 ) ); /* initialise to zeros */
851 if ( PulsarCheckParam( pars, "GLF2" ) ) {
852 const REAL8Vector *glpars = PulsarGetREAL8VectorParam( pars, "GLF2" );
853 for ( i = 0; i < glpars->length; i++ ) {
854 glf2[i] = glpars->data[i];
855 }
856 }
857
858 /* get decaying frequency component offset derivative */
859 glf0d = XLALCalloc( glnum, sizeof( REAL8 ) ); /* initialise to zeros */
860 if ( PulsarCheckParam( pars, "GLF0D" ) ) {
861 const REAL8Vector *glpars = PulsarGetREAL8VectorParam( pars, "GLF0D" );
862 for ( i = 0; i < glpars->length; i++ ) {
863 glf0d[i] = glpars->data[i];
864 }
865 }
866
867 /* get decaying frequency component decay time constant */
868 gltd = XLALCalloc( glnum, sizeof( REAL8 ) ); /* initialise to zeros */
869 if ( PulsarCheckParam( pars, "GLTD" ) ) {
870 const REAL8Vector *glpars = PulsarGetREAL8VectorParam( pars, "GLTD" );
871 for ( i = 0; i < glpars->length; i++ ) {
872 gltd[i] = glpars->data[i];
873 }
874 }
875
876 glphase = XLALCreateREAL8Vector( length );
877
878 for ( i = 0; i < length; i++ ) {
879 REAL8 deltaphi = 0., deltat = 0., DT = 0.;
880 REAL8 realT = XLALGPSGetREAL8( &datatimes->data[i] ); /* time of data */
881 DT = realT - T0; /* time diff between data and start of data */
882
883 /* include solar system barycentring time delays */
884 deltat = DT + dts->data[i];
885
886 /* include binary system barycentring time delays */
887 if ( bdts != NULL ) {
888 deltat += bdts->data[i];
889 }
890
891 /* correct for speed of GW compared to speed of light */
892 if ( cgw > 0.0 && cgw < 1. ) {
893 deltat /= cgw;
894 }
895
896 /* get glitch phase - based on equations in formResiduals.C of TEMPO2 from Eqn 1 of Yu et al (2013) http://ukads.nottingham.ac.uk/abs/2013MNRAS.429..688Y */
897 for ( j = 0; j < glnum; j++ ) {
898 if ( deltat >= ( glep[j] - T0 ) ) {
899 REAL8 dtg = 0, expd = 1.;
900 dtg = deltat - ( glep[j] - T0 ); /* time since glitch */
901 if ( gltd[j] != 0. ) {
902 expd = exp( -dtg / gltd[j] ); /* decaying part of glitch */
903 }
904 deltaphi += glph[j] + glf0[j] * dtg + 0.5 * glf1[j] * dtg * dtg + ( 1. / 6. ) * glf2[j] * dtg * dtg * dtg + glf0d[j] * gltd[j] * ( 1. - expd );
905 }
906 }
907
908 glphase->data[i] = deltaphi;
909 }
910 }
911
912 return glphase;
913}
914
915
916/**
917 * \brief The amplitude model of a complex heterodyned signal from the \f$ l=2, m=1,2 \f$ harmonics of a rotating neutron
918 * star.
919 *
920 * This function calculates the complex heterodyned time series model for a rotating neutron star. It will currently
921 * calculate the model for emission from the \f$ l=m=2 \f$ harmonic (which gives emission at twice the rotation frequency)
922 * and/or the \f$ l=2 \f$ and \f$ m=1 \f$ harmonic (which gives emission at the rotation frequency). See LIGO T1200265-v3.
923 * Further harmonics can be added and are defined by the \c freqFactor value, which is the multiple of the
924 * spin-frequency at which emission is produced.
925 *
926 * The antenna pattern functions are contained in a 1D lookup table, so within this function the correct value for the
927 * given time is interpolated from this lookup table using linear interpolation..
928 *
929 * \param pars [in] A set of pulsar parameters
930 * \param ifo [in] The ifo model containing detector-specific parameters
931 *
932 */
934{
935 UINT4 i = 0, j = 0, length;
936
937 REAL8 T, twopsi;
938 REAL8 cosiota = PulsarGetREAL8ParamOrZero( pars, "COSIOTA" );
939 REAL8 siniota = sin( acos( cosiota ) );
940 REAL8 s2psi = 0., c2psi = 0., spsi = 0., cpsi = 0.;
941 UINT4 nonGR = 0;
942
943 REAL8Vector *freqFactors = NULL;
944 INT4 varyphase = 0, roq = 0;
945
946 freqFactors = *( REAL8Vector ** )LALInferenceGetVariable( ifo->params, "freqfactors" );
947
948 if ( LALInferenceCheckVariable( ifo->params, "varyphase" ) ) {
949 varyphase = 1;
950 }
951 if ( LALInferenceCheckVariable( ifo->params, "roq" ) ) {
952 roq = 1;
953 }
954
955 twopsi = 2.*PulsarGetREAL8ParamOrZero( pars, "PSI" );
956 s2psi = sin( twopsi );
957 c2psi = cos( twopsi );
958
959 /* check for non-GR model */
960 if ( LALInferenceCheckVariable( ifo->params, "nonGR" ) ) {
961 nonGR = *( UINT4 * )LALInferenceGetVariable( ifo->params, "nonGR" );
962 }
963
964 if ( nonGR == 1 ) {
965 spsi = sin( PulsarGetREAL8ParamOrZero( pars, "PSI" ) );
966 cpsi = cos( PulsarGetREAL8ParamOrZero( pars, "PSI" ) );
967 }
968
969 /* loop over all detectors */
970 while ( ifo ) {
971 /* loop over components in data as given by the frequency factors */
972 for ( j = 0; j < freqFactors->length; j++ ) {
973 COMPLEX16 expPhi;
974 COMPLEX16 Cplus = 0., Ccross = 0., Cx = 0., Cy = 0., Cl = 0., Cb = 0.;
975
976 if ( !ifo ) {
977 XLAL_ERROR_VOID( XLAL_EINVAL, "Error... ifo model not defined." );
978 }
979
980 /* get the amplitude and phase factors */
981 if ( freqFactors->data[j] == 1. ) {
982 /* the l=2, m=1 harmonic at the rotation frequency */
983 if ( nonGR ) { /* amplitude if nonGR is specified */
984 COMPLEX16 expPhiTensor, expPsiTensor, expPhiScalar, expPsiScalar, expPhiVector, expPsiVector;
985
986 expPhiTensor = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PHI0TENSOR_F" ) );
987 expPsiTensor = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PSITENSOR_F" ) );
988 expPhiScalar = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PHI0SCALAR_F" ) );
989 expPsiScalar = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PSISCALAR_F" ) );
990 expPhiVector = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PHI0VECTOR_F" ) );
991 expPsiVector = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PSIVECTOR_F" ) );
992
993 Cplus = 0.5 * expPhiTensor * PulsarGetREAL8ParamOrZero( pars, "HPLUS_F" );
994 Ccross = 0.5 * expPhiTensor * PulsarGetREAL8ParamOrZero( pars, "HCROSS_F" ) * expPsiTensor;
995 Cx = 0.5 * expPhiVector * PulsarGetREAL8ParamOrZero( pars, "HVECTORX_F" );
996 Cy = 0.5 * expPhiVector * PulsarGetREAL8ParamOrZero( pars, "HVECTORY_F" ) * expPsiVector;
997 Cb = 0.5 * expPhiScalar * PulsarGetREAL8ParamOrZero( pars, "HSCALARB_F" );
998 Cl = 0.5 * expPhiScalar * PulsarGetREAL8ParamOrZero( pars, "HSCALARL_F" ) * expPsiScalar;
999 } else {
1000 expPhi = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PHI21" ) );
1001 Cplus = -0.25 * PulsarGetREAL8ParamOrZero( pars, "C21" ) * siniota * cosiota * expPhi;
1002 Ccross = 0.25 * I * PulsarGetREAL8ParamOrZero( pars, "C21" ) * siniota * expPhi;
1003 }
1004 } else if ( freqFactors->data[j] == 2. ) {
1005 /* the l=2, m=2 harmonic at twice the rotation frequency */
1006 if ( nonGR ) { /* amplitude if nonGR is specified */
1007 COMPLEX16 expPhiTensor, expPsiTensor, expPhiScalar, expPsiScalar, expPhiVector, expPsiVector;
1008
1009 expPhiTensor = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PHI0TENSOR" ) );
1010 expPsiTensor = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PSITENSOR" ) );
1011 expPhiScalar = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PHI0SCALAR" ) );
1012 expPsiScalar = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PSISCALAR" ) );
1013 expPhiVector = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PHI0VECTOR" ) );
1014 expPsiVector = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PSIVECTOR" ) );
1015
1016 Cplus = 0.5 * expPhiTensor * PulsarGetREAL8ParamOrZero( pars, "HPLUS" );
1017 Ccross = 0.5 * expPhiTensor * PulsarGetREAL8ParamOrZero( pars, "HCROSS" ) * expPsiTensor;
1018 Cx = 0.5 * expPhiVector * PulsarGetREAL8ParamOrZero( pars, "HVECTORX" );
1019 Cy = 0.5 * expPhiVector * PulsarGetREAL8ParamOrZero( pars, "HVECTORY" ) * expPsiVector;
1020 Cb = 0.5 * expPhiScalar * PulsarGetREAL8ParamOrZero( pars, "HSCALARB" );
1021 Cl = 0.5 * expPhiScalar * PulsarGetREAL8ParamOrZero( pars, "HSCALARL" ) * expPsiScalar;
1022 } else { /* just GR tensor mode amplitudes */
1023 expPhi = cexp( I * PulsarGetREAL8ParamOrZero( pars, "PHI22" ) );
1024 Cplus = -0.5 * PulsarGetREAL8ParamOrZero( pars, "C22" ) * ( 1. + cosiota * cosiota ) * expPhi;
1025 Ccross = I * PulsarGetREAL8ParamOrZero( pars, "C22" ) * cosiota * expPhi;
1026 }
1027 } else {
1028 XLAL_ERROR_VOID( XLAL_EINVAL, "Error... currently unknown frequency factor (%.2lf) for models.", freqFactors->data[j] );
1029 }
1030
1031 if ( varyphase || roq ) { /* have to compute the full time domain signal */
1032 REAL8Vector *sidDayFrac = NULL;
1033 REAL8 tsv, tsteps;
1034
1035 REAL8Vector *LUfplus = NULL, *LUfcross = NULL, *LUfx = NULL, *LUfy = NULL, *LUfb = NULL, *LUfl = NULL;
1036
1037 /* set lookup table parameters */
1038 tsteps = ( REAL8 )( *( INT4 * )LALInferenceGetVariable( ifo->params, "timeSteps" ) );
1039 tsv = LAL_DAYSID_SI / tsteps;
1040
1041 LUfplus = *( REAL8Vector ** )LALInferenceGetVariable( ifo->params, "a_response_tensor" );
1042 LUfcross = *( REAL8Vector ** )LALInferenceGetVariable( ifo->params, "b_response_tensor" );
1043
1044 if ( nonGR ) {
1045 LUfx = *( REAL8Vector ** )LALInferenceGetVariable( ifo->params, "a_response_vector" );
1046 LUfy = *( REAL8Vector ** )LALInferenceGetVariable( ifo->params, "b_response_vector" );
1047 LUfb = *( REAL8Vector ** )LALInferenceGetVariable( ifo->params, "a_response_scalar" );
1048 LUfl = *( REAL8Vector ** )LALInferenceGetVariable( ifo->params, "b_response_scalar" );
1049 }
1050
1051 /* get the sidereal time since the initial data point % sidereal day */
1052 sidDayFrac = *( REAL8Vector ** )LALInferenceGetVariable( ifo->params, "siderealDay" );
1053
1054 length = IFO_XTRA_DATA( ifo )->times->length;
1055
1056 for ( i = 0; i < length; i++ ) {
1057 REAL8 plus00, plus01, cross00, cross01, plus = 0., cross = 0.;
1058 REAL8 x00, x01, y00, y01, b00, b01, l00, l01;
1059 REAL8 timeScaled, timeMin, timeMax;
1060 REAL8 plusT = 0., crossT = 0., x = 0., y = 0., xT = 0., yT = 0., b = 0., l = 0.;
1061 INT4 timebinMin, timebinMax;
1062
1063 /* set the time bin for the lookup table */
1064 /* sidereal day in secs*/
1065 T = sidDayFrac->data[i];
1066 timebinMin = ( INT4 )fmod( floor( T / tsv ), tsteps );
1067 timeMin = timebinMin * tsv;
1068 timebinMax = ( INT4 )fmod( timebinMin + 1, tsteps );
1069 timeMax = timeMin + tsv;
1070
1071 /* get values of matrix for linear interpolation */
1072 plus00 = LUfplus->data[timebinMin];
1073 plus01 = LUfplus->data[timebinMax];
1074
1075 cross00 = LUfcross->data[timebinMin];
1076 cross01 = LUfcross->data[timebinMax];
1077
1078 /* rescale time for linear interpolation on a unit square */
1079 timeScaled = ( T - timeMin ) / ( timeMax - timeMin );
1080
1081 plus = plus00 + ( plus01 - plus00 ) * timeScaled;
1082 cross = cross00 + ( cross01 - cross00 ) * timeScaled;
1083
1084 plusT = plus * c2psi + cross * s2psi;
1085 crossT = cross * c2psi - plus * s2psi;
1086
1087 if ( nonGR ) {
1088 x00 = LUfx->data[timebinMin];
1089 x01 = LUfx->data[timebinMax];
1090 y00 = LUfy->data[timebinMin];
1091 y01 = LUfy->data[timebinMax];
1092 b00 = LUfb->data[timebinMin];
1093 b01 = LUfb->data[timebinMax];
1094 l00 = LUfl->data[timebinMin];
1095 l01 = LUfl->data[timebinMax];
1096
1097 x = x00 + ( x01 - x00 ) * timeScaled;
1098 y = y00 + ( y01 - y00 ) * timeScaled;
1099 b = b00 + ( b01 - b00 ) * timeScaled;
1100 l = l00 + ( l01 - l00 ) * timeScaled;
1101
1102 xT = x * cpsi + y * spsi;
1103 yT = y * cpsi - x * spsi;
1104 }
1105
1106 /* create the complex signal amplitude model appropriate for the harmonic */
1107 ifo->compTimeSignal->data->data[i] = ( Cplus * plusT ) + ( Ccross * crossT );
1108
1109 /* add non-GR components if required */
1110 if ( nonGR ) {
1111 ifo->compTimeSignal->data->data[i] += ( Cx * xT ) + ( Cy * yT ) + Cb * b + Cl * l;
1112 }
1113 }
1114 } else { /* just have to calculate the values to multiply the pre-summed data */
1115 /* for tensor-only models (e.g. the default of GR) calculate the two components of
1116 * the single model value - things multiplied by a(t) and things multiplied by b(t)
1117 * (both these will have real and imaginary components). NOTE: the values input into
1118 * ifo->compTimeSignal->data->data are not supposed to be identical to the above
1119 * relationships between the amplitudes and polarisation angles, as these are the
1120 * multiplicative coefficients of the a(t) and b(t) summations.
1121 */
1122
1123 /* put multiples of a(t) in first value and b(t) in second */
1124 if ( !nonGR ) {
1125 /* first check that compTimeSignal has been reduced in size to just hold these two values */
1126 if ( ifo->compTimeSignal->data->length != 2 ) { /* otherwise resize it */
1127 ifo->compTimeSignal = XLALResizeCOMPLEX16TimeSeries( ifo->compTimeSignal, 0, 2 );
1128 }
1129
1130 ifo->compTimeSignal->data->data[0] = ( Cplus * c2psi - Ccross * s2psi );
1131 ifo->compTimeSignal->data->data[1] = ( Cplus * s2psi + Ccross * c2psi );
1132 } else {
1133 /* first check that compTimeSignal has been reduced in size to just hold these size values */
1134 if ( ifo->compTimeSignal->data->length != 6 ) { /* otherwise resize it */
1135 ifo->compTimeSignal = XLALResizeCOMPLEX16TimeSeries( ifo->compTimeSignal, 0, 6 );
1136 }
1137
1138 ifo->compTimeSignal->data->data[0] = ( Cplus * c2psi - Ccross * s2psi );
1139 ifo->compTimeSignal->data->data[1] = ( Cplus * s2psi + Ccross * c2psi );
1140 ifo->compTimeSignal->data->data[2] = ( Cx * cpsi - Cy * spsi );
1141 ifo->compTimeSignal->data->data[3] = ( Cx * spsi + Cy * cpsi );
1142 ifo->compTimeSignal->data->data[4] = Cb;
1143 ifo->compTimeSignal->data->data[5] = Cl;
1144 }
1145 }
1146
1147 ifo = ifo->next;
1148 }
1149 }
1150}
1151
1152
1153/**
1154 * \brief Calculate the phase mismatch between two vectors of phases
1155 *
1156 * The function will calculate phase mismatch between two vectors of phases (with phases given in cycles rather than
1157 * radians).
1158 *
1159 * The mismatch is calculated as:
1160 * \f[
1161 * M = 1-\frac{1}{T}\int_0^T \cos{2\pi(\phi_1 - \phi_2)} dt.
1162 * \f]
1163 * In the function the integral is performed using the trapezium rule.
1164 *
1165 * PARAM phi1 [in] First phase vector
1166 * PARAM phi2 [in] Second phase vector
1167 * PARAM t [in] The time stamps of the phase points
1168 *
1169 * \return The mismatch
1170 */
1172{
1173 REAL8 mismatch = 0., dp1 = 0., dp2 = 0.;
1174 REAL4 sp, cp1, cp2;
1175 UINT4 i = 0;
1176
1177 REAL8 T = 0., dt = 0.;
1178
1179 /* data time span */
1180 T = XLALGPSGetREAL8( &t->data[t->length - 1] ) - XLALGPSGetREAL8( &t->data[0] );
1181
1182 if ( phi1->length != phi2->length ) {
1183 XLAL_ERROR_REAL8( XLAL_EBADLEN, "Phase lengths should be equal!" );
1184 }
1185
1186 /* calculate mismatch - integrate with trapezium rule */
1187 for ( i = 0; i < phi1->length - 1; i++ ) {
1188 if ( i == 0 ) {
1189 dp1 = fmod( phi1->data[i] - phi2->data[i], 1. );
1191 } else {
1192 dp1 = dp2;
1193 cp1 = cp2;
1194 }
1195
1196 dp2 = fmod( phi1->data[i + 1] - phi2->data[i + 1], 1. );
1197
1198 dt = XLALGPSGetREAL8( &t->data[i + 1] ) - XLALGPSGetREAL8( &t->data[i] );
1199
1201
1202 mismatch += ( cp1 + cp2 ) * dt;
1203 }
1204
1205 return ( 1. - fabs( mismatch ) / ( 2.*T ) );
1206}
1207
1208
1209/**
1210 * \brief Get the position and velocity of the Earth at a given time
1211 *
1212 * This function will get the position and velocity of the Earth from the ephemeris data at the time t. It will be
1213 * returned in an EarthState structure. This is based on the start of the XLALBarycenterEarth function.
1214 */
1216{
1217 REAL8 tgps[2];
1218
1219 REAL8 t0e; /* time since first entry in Earth ephem. table */
1220 INT4 ientryE; /* entry in look-up table closest to current time, tGPS */
1221
1222 REAL8 tinitE; /* time (GPS) of first entry in Earth ephem table */
1223 REAL8 tdiffE; /* current time tGPS minus time of nearest entry in Earth ephem look-up table */
1224 REAL8 tdiff2E; /* tdiff2 = tdiffE * tdiffE */
1225
1226 INT4 j;
1227
1228 /* check input */
1229 if ( !earth || !tGPS || !edat || !edat->ephemE || !edat->ephemS ) {
1230 XLAL_ERROR_VOID( XLAL_EINVAL, "Invalid NULL input 'earth', 'tGPS', 'edat','edat->ephemE' or 'edat->ephemS'" );
1231 }
1232
1233 tgps[0] = ( REAL8 )tGPS->gpsSeconds; /* convert from INT4 to REAL8 */
1234 tgps[1] = ( REAL8 )tGPS->gpsNanoSeconds;
1235
1236 tinitE = edat->ephemE[0].gps;
1237
1238 t0e = tgps[0] - tinitE;
1239 ientryE = ROUND( t0e / edat->dtEtable ); /* finding Earth table entry */
1240
1241 if ( ( ientryE < 0 ) || ( ientryE >= edat->nentriesE ) ) {
1242 XLAL_ERROR_VOID( XLAL_EDOM, "Input GPS time %f outside of Earth ephem range [%f, %f]\n", tgps[0], tinitE, tinitE +
1243 edat->nentriesE * edat->dtEtable );
1244 }
1245
1246 /* tdiff is arrival time minus closest Earth table entry; tdiff can be pos. or neg. */
1247 tdiffE = t0e - edat->dtEtable * ientryE + tgps[1] * 1.e-9;
1248 tdiff2E = tdiffE * tdiffE;
1249
1250 REAL8 *pos = edat->ephemE[ientryE].pos;
1251 REAL8 *vel = edat->ephemE[ientryE].vel;
1252 REAL8 *acc = edat->ephemE[ientryE].acc;
1253
1254 for ( j = 0; j < 3; j++ ) {
1255 earth->posNow[j] = pos[j] + vel[j] * tdiffE + 0.5 * acc[j] * tdiff2E;
1256 earth->velNow[j] = vel[j] + acc[j] * tdiffE;
1257 }
1258}
1259
1260
1261/**
1262 * \brief Creates a lookup table of the detector antenna pattern
1263 *
1264 * This function creates a lookup table of the tensor, vector and scalar antenna patterns for a given
1265 * detector orientation and source sky position. For the tensor modes these are the functions given by
1266 * equations 10-13 in \cite JKS98 , whilst for the vector and scalar modes they are the \f$ \psi \f$
1267 * independent parts of e.g. equations 5-8 of \cite Nishizawa2009 . We remove the \f$ \psi \f$ dependent
1268 * by setting \f$ \psi=0 \f$ .
1269 *
1270 * If \c avedt is a value over 60 seconds then the antenna pattern will actually be the mean value from
1271 * 60 second intervals within that timespan. This accounts for the fact that each data point is actually an
1272 * averaged value over the given timespan.
1273 *
1274 * \param t0 [in] initial GPS time of the data
1275 * \param detNSource [in] structure containing the detector and source orientations and locations
1276 * \param timeSteps [in] the number of grid bins to use in time
1277 * \param avedt [in] average the antenna pattern over this timespan
1278 * \param aT [in] a vector into which the a(t) Fplus tensor antenna pattern lookup table will be output
1279 * \param bT [in] a vector into which the b(t) Fcross tensor antenna pattern lookup table will be output
1280 * \param aV [in] a vector into which the a(t) Fx vector antenna pattern lookup table will be output
1281 * \param bV [in] a vector into which the b(t) Fy vector antenna pattern lookup table will be output
1282 * \param aS [in] a vector into which the a(t) Fb scalar antenna pattern lookup table will be output
1283 * \param bS [in] a vector into which the b(t) Fl scalar antenna pattern lookup table will be output
1284 */
1285void response_lookup_table( REAL8 t0, LALDetAndSource detNSource, INT4 timeSteps, REAL8 avedt, REAL8Vector *aT,
1287 REAL8Vector *bS )
1288{
1289 LIGOTimeGPS gps;
1290 REAL8 T = 0, Tstart = 0., Tav = 0;
1291
1292 REAL8 fplus = 0., fcross = 0., fx = 0., fy = 0., fb = 0., fl = 0.;
1293 REAL8 tsteps = ( REAL8 )timeSteps;
1294
1295 INT4 j = 0, k = 0, nav = 0;
1296
1297 /* number of points to average */
1298 if ( avedt == 60. ) {
1299 nav = 1;
1300 } else {
1301 nav = floor( avedt / 60. ) + 1;
1302 }
1303
1304 /* set the polarisation angle to zero to get the a(t) and b(t) antenna pattern functions */
1305 detNSource.pSource->orientation = 0.0;
1306
1307 for ( j = 0 ; j < timeSteps ; j++ ) {
1308 aT->data[j] = 0.;
1309 bT->data[j] = 0.;
1310 aV->data[j] = 0.;
1311 bV->data[j] = 0.;
1312 aS->data[j] = 0.;
1313 bS->data[j] = 0.;
1314
1315 /* central time of lookup table point */
1316 T = t0 + ( REAL8 )j * LAL_DAYSID_SI / tsteps;
1317
1318 if ( nav % 2 ) { /* is odd */
1319 Tstart = T - 0.5 * ( ( REAL8 )nav - 1. ) * 60.;
1320 } else { /* is even */
1321 Tstart = T - ( 0.5 * ( REAL8 )nav - 1. ) * 60. - 30.;
1322 }
1323
1324 for ( k = 0; k < nav; k++ ) {
1325 Tav = Tstart + 60.*( REAL8 )k;
1326
1327 XLALGPSSetREAL8( &gps, Tav );
1328
1329 XLALComputeDetAMResponseExtraModes( &fplus, &fcross, &fb, &fl, &fx, &fy, detNSource.pDetector->response,
1331 detNSource.pSource->equatorialCoords.latitude,
1332 detNSource.pSource->orientation, XLALGreenwichMeanSiderealTime( &gps ) );
1333
1334 aT->data[j] += fplus;
1335 bT->data[j] += fcross;
1336 aV->data[j] += fx;
1337 bV->data[j] += fy;
1338 aS->data[j] += fb;
1339 bS->data[j] += fl;
1340 }
1341
1342 aT->data[j] /= ( REAL8 )nav;
1343 bT->data[j] /= ( REAL8 )nav;
1344 aV->data[j] /= ( REAL8 )nav;
1345 bV->data[j] /= ( REAL8 )nav;
1346 aS->data[j] /= ( REAL8 )nav;
1347 bS->data[j] /= ( REAL8 )nav;
1348 }
1349}
1350
1351
1352/*------------------------ END OF MODEL FUNCTIONS ----------------------------*/
1353
1354
1355/*----------------- FUNCTIONS TO CONVERT BETWEEN PARAMETERS ------------------*/
1356
1357/**
1358 * \brief Convert sources parameters into amplitude and phase notation parameters
1359 *
1360 * Convert the physical source parameters into the amplitude and phase notation given in Eqns
1361 * 62-65 of \cite Jones:2015 .
1362 *
1363 * Note that \c phi0 is essentially the rotational phase of the pulsar. Also, note that if using \f$ h_0 \f$ ,
1364 * and therefore the convention for a signal as defined in \cite JKS98 , the sign of the waveform model is
1365 * the opposite of that in \cite Jones:2015 , and therefore a sign flip is required in the amplitudes.
1366 */
1368{
1369 REAL8 sinlambda, coslambda, sinlambda2, coslambda2, sin2lambda;
1370 REAL8 theta, sintheta, costheta2, sintheta2, sin2theta;
1373 REAL8 I21 = PulsarGetREAL8ParamOrZero( params, "I21" );
1374 REAL8 I31 = PulsarGetREAL8ParamOrZero( params, "I31" );
1375 REAL8 C21 = PulsarGetREAL8ParamOrZero( params, "C21" );
1376 REAL8 C22 = PulsarGetREAL8ParamOrZero( params, "C22" );
1377 REAL8 phi21 = PulsarGetREAL8ParamOrZero( params, "PHI21" );
1378 REAL8 phi22 = PulsarGetREAL8ParamOrZero( params, "PHI22" );
1379 REAL8 lambda = PulsarGetREAL8ParamOrZero( params, "LAMBDA" );
1381
1382 if ( h0 != 0. ) {
1383 phi22 = 2.*phi0;
1384 phi22 = phi22 - LAL_TWOPI * floor( phi22 / LAL_TWOPI );
1385 PulsarAddREAL8Param( params, "PHI22", phi22 );
1386
1387 C22 = -0.5 * h0; /* note the change in sign so that the triaxial model conforms to the convertion in JKS98 */
1388 PulsarAddREAL8Param( params, "C22", C22 );
1389 } else if ( ( I21 != 0. || I31 != 0. ) && ( C22 == 0. && C21 == 0. ) ) {
1390 sinlambda = sin( lambda );
1391 coslambda = cos( lambda );
1392 sin2lambda = sin( 2. * lambda );
1393 sinlambda2 = SQUARE( sinlambda );
1394 coslambda2 = SQUARE( coslambda );
1395
1396 theta = acos( costheta );
1397 sintheta = sin( theta );
1398 sin2theta = sin( 2. * theta );
1399 sintheta2 = SQUARE( sintheta );
1400 costheta2 = SQUARE( costheta );
1401
1402 REAL8 A22 = I21 * ( sinlambda2 - coslambda2 * costheta2 ) - I31 * sintheta2;
1403 REAL8 B22 = I21 * sin2lambda * costheta;
1404 REAL8 A222 = SQUARE( A22 );
1405 REAL8 B222 = SQUARE( B22 );
1406
1407 REAL8 A21 = I21 * sin2lambda * sintheta;
1408 REAL8 B21 = sin2theta * ( I21 * coslambda2 - I31 );
1409 REAL8 A212 = SQUARE( A21 );
1410 REAL8 B212 = SQUARE( B21 );
1411
1412 C22 = 2.*sqrt( A222 + B222 );
1413 C21 = 2.*sqrt( A212 + B212 );
1414
1415 PulsarAddREAL8Param( params, "C22", C22 );
1416 PulsarAddREAL8Param( params, "C21", C21 );
1417
1418 phi22 = fmod( 2.*phi0 - atan2( B22, A22 ), LAL_TWOPI );
1419 phi21 = fmod( phi0 - atan2( B21, A21 ), LAL_TWOPI );
1420
1421 PulsarAddREAL8Param( params, "PHI22", phi22 );
1422 PulsarAddREAL8Param( params, "PHI21", phi21 );
1423 }
1424}
void XLALBinaryPulsarDeltaTNew(BinaryPulsarOutput *output, BinaryPulsarInput *input, PulsarParameters *params)
function to calculate the binary system delay using new parameter structure
int j
int k
const REAL8Vector * PulsarGetREAL8VectorParam(const PulsarParameters *pars, const CHAR *name)
Return a REAL8Vector parameter.
void PulsarAddREAL8Param(PulsarParameters *pars, const CHAR *name, REAL8 value)
Add a REAL8 parameter to the PulsarParameters structure.
REAL8 PulsarGetREAL8ParamOrZero(const PulsarParameters *pars, const CHAR *name)
Return a REAL8 parameter if it exists, otherwise return zero.
int PulsarCheckParam(const PulsarParameters *pars, const CHAR *name)
Check for the existence of the parameter name in the PulsarParameters structure.
REAL8 PulsarGetREAL8Param(const PulsarParameters *pars, const CHAR *name)
Return a REAL8 parameter.
void PulsarFreeParams(PulsarParameters *pars)
Function to free memory from pulsar parameters.
void PulsarAddStringParam(PulsarParameters *pars, const CHAR *name, const CHAR *value)
Add a string parameter to the PulsarParameters structure.
void PulsarAddREAL8VectorParam(PulsarParameters *pars, const CHAR *name, const REAL8Vector *value)
Add a REAL8Vector parameter to the PulsarParameters structure.
#define PULSAR_PARNAME_MAX
int l
double theta
const double costheta
void XLALComputeDetAMResponseExtraModes(double *fplus, double *fcross, double *fb, double *fl, double *fx, double *fy, const REAL4 D[3][3], const double ra, const double dec, const double psi, const double gmst)
int XLALBarycenter(EmissionTime *emit, const BarycenterInput *baryinput, const EarthState *earth)
Transforms from detector arrival time in GPS (as specified in the LIGOTimeGPS structure) to pulse em...
int XLALBarycenterEarthNew(EarthState *earth, const LIGOTimeGPS *tGPS, const EphemerisData *edat, const TimeCorrectionData *tdat, TimeCorrectionType ttype)
Computes the position and orientation of the Earth, at some arrival time, but unlike XLALBarycenterEa...
TimeCorrectionType
Enumerated type denoting the time system type to be produced in the solar system barycentring routine...
Definition: LALBarycenter.h:72
#define LAL_PI_2
#define LAL_DAYSID_SI
#define LAL_PI
#define LAL_TWOPI
#define LAL_G_SI
double complex COMPLEX16
double REAL8
char CHAR
uint32_t UINT4
int32_t INT4
float REAL4
UINT4 LALInferenceGetUINT4Variable(LALInferenceVariables *vars, const char *name)
void LALInferenceAddVariable(LALInferenceVariables *vars, const char *name, const void *value, LALInferenceVariableType type, LALInferenceParamVaryType vary)
REAL8 LALInferenceGetREAL8Variable(LALInferenceVariables *vars, const char *name)
LALInferenceParamVaryType
void * LALInferenceGetVariable(const LALInferenceVariables *vars, const char *name)
REAL8Vector * LALInferenceGetREAL8VectorVariable(LALInferenceVariables *vars, const char *name)
int LALInferenceCheckVariable(LALInferenceVariables *vars, const char *name)
int LALInferenceCheckVariableNonFixed(LALInferenceVariables *vars, const char *name)
LALINFERENCE_REAL8_t
void * XLALCalloc(size_t m, size_t n)
int XLALSinCos2PiLUT(REAL4 *sin2pix, REAL4 *cos2pix, REAL8 x)
Calculate sin(2*pi*x) and cos(2*pi*x) to roughly 1e-7 precision using a lookup-table and Taylor-expan...
Definition: SinCosLUT.c:97
COMPLEX16TimeSeries * XLALResizeCOMPLEX16TimeSeries(COMPLEX16TimeSeries *series, int first, size_t length)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
#define XLAL_ERROR_VOID(...)
#define XLAL_ERROR_REAL8(...)
#define XLAL_ERROR_NULL(...)
#define XLAL_CHECK_REAL8(assertion,...)
#define XLAL_CHECK_NULL(assertion,...)
XLAL_EBADLEN
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EDOM
XLAL_EINVAL
REAL8 XLALGreenwichMeanSiderealTime(const LIGOTimeGPS *gpstime)
LIGOTimeGPS * XLALGPSSetREAL8(LIGOTimeGPS *epoch, REAL8 t)
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
#define ROUND(a)
M
list y
T
pos
phi2
phi1
dist
int T0
void add_variable_parameter(PulsarParameters *params, LALInferenceVariables *var, const CHAR *parname, LALInferenceParamVaryType vary)
Add a REAL8 parameter from a PulsarParameters variable into a LALInferenceVariable.
Definition: ppe_models.c:376
REAL8Vector * get_glitch_phase(PulsarParameters *pars, LIGOTimeGPSVector *datatimes, REAL8Vector *dts, REAL8Vector *bdts)
Computes the phase from the glitch model.
Definition: ppe_models.c:798
void response_lookup_table(REAL8 t0, LALDetAndSource detNSource, INT4 timeSteps, REAL8 avedt, REAL8Vector *aT, REAL8Vector *bT, REAL8Vector *aV, REAL8Vector *bV, REAL8Vector *aS, REAL8Vector *bS)
Creates a lookup table of the detector antenna pattern.
Definition: ppe_models.c:1285
void pulsar_model(PulsarParameters *params, LALInferenceIFOModel *ifo)
Generate the model of the neutron star signal.
Definition: ppe_models.c:408
REAL8Vector * get_bsb_delay(PulsarParameters *pars, LIGOTimeGPSVector *datatimes, REAL8Vector *dts, EphemerisData *edat)
Computes the delay between a pulsar in a binary system and the barycentre of the system.
Definition: ppe_models.c:762
REAL8Vector * get_ssb_delay(PulsarParameters *pars, LIGOTimeGPSVector *datatimes, EphemerisData *ephem, TimeCorrectionData *tdat, TimeCorrectionType ttype, LALDetector *detector)
Computes the delay between a GPS time at Earth and the solar system barycentre.
Definition: ppe_models.c:657
#define SQUARE(x)
Definition: ppe_models.c:33
void get_earth_pos_vel(EarthState *earth, EphemerisData *edat, LIGOTimeGPS *tGPS)
Get the position and velocity of the Earth at a given time.
Definition: ppe_models.c:1215
REAL8 get_phase_mismatch(REAL8Vector *phi1, REAL8Vector *phi2, LIGOTimeGPSVector *t)
Calculate the phase mismatch between two vectors of phases.
Definition: ppe_models.c:1171
void invert_source_params(PulsarParameters *params)
Convert sources parameters into amplitude and phase notation parameters.
Definition: ppe_models.c:1367
void get_pulsar_model(LALInferenceModel *model)
Defines the pulsar model/template to use.
Definition: ppe_models.c:52
void get_amplitude_model(PulsarParameters *pars, LALInferenceIFOModel *ifo)
The amplitude model of a complex heterodyned signal from the harmonics of a rotating neutron star.
Definition: ppe_models.c:933
REAL8Vector * get_phase_model(PulsarParameters *params, LALInferenceIFOModel *ifo, REAL8 freqFactor)
The phase evolution of a source.
Definition: ppe_models.c:493
void add_pulsar_parameter(LALInferenceVariables *var, PulsarParameters *params, const CHAR *parname)
Add a REAL8 parameter from a LALInferenceVariable into a PulsarParameters variable.
Definition: ppe_models.c:359
void set_nonGR_model_parameters(PulsarParameters *pars, char *nonGRmodel)
Set amplitude parameters for specific non-GR models.
Definition: ppe_models.c:301
Header file for the signal models functions used in parameter estimation code for known pulsar search...
#define IFO_XTRA_DATA(ifo)
Definition: ppe_models.h:35
#define NUMGLITCHPARS
The total number of glitch parameters that can define a signal.
static const CHAR glitchpars[NUMGLITCHPARS][VARNAME_MAX]
A list of the glitch parameters.
double t0
Basic input structure to LALBarycenter.c.
REAL8 alpha
Source right ascension in ICRS J2000 coords (radians).
REAL8 dInv
1/(distance to source), in 1/sec.
LIGOTimeGPS tgps
input GPS arrival time.
REAL8 delta
Source declination in ICRS J2000 coords (radians)
LALDetector site
detector site info.
structure containing the input parameters for the binary delay function
REAL8 tb
Time of arrival (TOA) at the SSB.
EarthState earth
The current Earth state (for e.g.
structure containing the output parameters for the binary delay function
REAL8 deltaT
deltaT to add to TDB in order to account for binary
Basic output structure of LALBarycenterEarth.c.
REAL8 velNow[3]
dimensionless velocity of Earth's center at tgps, extrapolated from JPL DE405 ephemeris
REAL8 posNow[3]
Cartesian coords of Earth's center at tgps, extrapolated from JPL DE405 ephemeris; units= sec.
Basic output structure produced by LALBarycenter.c.
REAL8 deltaT
(TDB) - (GPS)
This structure contains all information about the center-of-mass positions of the Earth and Sun,...
LALSource * pSource
const LALDetector * pDetector
REAL4 response[3][3]
REAL8 location[3]
LALInferenceVariables * params
LALInferenceVariables * params
LALInferenceIFOModel * ifo
SkyPosition equatorialCoords
REAL8 orientation
INT4 gpsNanoSeconds
A vector of 'timestamps' of type LIGOTimeGPS.
Definition: SFTfileIO.h:188
LIGOTimeGPS * data
array of timestamps
Definition: SFTfileIO.h:193
UINT4 length
number of timestamps
Definition: SFTfileIO.h:192
The PulsarParameters structure to contain a set of pulsar parameters.
REAL8 * data
REAL8 longitude
REAL8 latitude
This structure will contain a vector of time corrections used during conversion from TT to TDB/TCB/Te...