LALPulsar  6.1.0.1-fe68b98
SSBtimes.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007, 2009 Chris Messenger
3  * Copyright (C) 2006 John T. Whelan, Badri Krishnan
4  * Copyright (C) 2005, 2006, 2007, 2010, 2014 Reinhard Prix
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with with program; see the file COPYING. If not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301 USA
20  */
21 
22 /*---------- INCLUDES ----------*/
23 #include <math.h>
24 
25 #include <lal/SSBtimes.h>
26 #include <lal/AVFactories.h>
27 
28 /* GSL includes */
29 #include <lal/LALGSL.h>
30 #include <gsl/gsl_roots.h>
31 
32 /*---------- local DEFINES ----------*/
33 
34 /*----- Macros ----- */
35 
36 /** Simple Euklidean scalar product for two 3-dim vectors in cartesian coords */
37 #define SCALAR(u,v) ((u)[0]*(v)[0] + (u)[1]*(v)[1] + (u)[2]*(v)[2])
38 
39 /*---------- Global variables ----------*/
40 
42  { SSBPREC_NEWTONIAN, "newtonian" },
43  { SSBPREC_RELATIVISTIC, "relativistic" },
44  { SSBPREC_RELATIVISTICOPT, "relativisticopt" },
45  { SSBPREC_DMOFF, "DMoff"},
46 };
47 
48 /*---------- internal prototypes ----------*/
49 
50 static double gsl_E_solver( double E, void *p );
51 
52 struct E_solver_params {
53  double A, B, x0;
54 };
55 
56 /*==================== FUNCTION DEFINITIONS ====================*/
57 
58 /// \addtogroup SSBtimes_h
59 /// @{
60 
61 /** Compute extra time-delays for a CW source in a (Keplerian) binary orbital system.
62  *
63  *
64  \f[
65  \newcommand{\Det}{{\mathrm{det}}}
66  \newcommand{\tDet}{t_\Det}
67  \newcommand{\tSSB}{t_{\mathrm{SSB}}}
68  \newcommand{\tEM}{t_{\mathrm{em}}}
69  \newcommand{\tRef}{t_{\mathrm{ref}}}
70  \newcommand{\tPeri}{t_{\mathrm{p}}}
71  \newcommand{\TPeri}{T_{\mathrm{p}}}
72  \newcommand{\argp}{\omega}
73  \newcommand{\sini}{\sin i}
74  \newcommand{\fdot}{\dot{f}}
75  \f]
76 
77  * For given binary-orbital parameters in \a Doppler, compute the source-frame emission times \f$ \tEM(\tDet) \f$
78  * of CW wavefronts arriving at the detector frame at times \f$ \tDet \f$ .
79  * The input to this function should contain the wavefront arrival times \f$ \tSSB(\tDet) \f$ in the solar-system barycenter (SSB) frame,
80  * the additional time differences due to the binary orbital motion are then added by this function.
81  *
82  * NOTE: the output vector \a tSSBOut can be passed either as
83  * - unallocated (in this case it must be <tt>(*tSSBOut)==NULL</tt>): it gets allocated here, or
84  * - an allocated vector of the same length as the input vector \a tSSBIn
85  * (this is useful in order to minimize unnecessary memory allocs+frees on repeated calls using the same number of timesteps).
86  *
87  * NOTE2: it is OK to pass an identical in- and output-vector, i.e. <tt>(*tSSBOut) = tSSBIn</tt>: in this case the
88  * binary-orbital time offsets will be added, modifying the input.
89  *
90  * NOTE3: (FIXME!) the SSBtimes structure naming is very misleading: 'SSB' here really refers to the *source emission time*,
91  * not generally the solar-system-barycenter time, so this naming is only correct in the case of isolated NSs.
92  * The additional time-delay computed by this function is between the inertial-SSB time and the source emission time, so
93  * this is quite confusing right now and the corresponding variable-names and documentation should be fixed ASAP.
94  *
95 
96  ## CW Timing Generalities ##
97 
98 Notation: (all times are referring to a global Newtonian time axis):
99 \f{align*}{
100 & \tDet \ldots \text{wave-front arrival time at detector}\\
101 & \tSSB \ldots \text{arrival time at SSB}\\
102 & \tEM \ldots \text{wave-front emission time at the CW source}\\
103 & \tRef \ldots \text{reference time at which} \{\phi_0, f, \fdot, \ldots\} \text{are defined}
104 \f}
105 
106 The intrinsic CW phase in the source frame can be written as
107 \f{equation}{
108 \label{eq:sourcePhase}
109 \begin{split}
110 \Phi(\tEM) &= \phi_0 + 2 \pi \left[ f \, \Delta\tau + \frac{1}{2} \fdot \, \Delta\tau^2 + \ldots \right]\,,\\
111 \Delta\tau &\equiv \tEM - \tRef\,.
112 \end{split}
113 \f}
114 
115 In order to relate this to the CW phase \f$ \Phi_\Det \f$ arriving at the detector, we need the timing relation \f$ \tEM(\tDet) \f$ ,
116 such that \f$ \Phi_\Det(\tDet) = \Phi\left(\tEM(\tDet)\right) \f$ .
117 We also compute the explicit values of the time-derivative, i.e. \f$ \frac{d\tEM}{d \tDet}(\tDet) \f$ , which are required
118 by XLALComputeFaFb(), for example.
119 
120 XLALGetSSBtimes() computes the timing relation between detector time \f$ \tDet \f$ and SSB time \f$ \tSSB \f$ , namely
121 \f{align}{
122 \Delta\tau_0(\tDet) &\equiv \tSSB(\tDet) - \tRef\,,\\
123 \dot{\tau}_0(\tDet) &\equiv \frac{d\tSSB}{d \tDet}(\tDet)\,
124 \f}
125 which is passed to this function as an input in \a tSSBIn. We therefore need to compute the extra time delay due to the binary-orbital motion, namely
126 \f{align}{
127 \Delta\tau(\tDet) &\equiv \tEM(\tDet) - \tRef = [\tEM(\tDet) - \tSSB(\tDet)] + [\tSSB(\tDet) - \tRef] \notag\\
128  &= [\tEM - \tSSB](\tDet) + \Delta\tau_0(\tDet) \,, \label{eq:7a}\\
129 \dot{\tau}(\tDet) &\equiv \frac{d\tEM}{d \tDet}(\tDet) = \frac{d\tEM}{d\tSSB}\left(\tSSB(\tDet)\right) \, \frac{d\tSSB}{d\tDet}(\tDet) \notag\\
130  &= \left[ \frac{d\tEM}{d\tSSB}\left(\tSSB(\tDet)\right) \right]\,\dot{\tau}_0(\tDet)\,, \label{eq:7b}
131 \f}
132 
133 The relation between \f$ \tEM \f$ and \f$ \tSSB \f$ contains an unknown offset due to the distance of the binary system from the
134 SSB, which can be either constant, or changing at a constant or variable rate (eg due to accelerations in globular
135 clusters). However, we can absorb this unknown effect into the definition of the pulsar parameters
136  \f$ \{\phi_0,f,\fdot,\ldots\} \f$ , which are either unknown anyway, or affected by the exact same re-definitions if they are
137 known from photon astronomy. We therefore ignore this effect and pretend that there is no time delay between the SSB and
138 the binary-system barycenter (BSB), ie effectively \f$ \tSSB = t_{\mathrm{BSB}} \f$ .
139 
140 ### (Newtonian) Binary NS Timing equations ###
141 
142 The extra time-delay from the binary orbital motion can be written as
143 \f{equation}{
144  \label{eq:1}
145  \tSSB(\tEM) = \tEM + R(\tEM)\,,
146 \f}
147 where \f$ R \f$ is the radial distance from the BSB to the emitting NS along the line of sight, and here and in the following we are using
148 units where \f$ c=1 \f$ . The sign convention is such that \f$ R>0 \f$ means that the NS is further away than the BSB, when \f$ R<0 \f$ it is closer.
149 
150 In terms of orbital parameters, the radial distance \f$ R \f$ can be expressed as (see \ref inject_binary "this figure").
151 \f{equation}{
152  \label{eq:2}
153  R = r\,\sini\,\sin(\argp + \upsilon)\,,
154 \f}
155 where \f$ r \f$ is the distance of the NS from the BSB (ie the focus of the ellips), \f$ i \f$ is the inclination angle
156 between the orbital plane and the sky, \f$ \argp \f$ is the argument of periapse, and \f$ \upsilon \f$ is the <em>true anomaly</em> (ie
157 the angle from the periapse to the current NS location around the BSB.
158 
159 \anchor Eccentric_and_true_anomaly
160 \image html Eccentric_and_true_anomaly.png "Definition of true anomaly 'v' and eccentric anomaly 'E' to describe an ellipse [Wikipedia]"
161 
162 Using elementary trigonometry (cf. \ref Eccentric_and_true_anomaly "this figure" and https://en.wikipedia.org/wiki/Eccentric_anomaly), one can see that the elliptical
163 orbit can be described in terms of the true anomaly \f$ \upsilon \f$ as
164 \f{equation}{
165  \label{eq:3}
166  r(\upsilon) = \frac{a\,(1- e^2)}{1 + e\cos\upsilon}\,,
167 \f}
168 and in terms of the <em>eccentric anomaly</em> \f$ E \f$ as
169 \f{equation}{
170  \label{eq:4}
171  r(E) = a \, \left( 1 - e\,\cos E\right)\,.
172 \f}
173 From \eqref{eq:3} and \eqref{eq:4} we easily obtain the relations
174 \f{equation}{
175  \begin{split}
176  \cos\upsilon &= \frac{\cos E - e}{1 - e\cos E}\,,\\
177  \sin\upsilon &= \sin E \frac{\sqrt{1 - e^2}}{1 - e\cos E}\,,
178  \end{split}
179  \label{eq:9}
180 \f}
181 where in the second equation we have used the fact that \f$ \sin E \f$ and \f$ \sin\upsilon \f$ always have the same sign, as can be
182 seen from \ref Eccentric_and_true_anomaly "this figure".
183 
184 The (Keplerian) motion of the NS on this elliptical orbit is described by Kepler's equation:
185 \f{equation}{
186  \label{eq:6}
187  \tEM - \tPeri = \frac{P}{2\pi}\left( E - e\,\sin E\right)\,,
188 \f}
189 where we fixed the (discrete) gauge as \f$ E=0 \f$ at \f$ \tEM=\tPeri \f$ .
190 
191 #### Algorithm to solve for \f$ \tEM(\tSSB) \f$ ####
192 
193 Following Teviet's strategy explained in LALGenerateEllipticSpinOrbitCW() we proceed by first expressing \f$ \tSSB(E) \f$ ,
194 solving it numerically for \f$ E(\tSSB) \f$ , from which we obtain by substitution \f$ \tEM(\tSSB) \f$ and
195  \f$ d\tEM/d\tSSB \f$ required for \eqref{eq:7a},\eqref{eq:7b}.
196 
197 We start by writing \eqref{eq:1} using \eqref{eq:6} as
198 \f{equation}{
199  \label{eq:8}
200  \tSSB(E) = \tPeri + \frac{P}{2\pi}\left( E - e\,\sin E\right) + R(E)\,,
201 \f}
202 and using \eqref{eq:2}, \eqref{eq:3} with \eqref{eq:9}, we obtain
203 \f{equation}{
204  \label{eq:R_E}
205  R(E) = a\sini\left[ \sin\argp ( \cos E - e) + \cos\argp\,\sin E \sqrt{1 - e^2} \right]\,,
206 \f}
207 Before solving \eqref{eq:8} for \f$ E(\tSSB) \f$ , it is useful to rewrite it a bit further:
208 First we note that at periapse (i.e. \f$ E=0 \f$ ),
209 \f{equation}{
210 \TPeri \equiv \tSSB(E=0) = \tPeri + a\sini \,\sin\argp\,(1-e)\,, \label{eq:defTPeri}
211 \f}
212 which corresponds to the <em>observed</em> (SSB) time of periapse passage.
213 
214 Furthermore, as pointed out in LALGenerateEllipticSpinOrbitCW(), the (Newtonian) binary NS timing is periodic, namely
215  \f$ \tSSB(E + m\,2\pi) = \tSSB(E) + m\,P \f$ for integer \f$ m \f$ , and we can therefore simplify the numerical solution of \eqref{eq:8} for \f$ E(\tSSB) \f$ by
216 restricting the solution to the interval \f$ E\in[0,2\pi) \f$ by mapping \f$ \tSSB \f$ into \f$ [\TPeri,\,\TPeri + P) \f$ , via
217 \f{equation}{
218 x_0 \equiv \frac{2\pi}{P} (\tSSB - \TPeri) \mod 2\pi\,,
219 \f}
220 where we add \f$ 2\pi \f$ if \f$ x_0 < 0 \f$ to ensure that \f$ x_0 \in [0,\,2\pi) \f$ .
221 We can therefore rewrite \eqref{eq:8} as
222 \f{align}{
223 x_0 &= E + A\,\sin E + B \,( \cos E -1 )\,, \label{eq:E_tSSB}\\
224 A &\equiv \frac{2\pi}{P}\, a\sini \,\cos\argp\,\sqrt{1-e^2} - e\,, \label{eq:defA}\\
225 B &\equiv \frac{2\pi}{P}\, a\sini \,\sin\argp\,, \label{eq:defB}
226 \f}
227 which (after some substitutions) can be seen to agree with Teviet's equation found in LALGenerateEllipticSpinOrbitCW().
228 
229 This is solved numerically for \f$ E(\tSSB) \in [0,\,2\pi) \f$ , and plugging this back into \eqref{eq:R_E} and \eqref{eq:1}
230 we obtain \f$ \tEM(E) \f$ , and from this the required timing relation \eqref{eq:7a}.
231 
232 #### Computing the derivate \f$ d\tEM/d\tSSB \f$ ####
233 
234 We start from \eqref{eq:1} and write,
235 \f{equation}{
236  \label{eq:12}
237  \frac{d\tEM}{d\tSSB} = \left[\frac{d\tSSB}{d\tEM}\right]^{-1} = \left[1 + \frac{dR}{d E}\,\frac{d E}{d\tEM}\right]^{-1}\,.
238 \f}
239 From \eqref{eq:6} we obtain
240 \f{equation}{
241  \label{eq:11}
242  \frac{d E}{d\tEM} = \frac{2\pi}{P} \frac{1}{1 - e\cos E}\,,
243 \f}
244 and \eqref{eq:R_E} yields
245 \f{equation}{
246 \label{eq:13}
247 \begin{split}
248  \frac{dR}{d E} &= a\sini\left[ - \sin E \, \sin\argp + \cos E\,\cos\argp\,\sqrt{1- e^2}\right]\\
249  &= \frac{P}{2\pi}\left( (A + e)\,\cos E - B\,\sin E \right)\,,
250 \end{split}
251 \f}
252 which results in the derivative of \eqref{eq:12} to be expressible as
253 \f{equation}{
254 \label{eq:dtEM_dtSSB}
255 \frac{d\tEM}{d\tSSB} = \frac{1 - e\cos E}{1 + A\,\cos E - B \,\sin E}\,.
256 \f}
257 */
258 int
259 XLALAddBinaryTimes( SSBtimes **tSSBOut, //!< [out] reference-time offsets in emission frame: \f$ \tEM(\tDet)-\tRef \f$ and \f$ d\tEM/d\tDet \f$
260  const SSBtimes *tSSBIn, //!< [in] reference-time offsets in SSB frame: \f$ \tSSB(\tDet)-\tRef \f$ and \f$ d\tSSB/d\tDet \f$
261  const PulsarDopplerParams *Doppler //!< [in] pulsar Doppler parameters, includes binary orbit parameters */
262  )
263 {
264  XLAL_CHECK( tSSBIn != NULL, XLAL_EINVAL, "Invalid NULL input 'tSSB'\n" );
265  XLAL_CHECK( tSSBIn->DeltaT != NULL, XLAL_EINVAL, "Invalid NULL input 'tSSBIn->DeltaT'\n" );
266  XLAL_CHECK( tSSBIn->Tdot != NULL, XLAL_EINVAL, "Invalid NULL input 'tSSBIn->Tdot'\n" );
267 
268  XLAL_CHECK( Doppler != NULL, XLAL_EINVAL, "Invalid NULL input 'Doppler'\n" );
269  XLAL_CHECK( Doppler->asini >= 0, XLAL_EINVAL );
270 
271  UINT4 numSteps = tSSBIn->DeltaT->length; /* number of timesteps */
272  XLAL_CHECK( tSSBIn->Tdot->length == numSteps, XLAL_EINVAL,
273  "Length tSSBIn->DeltaT = %d, while tSSBIn->Tdot = %d\n", numSteps, tSSBIn->Tdot->length );
274 
275  SSBtimes *binaryTimes;
276  // ----- prepare output timeseries: either allocate or re-use existing
277  if ( ( *tSSBOut ) == NULL ) { // creating new output vector
278  XLAL_CHECK( ( binaryTimes = XLALDuplicateSSBtimes( tSSBIn ) ) != NULL, XLAL_EFUNC );
279  } else if ( ( *tSSBOut ) == tSSBIn ) { // input==output vector
280  binaryTimes = ( *tSSBOut );
281  } else { // input vector given, but not identical to output vector
282  binaryTimes = ( *tSSBOut );
283  // need to do a few more sanity checks
284  XLAL_CHECK( binaryTimes->DeltaT->length == numSteps, XLAL_EINVAL,
285  "Length (*tSSBOut)->DeltaT = %d, while tSSBIn->DeltaT = %d\n", binaryTimes->DeltaT->length, numSteps );
286  XLAL_CHECK( binaryTimes->Tdot->length == numSteps, XLAL_EINVAL,
287  "Length tSSBOut->Tdot = %d, while tSSBIn->Tdot = %d\n", binaryTimes->Tdot->length, numSteps );
288  // ... and copy the vector contents from the input SSB vector
289  binaryTimes->refTime = tSSBIn->refTime;
290  memcpy( binaryTimes->DeltaT->data, tSSBIn->DeltaT->data, numSteps * sizeof( binaryTimes->DeltaT->data[0] ) );
291  memcpy( binaryTimes->Tdot->data, tSSBIn->Tdot->data, numSteps * sizeof( binaryTimes->Tdot->data[0] ) );
292  } // re-using input vector
293 
294  /* ----- convenience variables */
295  REAL8 Porb = Doppler->period; /* binary orbital period */
296  REAL8 e = Doppler->ecc; /* the eccentricity */
297  REAL8 sqrtome2 = sqrt( 1.0 - e * e );
298  REAL8 asini = Doppler->asini; /* the projected orbital semimajor axis */
299  REAL8 argp = Doppler->argp;
300  REAL8 sinw = sin( argp ); /* the sin and cos of the argument of periapsis */
301  REAL8 cosw = cos( argp );
302  REAL8 n = LAL_TWOPI / Porb;
303  REAL8 Freq = Doppler->fkdot[0];
304 
305  REAL8 refTimeREAL8 = XLALGPSGetREAL8( &tSSBIn->refTime );
306 
307  // compute time-independent coefficients for tSSB(E) equation
308  REAL8 A = n * asini * cosw * sqrtome2 - e; // see Eq.(eq:defA)
309  REAL8 B = n * asini * sinw; // see Eq.(eq:defB)
310  REAL8 tp = XLALGPSGetREAL8( &( Doppler->tp ) );
311  REAL8 Tp = tp + asini * sinw * ( 1 - e ); // see Eq.(eq:defTPeri)
312 
313  REAL8 maxPhaseErr = 1e-3; // maximal allowed CW phase-error due to error in E
314  REAL8 epsabs = maxPhaseErr / ( Freq * Porb ); // absolute root-finding accuracy required on E
315  REAL8 epsrel = 0; // no constraint on relative accuracy
316 
317  /* loop over the SFTs i */
318  for ( UINT4 i = 0; i < numSteps; i++ ) {
319  REAL8 tSSB_i = refTimeREAL8 + tSSBIn->DeltaT->data[i]; // SSB time for the current SFT midpoint
320  REAL8 fracOrb_i = fmod( tSSB_i - Tp, Porb ) / Porb; // fractional orbit
321  if ( fracOrb_i < 0 ) {
322  fracOrb_i += 1; // enforce fracOrb to be within [0, 1)
323  }
324  REAL8 x0 = fracOrb_i * LAL_TWOPI;
325  REAL8 E_i; // eccentric anomaly at emission of the wavefront arriving in SSB at tSSB
326  {
327  // ---------- use GSL for the root-finding
328  const gsl_root_fsolver_type *T = gsl_root_fsolver_brent;
329  gsl_root_fsolver *s = gsl_root_fsolver_alloc( T );
330  REAL8 E_lo = 0, E_hi = LAL_TWOPI; // gauge-choice mod (2pi)
331  gsl_function F;
332  struct E_solver_params pars = {A, B, x0};
333  F.function = &gsl_E_solver;
334  F.params = &pars;
335 
336  XLAL_CHECK( gsl_root_fsolver_set( s, &F, E_lo, E_hi ) == 0, XLAL_EFAILED );
337 
338  int max_iter = 100;
339  int iter = 0;
340  int status;
341  do {
342  iter++;
343  status = gsl_root_fsolver_iterate( s );
344  XLAL_CHECK( ( status == GSL_SUCCESS ) || ( status == GSL_CONTINUE ), XLAL_EFAILED );
345  E_i = gsl_root_fsolver_root( s );
346  E_lo = gsl_root_fsolver_x_lower( s );
347  E_hi = gsl_root_fsolver_x_upper( s );
348  status = gsl_root_test_interval( E_lo, E_hi, epsabs, epsrel );
349 
350  } while ( ( status == GSL_CONTINUE ) && ( iter < max_iter ) );
351 
352  XLAL_CHECK( status == GSL_SUCCESS, XLAL_EMAXITER, "Eccentric anomaly: failed to converge to epsabs=%g within %d iterations\n", epsabs, max_iter );
353  gsl_root_fsolver_free( s );
354  } // gsl-root finding block
355 
356  // use this value of E(tSSB) to compute the additional binary time delay
357  REAL8 sinE = sin( E_i );
358  REAL8 cosE = cos( E_i );
359 
360  REAL8 R = asini * ( sinw * ( cosE - e ) + cosw * sinE * sqrtome2 ); // see Eq.(eq:R_E)
361  REAL8 dtEM_dtSSB = ( 1.0 - e * cosE ) / ( 1.0 + A * cosE - B * sinE ); // see Eq.(eq:dt_EMdtSSB)
362 
363  binaryTimes->DeltaT->data[i] -= R;
364  binaryTimes->Tdot->data[i] *= dtEM_dtSSB;
365 
366  } /* for i < numSteps */
367 
368  // pass back output SSB timings
369  ( *tSSBOut ) = binaryTimes;
370 
371  return XLAL_SUCCESS;
372 
373 } /* XLALAddBinaryTimes() */
374 
375 /** Function implementing \eqref{eq:E_tSSB} to be solved via numerical root-finder for \f$ E(\tSSB) \f$
376  */
377 static double
378 gsl_E_solver( REAL8 E, void *par )
379 {
380  struct E_solver_params *params = ( struct E_solver_params * ) par;
381  double A = params->A;
382  double B = params->B;
383  double x0 = params->x0;
384 
385  double diff = - x0 + ( E + A * sin( E ) + B * ( cos( E ) - 1.0 ) );
386 
387  return diff;
388 } // gsl_E_solver()
389 
390 
391 /**
392  * Multi-IFO version of XLALAddBinaryTimes().
393 
394  * For given binary-orbital parameters in \a Doppler, compute the source-frame emission times \f$ \tEM(\tDet) \f$
395  * of CW wavefronts arriving at the detector frame at times \f$ \tDet \f$ .
396  * The input to this function should contain the wavefront arrival times \f$ \tSSB(\tDet) \f$ in the solar-system barycenter (SSB) frame,
397  * the additional time differences due to the binary orbital motion are then added by this function.
398  *
399  * NOTE: the output vector \a multiSSBOut can be passed either as
400  * - unallocated (in this case it must be <tt>(*tSSBOut)==NULL</tt>): it gets allocated here, or
401  * - an allocated vector of the same length as the input vector \a multiSSBIn
402  * (this is useful in order to minimize unnecessary memory allocs+frees on repeated calls using the same number of timesteps).
403  *
404  * NOTE2: it is OK to pass an identical in- and output-vector, i.e. <tt>(*tSSBOut) = tSSBIn</tt>: in this case the
405  * binary-orbital time offsets will be added, modifying the input.
406  *
407  * NOTE3: (FIXME!) the SSBtimes structure naming is very misleading: 'SSB' here really refers to the *source emission time*,
408  * not generally the solar-system-barycenter time, so this naming is only correct in the case of isolated NSs.
409  * The additional time-delay computed by this function is between the inertial-SSB time and the source emission time, so
410  * this is quite confusing right now and the corresponding variable-names and documentation should be fixed ASAP.
411  */
412 int
413 XLALAddMultiBinaryTimes( MultiSSBtimes **multiSSBOut, /**< [out] output SSB times */
414  const MultiSSBtimes *multiSSBIn, /**< [in] SSB-timings for all input detector-state series */
415  const PulsarDopplerParams *Doppler /**< [in] pulsar Doppler parameters, includes binary orbit parameters */
416  )
417 {
418  /* check input */
419  XLAL_CHECK( multiSSBIn != NULL, XLAL_EINVAL, "Invalid NULL input 'multiSSB'\n" );
420  XLAL_CHECK( Doppler != NULL, XLAL_EINVAL, "Invalid NULL input 'Doppler'\n" );
421  XLAL_CHECK( Doppler->asini >= 0, XLAL_EINVAL );
422 
423  UINT4 numDetectors = multiSSBIn->length;
424 
425  MultiSSBtimes *multiBinaryTimes;
426  // ----- prepare output timeseries: either allocate or re-use existing
427  if ( ( *multiSSBOut ) == NULL ) { // creating new output vector
428  XLAL_CHECK( ( multiBinaryTimes = XLALDuplicateMultiSSBtimes( multiSSBIn ) ) != NULL, XLAL_EFUNC );
429  } else { // input vector given
430  multiBinaryTimes = ( *multiSSBOut );
431  XLAL_CHECK( multiBinaryTimes->length == numDetectors, XLAL_EINVAL,
432  "Inconsistent length (*multiSSBOut)->length = %d, while multiSSBIn->length = %d\n", ( *multiSSBOut )->length, numDetectors );
433  // we'll leave all other sanity-checks to XLALAddBinaryTimes() calls
434  }
435 
436  // ----- simply loop over detectors for XLALAddBinaryTimes()
437  for ( UINT4 X = 0; X < numDetectors; X ++ ) {
438  int ret = XLALAddBinaryTimes( &( multiBinaryTimes->data[X] ), multiSSBIn->data[X], Doppler );
439  XLAL_CHECK( ret == XLAL_SUCCESS, XLAL_EFUNC, "XLALAddBinaryTimes() failed for X=%d\n", X );
440  } /* for X < numDet */
441 
442  // pass back result-vector
443  ( *multiSSBOut ) = multiBinaryTimes;
444 
445  return XLAL_SUCCESS;
446 
447 } /* XLALAddMultiBinaryTimes() */
448 
449 
450 /** Duplicate (ie allocate + copy) an input SSBtimes structure.
451  * This can be useful for creating a copy before adding binary-orbital corrections in XLALAddBinaryTimes()
452  */
453 SSBtimes *
455 {
456  XLAL_CHECK_NULL( tSSB != NULL, XLAL_EINVAL, "Invalid NULL input 'tSSB'\n" );
457 
458  UINT4 len;
459  SSBtimes *ret;
460  ret = XLALCalloc( 1, len = sizeof( *ret ) );
461  XLAL_CHECK_NULL( ret != NULL, XLAL_ENOMEM, "Failed to XLALCalloc ( 1, %d )\n", len );
462 
463  ret->refTime = tSSB->refTime;
464 
465  if ( tSSB->DeltaT ) {
466  len = tSSB->DeltaT->length;
467  ret->DeltaT = XLALCreateREAL8Vector( len );
468  XLAL_CHECK_NULL( ret->DeltaT != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector(%d) failed\n", len );
469  memcpy( ret->DeltaT->data, tSSB->DeltaT->data, len * sizeof( ret->DeltaT->data[0] ) );
470  }
471 
472  if ( tSSB->Tdot ) {
473  len = tSSB->Tdot->length;
474  ret->Tdot = XLALCreateREAL8Vector( len );
475  XLAL_CHECK_NULL( ret->Tdot != NULL, XLAL_EFUNC, "XLALCreateREAL8Vector(%d) failed\n", len );
476  memcpy( ret->Tdot->data, tSSB->Tdot->data, len * sizeof( ret->Tdot->data[0] ) );
477  }
478 
479  return ret;
480 
481 } /* XLALDuplicateSSBtimes() */
482 
483 
484 /** Duplicate (ie allocate + copy) an input MultiSSBtimes structure.
485  */
488 {
489  XLAL_CHECK_NULL( multiSSB != NULL, XLAL_EINVAL, "Invalid NULL input 'multiSSB'\n" );
490 
491  UINT4 len;
492  MultiSSBtimes *ret;
493  ret = XLALCalloc( 1, len = sizeof( *ret ) );
494  XLAL_CHECK_NULL( ret != NULL, XLAL_ENOMEM, "Failed to XLALCalloc ( 1, %d )\n", len );
495 
496  UINT4 numDetectors = multiSSB->length;
497  ret->length = numDetectors;
498  ret->data = XLALCalloc( numDetectors, len = sizeof( ret->data[0] ) );
499  XLAL_CHECK_NULL( ret->data != NULL, XLAL_ENOMEM, "Failed to XLALCalloc ( %d, %d )\n", numDetectors, len );
500 
501  for ( UINT4 X = 0; X < numDetectors; X ++ ) {
502  ret->data[X] = XLALDuplicateSSBtimes( multiSSB->data[X] );
503  XLAL_CHECK_NULL( ret->data[X] != NULL, XLAL_EFUNC, "XLALDuplicateSSBtimes() failed for detector X=%d\n", X );
504  } // for X < numDetectors
505 
506  return ret;
507 
508 } /* XLALDuplicateMultiSSBtimes() */
509 
510 /** For a given DetectorStateSeries, calculate the time-differences
511  * \f$ \Delta T_\alpha\equiv T(t_\alpha) - T_0 \f$ , and their
512  * derivatives \f$ \dot{T}_\alpha \equiv d T / d t (t_\alpha) \f$ .
513  *
514  * \note The return-vector is allocated here
515  *
516  */
517 SSBtimes *
518 XLALGetSSBtimes( const DetectorStateSeries *DetectorStates, /**< [in] detector-states at timestamps t_i */
519  SkyPosition pos, /**< source sky-location */
520  LIGOTimeGPS refTime, /**< SSB reference-time T_0 of pulsar-parameters */
521  SSBprecision precision /**< relativistic or Newtonian SSB transformation? */
522  )
523 {
524  XLAL_CHECK_NULL( DetectorStates != NULL, XLAL_EINVAL, "Invalid NULL input 'DetectorStates'\n" );
525  XLAL_CHECK_NULL( precision < SSBPREC_LAST, XLAL_EDOM, "Invalid value precision=%d, allowed are [0, %d]\n", precision, SSBPREC_LAST - 1 );
526  XLAL_CHECK_NULL( pos.system == COORDINATESYSTEM_EQUATORIAL, XLAL_EDOM, "Only equatorial coordinate system (=%d) allowed, got %d\n", COORDINATESYSTEM_EQUATORIAL, pos.system );
527 
528  UINT4 numSteps = DetectorStates->length; /* number of timestamps */
529 
530  // prepare output SSBtimes struct
531  int len;
532  SSBtimes *ret = XLALCalloc( 1, len = sizeof( *ret ) );
533  XLAL_CHECK_NULL( ret != NULL, XLAL_ENOMEM, "Failed to XLALCalloc(1,%d)\n", len );
534  ret->DeltaT = XLALCreateREAL8Vector( numSteps );
535  XLAL_CHECK_NULL( ret->DeltaT != NULL, XLAL_EFUNC, "ret->DeltaT = XLALCreateREAL8Vector(%d) failed\n", numSteps );
536  ret->Tdot = XLALCreateREAL8Vector( numSteps );
537  XLAL_CHECK_NULL( ret->Tdot != NULL, XLAL_EFUNC, "ret->Tdot = XLALCreateREAL8Vector(%d) failed\n", numSteps );
538 
539  /* convenience variables */
540  REAL8 alpha = pos.longitude;
541  REAL8 delta = pos.latitude;
542  REAL8 refTimeREAL8 = XLALGPSGetREAL8( &refTime );
543  BarycenterBuffer *bBuffer = NULL;
544 
545  BarycenterInput XLAL_INIT_DECL( baryinput );
546 
547  /*----- now calculate the SSB transformation in the precision required */
548  switch ( precision ) {
549  REAL8 vn[3]; /* unit-vector pointing to source in Cart. coord. */
550 
551  case SSBPREC_NEWTONIAN: /* use simple vr.vn to calculate time-delay */
552 
553  /*----- get the cartesian source unit-vector */
554  vn[0] = cos( alpha ) * cos( delta );
555  vn[1] = sin( alpha ) * cos( delta );
556  vn[2] = sin( delta );
557 
558  for ( UINT4 i = 0; i < numSteps; i++ ) {
559  LIGOTimeGPS *ti = &( DetectorStates->data[i].tGPS );
560  /* DeltaT_alpha */
561  ret->DeltaT->data[i] = XLALGPSGetREAL8( ti );
562  ret->DeltaT->data[i] += SCALAR( vn, DetectorStates->data[i].rDetector );
563  ret->DeltaT->data[i] -= refTimeREAL8;
564 
565  /* Tdot_alpha */
566  ret->Tdot->data[i] = 1.0 + SCALAR( vn, DetectorStates->data[i].vDetector );
567 
568  } /* for i < numSteps */
569 
570  break;
571 
572  case SSBPREC_RELATIVISTIC: /* use XLALBarycenter() to get SSB-times and derivative */
573 
574  baryinput.site = DetectorStates->detector;
575  baryinput.site.location[0] /= LAL_C_SI;
576  baryinput.site.location[1] /= LAL_C_SI;
577  baryinput.site.location[2] /= LAL_C_SI;
578 
579  baryinput.alpha = alpha;
580  baryinput.delta = delta;
581  baryinput.dInv = 0;
582 
583  for ( UINT4 i = 0; i < numSteps; i++ ) {
584  EmissionTime emit;
585  DetectorState *state = &( DetectorStates->data[i] );
586 
587  baryinput.tgps = state->tGPS;
588 
589  if ( XLALBarycenter( &emit, &baryinput, &( state->earthState ) ) != XLAL_SUCCESS ) {
590  XLAL_ERROR_NULL( XLAL_EFUNC, "XLALBarycenter() failed with xlalErrno = %d\n", xlalErrno );
591  }
592 
593  ret->DeltaT->data[i] = XLALGPSGetREAL8( &emit.te ) - refTimeREAL8;
594  ret->Tdot->data[i] = emit.tDot;
595 
596  } /* for i < numSteps */
597 
598  break;
599 
600  case SSBPREC_RELATIVISTICOPT: /* use optimized version XLALBarycenterOpt() */
601 
602  baryinput.site = DetectorStates->detector;
603  baryinput.site.location[0] /= LAL_C_SI;
604  baryinput.site.location[1] /= LAL_C_SI;
605  baryinput.site.location[2] /= LAL_C_SI;
606 
607  baryinput.alpha = alpha;
608  baryinput.delta = delta;
609  baryinput.dInv = 0;
610 
611  for ( UINT4 i = 0; i < numSteps; i++ ) {
612  EmissionTime emit;
613  DetectorState *state = &( DetectorStates->data[i] );
614  baryinput.tgps = state->tGPS;
615 
616  if ( XLALBarycenterOpt( &emit, &baryinput, &( state->earthState ), &bBuffer ) != XLAL_SUCCESS ) {
617  XLAL_ERROR_NULL( XLAL_EFUNC, "XLALBarycenterOpt() failed with xlalErrno = %d\n", xlalErrno );
618  }
619 
620  ret->DeltaT->data[i] = XLALGPSGetREAL8( &emit.te ) - refTimeREAL8;
621  ret->Tdot->data[i] = emit.tDot;
622 
623  } /* for i < numSteps */
624  // free buffer memory
625  XLALFree( bBuffer );
626 
627  break;
628 
629  case SSBPREC_DMOFF: /* switch off all demodulation terms */
630 
631  for ( UINT4 i = 0; i < numSteps; i++ ) {
632  DetectorState *state = &( DetectorStates->data[i] );
633  ret->DeltaT->data[i] = XLALGPSGetREAL8( &state->tGPS ) - refTimeREAL8;
634  ret->Tdot->data[i] = 1.0;
635  } /* for i < numSteps */
636  break;
637 
638  default:
639  XLAL_ERROR_NULL( XLAL_EFAILED, "\n?? Something went wrong.. this should never be called!\n\n" );
640  break;
641  } /* switch precision */
642 
643  /* finally: store the reference-time used into the output-structure */
644  ret->refTime = refTime;
645 
646  return ret;
647 
648 } /* XLALGetSSBtimes() */
649 
650 /** Multi-IFO version of XLALGetSSBtimes().
651  * Get all SSB-timings for all input detector-series.
652  *
653  * NOTE: this functions *allocates* the output-vector,
654  * use XLALDestroyMultiSSBtimes() to free this.
655  */
657 XLALGetMultiSSBtimes( const MultiDetectorStateSeries *multiDetStates, /**< [in] detector-states at timestamps t_i */
658  SkyPosition skypos, /**< source sky-position [in equatorial coords!] */
659  LIGOTimeGPS refTime, /**< SSB reference-time T_0 for SSB-timing */
660  SSBprecision precision /**< use relativistic or Newtonian SSB timing? */
661  )
662 {
663  /* check input */
664  XLAL_CHECK_NULL( multiDetStates != NULL, XLAL_EINVAL, "Invalid NULL input 'multiDetStates'\n" );
665  XLAL_CHECK_NULL( multiDetStates->length > 0, XLAL_EINVAL, "Invalid zero-length 'multiDetStates'\n" );
666 
667  UINT4 numDetectors = multiDetStates->length;
668 
669  // prepare return struct
670  int len;
671  MultiSSBtimes *ret = XLALCalloc( 1, len = sizeof( *ret ) );
672  XLAL_CHECK_NULL( ret != NULL, XLAL_ENOMEM, "Failed to XLALCalloc(1,%d)\n", len );
673  ret->length = numDetectors;
674  ret->data = XLALCalloc( numDetectors, len = sizeof( *ret->data ) );
675  XLAL_CHECK_NULL( ret->data != NULL, XLAL_ENOMEM, "Failed to XLALCalloc(%d,%d)\n", numDetectors, len );
676 
677  // loop over detectors
678  for ( UINT4 X = 0; X < numDetectors; X ++ ) {
679  ret->data[X] = XLALGetSSBtimes( multiDetStates->data[X], skypos, refTime, precision );
680  XLAL_CHECK_NULL( ret->data[X] != NULL, XLAL_EFUNC, "ret->data[%d] = XLALGetSSBtimes() failed with xlalErrno = %d\n", X, xlalErrno );
681 
682  } /* for X < numDet */
683 
684  return ret;
685 
686 } /* XLALGetMultiSSBtimes() */
687 
688 /** Find the earliest timestamp in a multi-SSB data structure
689  *
690 */
691 int XLALEarliestMultiSSBtime( LIGOTimeGPS *out, /**< output earliest GPS time */
692  const MultiSSBtimes *multiSSB, /**< input multi SSB SFT-midpoint timestamps */
693  const REAL8 Tsft /**< the length of an SFT */
694  )
695 {
696  UINT4 i, j;
697  LIGOTimeGPS t;
698  REAL8 delta;
699 
700  /* check sanity of input */
701  if ( !multiSSB || ( multiSSB->length == 0 ) ) {
702  XLALPrintError( "%s: empty multiSSBtimes input!\n", __func__ );
704  }
705  if ( !multiSSB->data[0] || ( multiSSB->data[0]->DeltaT->length == 0 ) ) {
706  XLALPrintError( "%s: empty multiSSBtimes input!\n", __func__ );
708  }
709 
710 
711  /* initialise the earliest and latest sample value */
712  out->gpsSeconds = multiSSB->data[0]->refTime.gpsSeconds;
713  out->gpsNanoSeconds = multiSSB->data[0]->refTime.gpsNanoSeconds;
714  delta = multiSSB->data[0]->DeltaT->data[0] - 0.5 * Tsft * multiSSB->data[0]->Tdot->data[0];
715  if ( ( XLALGPSAdd( out, delta ) ) == NULL ) {
716  XLALPrintError( "%s: XLALGPSAdd() failed! errno = %d!\n", __func__, xlalErrno );
718  }
719  /* loop over detectors */
720  for ( i = 0; i < multiSSB->length; i++ ) {
721 
722  /* loop over all SSB times and find the earliest SSB SFT start time */
723  for ( j = 0; j < multiSSB->data[i]->DeltaT->length; j++ ) {
724 
725  /* reset the reference time */
726  t.gpsSeconds = multiSSB->data[i]->refTime.gpsSeconds;
727  t.gpsNanoSeconds = multiSSB->data[i]->refTime.gpsNanoSeconds;
728 
729  /* compute SSB time - we approximate the SFT start time in the SSB as t_mid_SSB - 0.5*Tsft*dt_SSB/dt_det */
730  delta = multiSSB->data[i]->DeltaT->data[j] - 0.5 * Tsft * multiSSB->data[i]->Tdot->data[j];
731  if ( ( XLALGPSAdd( &t, delta ) ) == NULL ) {
732  XLALPrintError( "%s: XLALGPSAdd() failed! errno = %d!\n", __func__, xlalErrno );
734  }
735 
736  /* compare it to the existing earliest */
737  if ( ( XLALGPSCmp( out, &t ) == 1 ) ) {
738  out->gpsSeconds = t.gpsSeconds;
739  out->gpsNanoSeconds = t.gpsNanoSeconds;
740  }
741 
742  }
743 
744  }
745 
746  /* success */
747  return XLAL_SUCCESS;
748 
749 } /* XLALEarliestMultiSSBtime() */
750 
751 /** Find the latest timestamp in a multi-SSB data structure
752  *
753 */
754 int XLALLatestMultiSSBtime( LIGOTimeGPS *out, /**< output latest GPS time */
755  const MultiSSBtimes *multiSSB, /**< input multi SSB SFT-midpoint timestamps */
756  const REAL8 Tsft /**< the length of an SFT */
757  )
758 {
759  UINT4 i, j;
760  LIGOTimeGPS t;
761  REAL8 delta;
762 
763  /* check sanity of input */
764  if ( !multiSSB || ( multiSSB->length == 0 ) ) {
765  XLALPrintError( "%s: empty multiSSBtimes input!\n", __func__ );
767  }
768  if ( !multiSSB->data[0] || ( multiSSB->data[0]->DeltaT->length == 0 ) ) {
769  XLALPrintError( "%s: empty multiSSBtimes input!\n", __func__ );
771  }
772 
773 
774  /* initialise the earliest and latest sample value */
775  out->gpsSeconds = multiSSB->data[0]->refTime.gpsSeconds;
776  out->gpsNanoSeconds = multiSSB->data[0]->refTime.gpsNanoSeconds;
777  delta = multiSSB->data[0]->DeltaT->data[0] + 0.5 * Tsft * multiSSB->data[0]->Tdot->data[0];
778  if ( ( XLALGPSAdd( out, delta ) ) == NULL ) {
779  XLALPrintError( "%s: XLALGPSAdd() failed! errno = %d!\n", __func__, xlalErrno );
781  }
782  /* loop over detectors */
783  for ( i = 0; i < multiSSB->length; i++ ) {
784 
785  /* loop over all SSB times and find the latest SSB SFT start time */
786  for ( j = 0; j < multiSSB->data[i]->DeltaT->length; j++ ) {
787 
788  /* reset the reference time */
789  t.gpsSeconds = multiSSB->data[i]->refTime.gpsSeconds;
790  t.gpsNanoSeconds = multiSSB->data[i]->refTime.gpsNanoSeconds;
791 
792  /* compute SSB time - we approximate the SFT end time in the SSB as t_mid_SSB + 0.5*Tsft*dt_SSB/dt_det */
793  delta = multiSSB->data[i]->DeltaT->data[j] + 0.5 * Tsft * multiSSB->data[i]->Tdot->data[j];
794  if ( ( XLALGPSAdd( &t, delta ) ) == NULL ) {
795  XLALPrintError( "%s: XLALGPSAdd() failed! errno = %d!\n", __func__, xlalErrno );
797  }
798 
799  /* compare it to the existing earliest */
800  if ( ( XLALGPSCmp( out, &t ) == -1 ) ) {
801  out->gpsSeconds = t.gpsSeconds;
802  out->gpsNanoSeconds = t.gpsNanoSeconds;
803  }
804 
805  }
806 
807  }
808 
809  /* success */
810  return XLAL_SUCCESS;
811 
812 } /* XLALLatestMultiSSBtime() */
813 
814 /* ===== Object creation/destruction functions ===== */
815 
816 /** Destroy a SSBtimes structure.
817  * Note, this is "NULL-robust" in the sense that it will not crash
818  * on NULL-entries anywhere in this struct, so it can be used
819  * for failure-cleanup even on incomplete structs
820  */
821 void
823 {
824 
825  if ( ! tSSB ) {
826  return;
827  }
828 
829  if ( tSSB->DeltaT ) {
831  }
832  if ( tSSB->Tdot ) {
833  XLALDestroyREAL8Vector( tSSB->Tdot );
834  }
835  XLALFree( tSSB );
836 
837 }
838 
839 /** Destroy a MultiSSBtimes structure.
840  * Note, this is "NULL-robust" in the sense that it will not crash
841  * on NULL-entries anywhere in this struct, so it can be used
842  * for failure-cleanup even on incomplete structs
843  */
844 void
846 {
847  UINT4 X;
848 
849  if ( ! multiSSB ) {
850  return;
851  }
852 
853  if ( multiSSB->data ) {
854  for ( X = 0; X < multiSSB->length; X ++ ) {
855  XLALDestroySSBtimes( multiSSB->data[X] );
856  } /* for X < numDetectors */
857  LALFree( multiSSB->data );
858  }
859  LALFree( multiSSB );
860 
861  return;
862 
863 } /* XLALDestroyMultiSSBtimes() */
864 
865 /// @}
#define __func__
log an I/O error, i.e.
int j
#define LALFree(p)
static double double delta
UINT2 A
Definition: SFTnaming.c:46
UINT2 B
Definition: SFTnaming.c:47
#define SCALAR(u, v)
Simple Euklidean scalar product for two 3-dim vectors in cartesian coords.
Definition: SSBtimes.c:37
int s
double e
int XLALBarycenterOpt(EmissionTime *emit, const BarycenterInput *baryinput, const EarthState *earth, BarycenterBuffer **buffer)
Speed optimized version of XLALBarycenter(), should be fully equivalent except for the additional buf...
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...
#define LAL_TWOPI
double REAL8
#define XLAL_INIT_DECL(var,...)
uint32_t UINT4
void * XLALCalloc(size_t m, size_t n)
void XLALFree(void *p)
SSBprecision
The precision in calculating the barycentric transformation.
Definition: SSBtimes.h:45
int XLALEarliestMultiSSBtime(LIGOTimeGPS *out, const MultiSSBtimes *multiSSB, const REAL8 Tsft)
Find the earliest timestamp in a multi-SSB data structure.
Definition: SSBtimes.c:691
MultiSSBtimes * XLALGetMultiSSBtimes(const MultiDetectorStateSeries *multiDetStates, SkyPosition skypos, LIGOTimeGPS refTime, SSBprecision precision)
Multi-IFO version of XLALGetSSBtimes().
Definition: SSBtimes.c:657
const UserChoices SSBprecisionChoices
Static array of all SSBprecision choices, for use by the UserInput module parsing routines.
Definition: SSBtimes.c:41
void XLALDestroyMultiSSBtimes(MultiSSBtimes *multiSSB)
Destroy a MultiSSBtimes structure.
Definition: SSBtimes.c:845
void XLALDestroySSBtimes(SSBtimes *tSSB)
Destroy a SSBtimes structure.
Definition: SSBtimes.c:822
SSBtimes * XLALGetSSBtimes(const DetectorStateSeries *DetectorStates, SkyPosition pos, LIGOTimeGPS refTime, SSBprecision precision)
For a given DetectorStateSeries, calculate the time-differences , and their derivatives .
Definition: SSBtimes.c:518
int XLALAddMultiBinaryTimes(MultiSSBtimes **multiSSBOut, const MultiSSBtimes *multiSSBIn, const PulsarDopplerParams *Doppler)
Multi-IFO version of XLALAddBinaryTimes().
Definition: SSBtimes.c:413
static double gsl_E_solver(double E, void *p)
Function implementing Eq.
Definition: SSBtimes.c:378
int XLALLatestMultiSSBtime(LIGOTimeGPS *out, const MultiSSBtimes *multiSSB, const REAL8 Tsft)
Find the latest timestamp in a multi-SSB data structure.
Definition: SSBtimes.c:754
MultiSSBtimes * XLALDuplicateMultiSSBtimes(const MultiSSBtimes *multiSSB)
Duplicate (ie allocate + copy) an input MultiSSBtimes structure.
Definition: SSBtimes.c:487
int XLALAddBinaryTimes(SSBtimes **tSSBOut, const SSBtimes *tSSBIn, const PulsarDopplerParams *Doppler)
Compute extra time-delays for a CW source in a (Keplerian) binary orbital system.
Definition: SSBtimes.c:259
SSBtimes * XLALDuplicateSSBtimes(const SSBtimes *tSSB)
Duplicate (ie allocate + copy) an input SSBtimes structure.
Definition: SSBtimes.c:454
@ SSBPREC_LAST
end marker
Definition: SSBtimes.h:50
@ SSBPREC_RELATIVISTIC
detailed relativistic:
Definition: SSBtimes.h:47
@ SSBPREC_RELATIVISTICOPT
optimized relativistic, numerically equivalent to SSBPREC_RELATIVISTIC, but faster
Definition: SSBtimes.h:48
@ SSBPREC_NEWTONIAN
simple Newtonian:
Definition: SSBtimes.h:46
@ SSBPREC_DMOFF
switch off all demodulatoin terms
Definition: SSBtimes.h:49
COORDINATESYSTEM_EQUATORIAL
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
#define XLAL_ERROR_NULL(...)
#define xlalErrno
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_CHECK_NULL(assertion,...)
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EMAXITER
XLAL_EDOM
XLAL_EINVAL
XLAL_EFAILED
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
int XLALGPSCmp(const LIGOTimeGPS *t0, const LIGOTimeGPS *t1)
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
T
pos
n
out
precision
double alpha
size_t numDetectors
Basic input structure to LALBarycenter.c.
State-info about position, velocity and LMST of a detector together with corresponding EarthState.
REAL8 vDetector[3]
Cart.
EarthState earthState
EarthState information.
REAL8 rDetector[3]
Cartesian coords of detector position in ICRS J2000.
LIGOTimeGPS tGPS
GPS timestamps corresponding to this entry.
Timeseries of DetectorState's, representing the detector-info at different timestamps.
DetectorState * data
array of DetectorState entries
UINT4 length
total number of entries
LALDetector detector
detector-info corresponding to this timeseries
Basic output structure produced by LALBarycenter.c.
LIGOTimeGPS te
pulse emission time (TDB); also sometimes called `‘arrival time (TDB) of same wavefront at SSB’'
REAL8 tDot
d(emission time in TDB)/d(arrival time in GPS)
REAL8 location[3]
INT4 gpsNanoSeconds
Multi-IFO time-series of DetectorStates.
UINT4 length
number of detectors
DetectorStateSeries ** data
vector of pointers to DetectorStateSeries
Multi-IFO container for SSB timings.
Definition: SSBtimes.h:67
SSBtimes ** data
array of SSBtimes (pointers)
Definition: SSBtimes.h:69
UINT4 length
number of IFOs
Definition: SSBtimes.h:68
Type containing the 'Doppler-parameters' affecting the time-evolution of the phase.
REAL8 period
Binary: orbital period (sec)
LIGOTimeGPS tp
Binary: time of observed periapsis passage (in SSB)
PulsarSpins fkdot
Intrinsic spins: [Freq, f1dot, f2dot, ...
REAL8 ecc
Binary: orbital eccentricity.
REAL8 asini
Binary: projected, normalized orbital semi-major axis (s).
REAL8 argp
Binary: argument of periapsis (radians)
REAL8 * data
Simple container for two REAL8-vectors, namely the SSB-timings DeltaT_alpha and Tdot_alpha,...
Definition: SSBtimes.h:60
REAL8Vector * Tdot
dT/dt : time-derivative of SSB-time wrt local time for SFT-alpha
Definition: SSBtimes.h:63
REAL8Vector * DeltaT
Time-difference of SFT-alpha - tau0 in SSB-frame.
Definition: SSBtimes.h:62
LIGOTimeGPS refTime
reference-time 'tau0'
Definition: SSBtimes.h:61