25#include <lal/LALMalloc.h>
26#include <lal/LALInitBarycenter.h>
27#include <lal/PulsarDataTypes.h>
28#include <lal/LALConstants.h>
29#include <lal/StringVector.h>
30#include <lal/LogPrintf.h>
32#include <lal/PtoleMetric.h>
33#include <lal/UniversalDopplerMetric.h>
34#include <lal/MetricUtils.h>
36#include <lal/GSLHelpers.h>
51#define COPY_VECT(dst,src) do { (dst)[0] = (src)[0]; (dst)[1] = (src)[1]; (dst)[2] = (src)[2]; } while(0)
53#define NORM(v) ( sqrt ( (v)[0]*(v)[0] + (v)[1]*(v)[1] + (v)[2]*(v)[2] ) )
55#define DIV_VECT(dst,src,div) do { (dst)[0] = (src)[0]/(div); (dst)[1] = (src)[1]/(div); (dst)[2] = (src)[2]/(div); } while(0)
56#define SUB_VECT(dst,src) do { (dst)[0] -= (src)[0]; (dst)[1] -= (src)[1]; (dst)[2] -= (src)[2]; } while(0)
57#define MULT_VECT(v,lam) do{ (v)[0] *= (lam); (v)[1] *= (lam); (v)[2] *= (lam); } while(0)
70typedef struct tagOldDopplerMetric {
78 gsl_matrix *m1_ij, *m2_ij, *m3_ij;
80 gsl_matrix *Fisher_ab;
135 const REAL8 tolPh = 0.01;
138 const char earthEphem[] = TEST_PKG_DATA_DIR
"earth00-40-DE405.dat.gz";
139 const char sunEphem[] = TEST_PKG_DATA_DIR
"sun00-40-DE405.dat.gz";
145 const REAL8 Tseg = 60000;
149 const REAL8 Freq = 100;
171 .fkdot = { Freq,
f1dot },
182 .multiIFO = multiIFO,
183 .multiNoiseFloor = multiNoiseFloor,
184 .signalParams = { .Amp = Amp, .Doppler = dop },
193 XLALPrintWarning(
"\n---------- ROUND 1: ephemeris-based, single-IFO phase metrics ----------\n" );
218 XLALPrintWarning(
"\n---------- ROUND 2: Ptolemaic-based, single-IFO phase metrics ----------\n" );
245 XLALPrintWarning(
"\n---------- ROUND 3: ephemeris-based, multi-IFO F-stat metrics ----------\n" );
273 XLALPrintWarning(
"\n---------- ROUND 4: compare analytic {f,f1dot,f2dot,f3dot} phase metric vs XLALComputeDopplerPhaseMetric() ----------\n" );
295 REAL8 gStart_ij[] = { 1.0 / 3, 2.0 / 3, 6.0 / 5, 32.0 / 15, \
296 2.0 / 3, 64.0 / 45, 8.0 / 3, 512.0 / 105, \
297 6.0 / 5, 8.0 / 3, 36.0 / 7, 48.0 / 5, \
298 32.0 / 15, 512.0 / 105, 48.0 / 5, 4096.0 / 225
300 const gsl_matrix_view gStart = gsl_matrix_view_array( gStart_ij, 4, 4 );
304 "RefTime=StartTime: Error(g_ij,g_analytic)= %e exceeds tolerance of %e\n", diff_2_1, tolPh );
305 XLALPrintWarning(
"Analytic (refTime=startTime): diff_2_1 = %e\n", diff_2_1 );
308 gsl_matrix_free( gN_ij );
318 REAL8 gMid_ij[] = { 1.0 / 3, 0, 1.0 / 5, 0, \
319 0, 4.0 / 45, 0, 8.0 / 105, \
320 1.0 / 5, 0, 1.0 / 7, 0, \
321 0, 8.0 / 105, 0, 16.0 / 225
323 const gsl_matrix_view gMid = gsl_matrix_view_array( gMid_ij, 4, 4 );
327 "RefTime=MidTime: Error(g_ij,g_analytic)= %e exceeds tolerance of %e\n", diff_2_1, tolPh );
328 XLALPrintWarning(
"Analytic (refTime=midTime): diff_2_1 = %e\n\n", diff_2_1 );
331 gsl_matrix_free( gN_ij );
335 XLALPrintWarning(
"\n---------- ROUND 5: ephemeris-based, single-IFO, segment-averaged phase metrics ----------\n" );
348 const UINT4 Nseg = 10;
357 segList_k.arraySize = 1;
358 segList_k.length = 1;
359 segList_k.segs = &segment_k;
363 for (
UINT4 k = 0;
k < Nseg; ++
k ) {
376 const double gFF = gsl_matrix_get( metric1_k->
g_ij, 0, 0 );
377 const double gFA = gsl_matrix_get( metric1_k->
g_ij, 0, 1 );
378 const double gFD = gsl_matrix_get( metric1_k->
g_ij, 0, 2 );
379 const double gFf = gsl_matrix_get( metric1_k->
g_ij, 0, 3 );
380 const double gAf = gsl_matrix_get( metric1_k->
g_ij, 1, 3 );
381 const double gDf = gsl_matrix_get( metric1_k->
g_ij, 2, 3 );
382 const double gff = gsl_matrix_get( metric1_k->
g_ij, 3, 3 );
383 gsl_matrix_set( metric1_k->
g_ij, 0, 3, gFf + gFF *
dt );
384 gsl_matrix_set( metric1_k->
g_ij, 3, 0, gsl_matrix_get( metric1_k->
g_ij, 0, 3 ) );
385 gsl_matrix_set( metric1_k->
g_ij, 1, 3, gAf + gFA *
dt );
386 gsl_matrix_set( metric1_k->
g_ij, 3, 1, gsl_matrix_get( metric1_k->
g_ij, 1, 3 ) );
387 gsl_matrix_set( metric1_k->
g_ij, 2, 3, gDf + gFD *
dt );
388 gsl_matrix_set( metric1_k->
g_ij, 3, 2, gsl_matrix_get( metric1_k->
g_ij, 2, 3 ) );
389 gsl_matrix_set( metric1_k->
g_ij, 3, 3, gff + 2 * gFf *
dt + gFF *
dt *
dt );
399 GPMAT( metric1->
g_ij,
"%0.4e" );
400 GPMAT( metric2P->
g_ij,
"%0.4e" );
413 XLALPrintWarning(
"\n---------- ROUND 6: directed binary orbital metric ----------\n" );
415 REAL8 Period = 68023.70496;
418 REAL8 tAsc = 897753994;
432 REAL8 TspanScoX1 = 20 * 19 * 3600;
436 REAL8 DeltaMidAsc = tMid - tAsc;
441 .segmentList = segListScoX1,
442 .multiIFO = multiIFO,
443 .multiNoiseFloor = multiNoiseFloor,
444 .signalParams = { .Amp = Amp, .Doppler = dopScoX1 },
457 XLAL_CHECK( ( g0_ij = gsl_matrix_calloc( 6, 6 ) ) != NULL,
XLAL_ENOMEM,
"Failed to gsl_calloc a 6x6 matrix\n" );
458 gsl_matrix_set( g0_ij, 0, 0, pow(
LAL_PI * TspanScoX1, 2 ) / 3.0 );
459 gsl_matrix_set( g0_ij, 1, 1, 2.0 * pow(
LAL_PI * Freq, 2 ) );
460 gsl_matrix_set( g0_ij, 2, 2, 2.0 * pow(
LAL_PI * Freq * asini *
Omega, 2 ) );
461 gsl_matrix_set( g0_ij, 3, 3, 0.5 * pow(
Omega, 4 ) * pow( Freq * asini, 2 ) * ( pow( TspanScoX1, 2 ) / 12.0 + pow( DeltaMidAsc, 2 ) ) );
462 REAL8 gPAsc =
LAL_PI * pow( Freq * asini, 2 ) * pow(
Omega, 3 ) * DeltaMidAsc;
463 gsl_matrix_set( g0_ij, 2, 3, gPAsc );
464 gsl_matrix_set( g0_ij, 3, 2, gPAsc );
465 gsl_matrix_set( g0_ij, 4, 4, 0.5 * pow(
LAL_PI * Freq * asini, 2 ) );
466 gsl_matrix_set( g0_ij, 5, 5, 0.5 * pow(
LAL_PI * Freq * asini, 2 ) );
468 GPMAT( metric_ScoX1->
g_ij,
"%0.4e" );
469 GPMAT( g0_ij,
"%0.4e" );
472 REAL8 diff, tolScoX1 = 0.05;
477 XLALPrintWarning(
"\n---------- ROUND 7: directed binary orbital metric -- comparison between 'old' and 'new' coords ----------\n" );
481 pars_ScoX1_newCoords.
coordSys = coordSysScoX1_newCoords;
488 XLAL_CHECK( ( Trnf_ij = gsl_matrix_calloc( 6, 6 ) ) != NULL,
XLAL_ENOMEM,
"Failed to gsl_calloc a 6x6 matrix\n" );
489 gsl_matrix_set( Trnf_ij, 0, 0, 1.0 );
490 gsl_matrix_set( Trnf_ij, 1, 1, 1.0 );
491 gsl_matrix_set( Trnf_ij, 2, 2, asini *
Omega );
492 gsl_matrix_set( Trnf_ij, 3, 3, -1.0 * asini * pow(
Omega, 2 ) / ( 2 *
LAL_PI ) );
493 gsl_matrix_set( Trnf_ij, 4, 4, asini );
494 gsl_matrix_set( Trnf_ij, 5, 5, asini );
499 GPMAT( metric_ScoX1->
g_ij,
"%0.4e" );
500 GPMAT( metric_ScoX1_newCoords->
g_ij,
"%0.4e" );
503 REAL8 Coord_diff, tolCoordScoX1 = 1
e-10;
508 gsl_matrix_free( g0_ij );
532 CHAR earthEphem[] = TEST_DATA_DIR
"circularEphem.dat";
533 CHAR sunEphem[] = TEST_PKG_DATA_DIR
"sun00-40-DE405.dat";
549 vect3D_t r_0 = {498.41220200278, 24.31154155846971, 0 };
550 vect3D_t r_1 = {-4.84039532365306e-06, 9.923320107134072e-05, 0 };
551 vect3D_t r_2 = { -1.975719726623028e-11, -9.63716218195963e-13, 0 };
564 for (
i = 0;
i < 3;
i++ ) {
565 diff[
i] = r_0[
i] - rOrb_n->
data[0][
i];
567 reldiff = sqrt(
NORM( diff ) /
NORM( r_0 ) );
568 XLAL_CHECK( reldiff <= reltol,
XLAL_ETOL,
"Relative error %g on 0th order r_0 exceeds tolerance of %g.\n", reldiff, reltol );
571 for (
i = 0;
i < 3;
i++ ) {
572 diff[
i] = r_1[
i] - rOrb_n->
data[1][
i];
574 reldiff = sqrt(
NORM( diff ) /
NORM( r_0 ) );
575 XLAL_CHECK( reldiff <= reltol,
XLAL_ETOL,
"Relative error %g on 1st order r_1 exceeds tolerance of %g.\n", reldiff, reltol );
578 for (
i = 0;
i < 3;
i++ ) {
579 diff[
i] = r_2[
i] - rOrb_n->
data[2][
i];
581 reldiff = sqrt(
NORM( diff ) /
NORM( r_0 ) );
582 XLAL_CHECK( reldiff <= reltol,
XLAL_ETOL,
"Relative error %g on 2n order r_2 exceeds tolerance of %g.\n", reldiff, reltol );
604 MULT_VECT( rTest_n[2], -RorbC * Om * Om );
607 MULT_VECT( rTest_n[3], -RorbC * Om * Om * Om );
610 MULT_VECT( rTest_n[4], RorbC * Om * Om * Om * Om );
616 for (
n = 0;
n <= maxorder;
n ++ ) {
617 for (
i = 0;
i < 3;
i++ ) {
618 diff[
i] = rTest_n[
n][
i] - rOrb_n->
data[
n][
i];
620 reldiff = sqrt(
NORM( diff ) /
NORM( rTest_n[
n] ) );
621 XLALPrintInfo(
"order %d: relative difference = %g\n",
n, reldiff );
623 "Relative error %g on r_%d exceeds tolerance of %g.\n"
624 "rd[%d] = {%g, %g, %g}, rTest[%d] = {%g, %g, %g}\n",
627 n, rTest_n[
n][0], rTest_n[
n][1], rTest_n[
n][2] );
void LALCheckMemoryLeaks(void)
const double scale
multiplicative scaling factor of the coordinate
#define DIV_VECT(dst, src, div)
#define COPY_VECT(dst, src)
OldDopplerMetric * XLALOldDopplerFstatMetric(const OldMetricType_t metricType, const DopplerMetricParams *metricParams, const EphemerisData *edat)
The only purpose of this function is to serve as a backwards-comparison check for XLALDopplerFstatMet...
int XLALScaleOldDopplerMetric(OldDopplerMetric *m, REAL8 scale)
Scale all (existing) matrices, error-estimates and 'rho2' by 'scale'.
static int test_XLALComputeDopplerMetrics(void)
Unit test for metric functions XLALComputeDopplerPhaseMetric() and XLALComputeDopplerFstatMetric()
static int test_XLALComputeOrbitalDerivatives(void)
Unit test function for XLALComputeOrbitalDerivatives()
int main(void)
MAIN function: calls a number of unit-tests.
int XLALAddOldDopplerMetric(OldDopplerMetric **metric1, const OldDopplerMetric *metric2)
Add 'metric2' to 'metric1', by adding the matrixes and 'rho2', and adding error-estimates in quadratu...
void XLALDestroyOldDopplerMetric(OldDopplerMetric *metric)
Free a OldDopplerMetric structure.
#define MULT_VECT(v, lam)
@ OLDMETRIC_TYPE_PHASE
compute phase metric only
@ OLDMETRIC_TYPE_FSTAT
compute full F-metric only
@ OLDMETRIC_TYPE_ALL
compute both F-metric and phase-metric
int XLALParseMultiLALDetector(MultiLALDetector *detInfo, const LALStringVector *detNames)
Parse string-vectors (typically input by user) of N detector-names for detectors ,...
int XLALParseMultiNoiseFloor(MultiNoiseFloor *multiNoiseFloor, const LALStringVector *sqrtSX, UINT4 numDetectors)
Parse string-vectors (typically input by user) of N detector noise-floors for detectors ,...
EphemerisData * XLALInitBarycenter(const CHAR *earthEphemerisFile, const CHAR *sunEphemerisFile)
XLAL interface to reading ephemeris files 'earth' and 'sun', and return ephemeris-data in old backwar...
void XLALDestroyEphemerisData(EphemerisData *edat)
Destructor for EphemerisData struct, NULL robust.
#define XLAL_INIT_DECL(var,...)
REAL8 XLALCompareMetrics(const gsl_matrix *g1_ij, const gsl_matrix *g2_ij)
Flexible comparison function between two metrics and .
int XLALInverseTransformMetric(gsl_matrix **p_gpr_ij, const gsl_matrix *transform, const gsl_matrix *g_ij)
Apply the inverse of a transform to a metric such that , or equivalently .
int XLALNaturalizeMetric(gsl_matrix **p_gpr_ij, gsl_matrix **p_transform, const gsl_matrix *g_ij, const DopplerMetricParams *metricParams)
Return a metric in naturalized coordinates.
int XLALSegListInit(LALSegList *seglist)
int XLALSegListClear(LALSegList *seglist)
int XLALSegListInitSimpleSegments(LALSegList *seglist, LIGOTimeGPS startTime, UINT4 Nseg, REAL8 Tseg)
void XLALDestroyStringVector(LALStringVector *vect)
LALStringVector * XLALCreateStringVector(const CHAR *str1,...)
REAL8 vect3D_t[3]
3D vector
void XLALDestroyDopplerFstatMetric(DopplerFstatMetric *metric)
Free a DopplerFstatMetric structure.
void XLALDestroyDopplerPhaseMetric(DopplerPhaseMetric *metric)
Free a DopplerPhaseMetric structure.
vect3Dlist_t * XLALComputeOrbitalDerivatives(UINT4 maxorder, const LIGOTimeGPS *tGPS, const EphemerisData *edat)
Compute time-derivatives up to 'maxorder' of the Earths' orbital position vector .
DopplerFstatMetric * XLALComputeDopplerFstatMetric(const DopplerMetricParams *metricParams, const EphemerisData *edat)
Calculate the general (single-segment coherent, or multi-segment semi-coherent) full (multi-IFO) Fsta...
void XLALDestroyVect3Dlist(vect3Dlist_t *list)
DopplerPhaseMetric * XLALComputeDopplerPhaseMetric(const DopplerMetricParams *metricParams, const EphemerisData *edat)
Calculate an approximate "phase-metric" with the specified parameters.
@ DOPPLERCOORD_ETA
Lagrange parameter 'eta = ecc * sin(argp) of binary orbit (ELL1 model) [Units: none].
@ DOPPLERCOORD_KAPPA
Lagrange parameter 'kappa = ecc * cos(argp)', ('ecc' = eccentricity, 'argp' = argument of periapse) o...
@ DOPPLERCOORD_TASC
Time of ascension (neutron star crosses line of nodes moving away from observer) for binary orbit (EL...
@ DOPPLERCOORD_ETAP
Rescaled (by asini) differential-coordinate 'detap = asini * deta' [Units: light seconds].
@ DOPPLERCOORD_KAPPAP
Rescaled (by asini) differential-coordinate 'dkappap = asini * dkappa' [Units: light seconds].
@ DOPPLERCOORD_ASINI
Projected semimajor axis of binary orbit in small-eccentricy limit (ELL1 model) [Units: light seconds...
@ DOPPLERCOORD_F2DOT
Second spindown [Units: Hz/s^2].
@ DOPPLERCOORD_DASC
Distance traversed on the arc of binary orbit (ELL1 model) 'dasc = 2 * pi * (ap/porb) * tasc' [Units:...
@ DOPPLERCOORD_DELTA
Declination [Units: radians].
@ DOPPLERCOORD_F1DOT
First spindown [Units: Hz/s].
@ DOPPLERCOORD_ALPHA
Right ascension [Units: radians].
@ DOPPLERCOORD_VP
Rescaled (by asini) differential-coordinate 'dvp = asini * dOMEGA', ('OMEGA' = 2 * pi/'porb') of bina...
@ DOPPLERCOORD_PORB
Period of binary orbit (ELL1 model) [Units: s].
@ DOPPLERCOORD_F3DOT
Third spindown [Units: Hz/s^3].
@ DOPPLERCOORD_FREQ
Frequency [Units: Hz].
@ DETMOTION_SPIN
Full spin motion.
@ DETMOTION_PTOLEORBIT
Ptolemaic (circular) orbital motion.
@ DETMOTION_ORBIT
Ephemeris-based orbital motion.
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_CHECK(assertion,...)
int int XLALPrintWarning(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
LIGOTimeGPS * XLALGPSSetREAL8(LIGOTimeGPS *epoch, REAL8 t)
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
def Omega(v, m1, m2, S1, S2, Ln)
type describing a Doppler coordinate system: lists the number of dimensions and the symbolic names of...
Struct to hold the output of XLALComputeDopplerFstatMetric(), including meta-info on the number of di...
gsl_matrix * gFav_ij
'average' Fstat-metric
gsl_matrix * gF_ij
full F-statistic metric gF_ij, including antenna-pattern effects (see )
meta-info specifying a Doppler-metric
MultiLALDetector multiIFO
detectors to compute metric for
DetectorMotionType detMotionType
the type of detector-motion assumed: full spin+orbit, pure orbital, Ptole, ...
BOOLEAN approxPhase
use an approximate phase-model, neglecting Roemer delay in spindown coordinates
PulsarParams signalParams
parameter-space point to compute metric for (doppler + amplitudes)
LALSegList segmentList
segment list: Nseg segments of the form (startGPS endGPS numSFTs)
MultiNoiseFloor multiNoiseFloor
and associated per-detector noise-floors to be used for weighting.
DopplerCoordinateSystem coordSys
number of dimensions and coordinate-IDs of Doppler-metric
Struct to hold the output of XLALComputeDopplerPhaseMetric(), including meta-info on the number of di...
gsl_matrix * g_ij
symmetric matrix holding the phase-metric, averaged over segments
This structure contains all information about the center-of-mass positions of the Earth and Sun,...
array of detectors definitions 'LALDetector'
UINT4 length
number of detectors
array of detector-specific 'noise floors' (ie PSD values), assumed constant over the frequency-band o...
UINT4 length
number of detectors
gsl_matrix * g_ij
symmetric matrix holding the phase-metric, averaged over segments
gsl_matrix * gFav_ij
'average' Fstat-metric
gsl_matrix * gF_ij
full F-statistic metric gF_ij, including antenna-pattern effects (see )
Type containing the JKS 'amplitude parameters' {h0, cosi, phi0, psi}.
Type containing the 'Doppler-parameters' affecting the time-evolution of the phase.
LIGOTimeGPS refTime
Reference time of pulsar parameters (in SSB!)
PulsarDopplerParams Doppler
'Phase-evolution parameters': {skypos, fkdot, orbital params }
variable-length list of 3D vectors
vect3D_t * data
array of 3D vectors