Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALSimulationTest.c
Go to the documentation of this file.
1#include <math.h>
2#include <stdio.h>
3
4#include <lal/Date.h>
5#include <lal/LALDatatypes.h>
6#include <lal/LALDetectors.h>
7#include <lal/DetResponse.h>
8#include <lal/TimeSeries.h>
9#include <lal/Units.h>
10#include <lal/TimeDelay.h>
11#include <lal/LALSimulation.h>
12#include <gsl/gsl_sf_trig.h>
13
15
16static REAL8TimeSeries *new_series(double deltaT, unsigned length, double fill)
17{
19 unsigned i;
20 for(i = 0 ; i < new->data->length; i++)
21 new->data->data[i] = fill;
22 return new;
23}
24
26{
27 return XLALCutREAL8TimeSeries(src, 0, src->data->length);
28}
29
30static void add_circular_polarized_sine(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, LIGOTimeGPS epoch, double ampl, double freq)
31{
32 double t0 = XLALGPSDiff(&hplus->epoch, &epoch);
33 unsigned i;
34
35 for(i = 0; i < hplus->data->length; i++) {
36 double t = t0 + i * hplus->deltaT;
37 hplus->data->data[i] = ampl * cos(LAL_TWOPI * freq * t);
38 hcross->data->data[i] = ampl * sin(LAL_TWOPI * freq * t);
39 }
40}
41
42static double modelsignal(LIGOTimeGPS t, LIGOTimeGPS epoch, double ampl, double freq, double armlen, double xcos, double ycos, double fxplus, double fxcross, double fyplus, double fycross)
43{
44 double t0 = XLALGPSDiff(&t, &epoch);
45
46 double Txplus = armlen * (1. + xcos) / LAL_C_SI;
47 double Txminus = armlen * (1. - xcos) / LAL_C_SI;
48 double Typlus = armlen * (1. + ycos) / LAL_C_SI;
49 double Tyminus = armlen * (1. - ycos) / LAL_C_SI;
50
51 double t1x = t0 - Txplus / 2.0;
52 double t2x = t0 + Txminus / 2.0;
53 double signalxplus = ampl * fxplus * (gsl_sf_sinc(freq * Txminus) * cos(LAL_TWOPI * freq * t1x) + gsl_sf_sinc(freq * Txplus) * cos(LAL_TWOPI * freq * t2x)) / 2.0;
54 double signalxcross = ampl * fxcross * (gsl_sf_sinc(freq * Txminus) * sin(LAL_TWOPI * freq * t1x) + gsl_sf_sinc(freq * Txplus) * sin(LAL_TWOPI * freq * t2x)) / 2.0;
55
56 double t1y = t0 - Typlus / 2.0;
57 double t2y = t0 + Tyminus / 2.0;
58 double signalyplus = ampl * fyplus * (gsl_sf_sinc(freq * Tyminus) * cos(LAL_TWOPI * freq * t1y) + gsl_sf_sinc(freq * Typlus) * cos(LAL_TWOPI * freq * t2y)) / 2.0;
59 double signalycross = ampl * fycross * (gsl_sf_sinc(freq * Tyminus) * sin(LAL_TWOPI * freq * t1y) + gsl_sf_sinc(freq * Typlus) * sin(LAL_TWOPI * freq * t2y)) / 2.0;
60
61 return signalxplus + signalxcross + signalyplus + signalycross;
62}
63
64/* add the signal the detector observes when hplus = ampl * cos(2 * pi * f * (t - epoch)) and hcross = ampl * sin(2 * pi * f * (t - epoch)) */
65static void compute_answer(REAL8TimeSeries *mdl, LIGOTimeGPS epoch, double ampl, double freq, REAL8 right_ascension, REAL8 declination, REAL8 psi, const LALDetector *detector)
66{
67 double armlen = XLAL_REAL8_FAIL_NAN;
68 double xcos = XLAL_REAL8_FAIL_NAN;
69 double ycos = XLAL_REAL8_FAIL_NAN;
70 double fxplus = XLAL_REAL8_FAIL_NAN;
71 double fxcross = XLAL_REAL8_FAIL_NAN;
72 double fyplus = XLAL_REAL8_FAIL_NAN;
73 double fycross = XLAL_REAL8_FAIL_NAN;
74 unsigned i;
75
76 for(i = 0; i < mdl->data->length; i++) {
77 LIGOTimeGPS t = mdl->epoch;
78 XLALGPSAdd(&t, i * mdl->deltaT);
79
80 XLALComputeDetAMResponseParts(&armlen, &xcos, &ycos, &fxplus, &fyplus, &fxcross, &fycross, detector, right_ascension, declination, psi, XLALGreenwichMeanSiderealTime(&t));
81
82 XLALGPSAdd(&t, -XLALTimeDelayFromEarthCenter(detector->location, right_ascension, declination, &t));
83
84 mdl->data->data[i] = modelsignal(t, epoch, ampl, freq, armlen, xcos, ycos, fxplus, fxcross, fyplus, fycross);
85 }
86}
87
89{
90 REAL8TimeSeries *result = copy_series(s1);
91 unsigned i;
92
93 for(i = 0; i < s1->data->length; i++)
94 result->data->data[i] -= s0->data->data[i];
95
96 return result;
97}
98
99
100static double RMS(const REAL8TimeSeries *s)
101{
102 double rms = 0.;
103 unsigned i;
104
105 for(i = 0; i < s->data->length; i++)
106 rms += s->data->data[i] * s->data->data[i];
107
108 return sqrt(rms / s->data->length);
109}
110
111
112static void minmax(const REAL8TimeSeries *s, double *min, double *max)
113{
114 unsigned i;
115
116 *min = *max = s->data->data[0];
117 for(i = 1; i < s->data->length; i++) {
118 if(s->data->data[i] < *min)
119 *min = s->data->data[i];
120 if(s->data->data[i] > *max)
121 *max = s->data->data[i];
122 }
123}
124
125
126static void check_result(const REAL8TimeSeries *model, const REAL8TimeSeries *result, double rms_bound, double residual_min, double residual_max)
127{
128 REAL8TimeSeries *err = error(model, result);
129 double rms, min, max;
130
131 rms = RMS(err);
132 minmax(err, &min, &max);
133
134 fprintf(stderr, "error vector: RMS=%g, min=%g, max=%g\n", rms, min, max);
136 if(rms > rms_bound || min < residual_min || max > residual_max) {
137 fprintf(stderr, "error vector larger than allowed\n");
138 exit(1);
139 }
140}
141
142
143int main(void)
144{
145 REAL8TimeSeries *hplus, *hcross, *dst, *short_dst, *mdl;
147 double f, ampl, dt;
148 unsigned length_origin, start_mdl, length_mdl;
149 REAL8 right_ascension = 0.0, declination = 0.0, psi = 0.0;
150
151 ampl = 1.0;
152 f = 100.0;
153 dt = 1.0 / (f * 4.0);
154 length_origin = 1024 * 3;
155 start_mdl = 1024;
156 length_mdl = 1024;
157
158 hplus = new_series(dt, length_origin, 0.0);
159 hcross = copy_series(hplus);
160
161 add_circular_polarized_sine(hplus, hcross, hplus->epoch, ampl, f);
162 dst = XLALSimDetectorStrainREAL8TimeSeries(hplus, hcross, right_ascension, declination, psi, &detector);
163 short_dst = XLALCutREAL8TimeSeries(dst, start_mdl, length_mdl);
164
165 fprintf(stderr, "injecting unit amplitude %g Hz circular polarized monochromatic GWs sampled at %g Hz into LHO data\n", f, 1/ dt);
166
167 mdl = copy_series(short_dst);
168 compute_answer(mdl, hplus->epoch, ampl, f, right_ascension, declination, psi, &detector);
169
170 check_result(mdl, short_dst, 0.0012, -0.0016, 0.0016);
171
177
179 f = 10000.0;
180 dt = 1.0 / (f * 4.0);
181 length_origin = 1024 * 3;
182 start_mdl = 1024;
183 length_mdl = 1024;
184
185 hplus = new_series(dt, length_origin, 0.0);
186 hcross = copy_series(hplus);
187
188 add_circular_polarized_sine(hplus, hcross, hplus->epoch, ampl, f);
189 dst = XLALSimDetectorStrainREAL8TimeSeries(hplus, hcross, right_ascension, declination, psi, &detector);
190 short_dst = XLALCutREAL8TimeSeries(dst, start_mdl, length_mdl);
191
192 fprintf(stderr, "injecting unit amplitude %g Hz circular polarized monochromatic GWs sampled at %g Hz into ET data\n", f, 1/ dt);
193
194 mdl = copy_series(short_dst);
195 compute_answer(mdl, hplus->epoch, ampl, f, right_ascension, declination, psi, &detector);
196
197 check_result(mdl, short_dst, 0.0004, -0.0006, 0.0006);
198
204
205 exit(0);
206}
static void minmax(const REAL8TimeSeries *s, double *min, double *max)
static REAL8TimeSeries * error(const REAL8TimeSeries *s1, const REAL8TimeSeries *s0)
static void compute_answer(REAL8TimeSeries *mdl, LIGOTimeGPS epoch, double ampl, double freq, REAL8 right_ascension, REAL8 declination, REAL8 psi, const LALDetector *detector)
static void add_circular_polarized_sine(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, LIGOTimeGPS epoch, double ampl, double freq)
static REAL8TimeSeries * new_series(double deltaT, unsigned length, double fill)
static void check_result(const REAL8TimeSeries *model, const REAL8TimeSeries *result, double rms_bound, double residual_min, double residual_max)
int main(void)
static LIGOTimeGPS gps_zero
static REAL8TimeSeries * copy_series(const REAL8TimeSeries *src)
static double RMS(const REAL8TimeSeries *s)
static double modelsignal(LIGOTimeGPS t, LIGOTimeGPS epoch, double ampl, double freq, double armlen, double xcos, double ycos, double fxplus, double fxcross, double fyplus, double fycross)
#define fprintf
int s
Definition: bh_qnmode.c:137
double dt
Definition: bh_ringdown.c:113
double i
Definition: bh_ringdown.c:118
const char * detector
const LALDetector lalCachedDetectors[LAL_NUM_DETECTORS]
void XLALComputeDetAMResponseParts(double *armlen, double *xcos, double *ycos, double *fxplus, double *fyplus, double *fxcross, double *fycross, const LALDetector *detector, double ra, double dec, double psi, double gmst)
#define LAL_C_SI
#define LAL_TWOPI
#define LIGOTIMEGPSZERO
double REAL8
LAL_ET1_DETECTOR
LAL_LHO_4K_DETECTOR
REAL8TimeSeries * XLALSimDetectorStrainREAL8TimeSeries(const REAL8TimeSeries *hplus, const REAL8TimeSeries *hcross, REAL8 right_ascension, REAL8 declination, REAL8 psi, const LALDetector *detector)
Transforms the waveform polarizations into a detector strain.
REAL8 XLALTimeDelayFromEarthCenter(const double detector_earthfixed_xyz_metres[3], double source_right_ascension_radians, double source_declination_radians, const LIGOTimeGPS *gpstime)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
REAL8TimeSeries * XLALCutREAL8TimeSeries(const REAL8TimeSeries *series, size_t first, size_t length)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
const LALUnit lalDimensionlessUnit
#define XLAL_REAL8_FAIL_NAN
REAL8 XLALGreenwichMeanSiderealTime(const LIGOTimeGPS *gpstime)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
dst
src
REAL8Sequence * data
LIGOTimeGPS epoch
REAL8 * data
LIGOTimeGPS epoch
Definition: unicorn.c:20
double deltaT
Definition: unicorn.c:24