00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <math.h>
00031 #include <gsl/gsl_rng.h>
00032 #include <gsl/gsl_randist.h>
00033 #include <lal/LALSimBurst.h>
00034 #include <lal/LALConstants.h>
00035 #include <lal/FrequencySeries.h>
00036 #include <lal/Sequence.h>
00037 #include <lal/TimeFreqFFT.h>
00038 #include <lal/TimeSeries.h>
00039 #include <lal/RealFFT.h>
00040 #include <lal/Units.h>
00041 #include <lal/Date.h>
00042 #include "check_series_macros.h"
00043
00044
00045 #include <lal/LALRCSID.h>
00046 NRCSID(LALSIMBURSTC, "$Id:");
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 static void gaussian_noise(REAL8TimeSeries * series, REAL8 rms, gsl_rng * rng)
00059 {
00060 unsigned i;
00061
00062 for(i = 0; i < series->data->length; i++)
00063 series->data->data[i] = gsl_ran_gaussian(rng, rms);
00064 }
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 REAL8 XLALMeasureHPeak(const REAL8TimeSeries *series)
00082 {
00083 static const char func[] = "XLALMeasureHPeak";
00084 double hpeak;
00085 unsigned i;
00086
00087 if(!series->data->length)
00088 XLAL_ERROR_REAL8(func, XLAL_EBADLEN);
00089
00090 hpeak = series->data->data[0];
00091 for(i = 1; i < series->data->length; i++)
00092 if(fabs(series->data->data[i]) > fabs(hpeak))
00093 hpeak = series->data->data[i];
00094
00095 return hpeak;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 REAL8 XLALMeasureIntS1S2DT(const REAL8TimeSeries *s1, const REAL8TimeSeries *s2)
00107 {
00108 static const char func[] = "XLALMeasureIntS1S2DT";
00109 double e = 0.0;
00110 double sum = 0.0;
00111 unsigned i;
00112
00113
00114
00115 LAL_CHECK_CONSISTENT_TIME_SERIES(s1, s2, XLAL_REAL8_FAIL_NAN);
00116
00117
00118
00119 for(i = 0; i < s1->data->length; i++) {
00120 double tmp = sum;
00121
00122
00123 double x = s1->data->data[i] * s2->data->data[i] + e;
00124
00125 sum += x;
00126
00127 e = tmp - sum;
00128
00129 e += x;
00130 }
00131
00132 return sum * s1->deltaT;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 REAL8 XLALMeasureHrss(
00148 const REAL8TimeSeries *hplus,
00149 const REAL8TimeSeries *hcross
00150 )
00151 {
00152 return sqrt(XLALMeasureIntS1S2DT(hplus, hplus) + XLALMeasureIntS1S2DT(hcross, hcross));
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 REAL8 XLALMeasureIntHDotSquaredDT(const COMPLEX16FrequencySeries *fseries)
00169 {
00170 unsigned i;
00171 double e = 0.0;
00172 double sum = 0.0;
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 for(i = 0; i < fseries->data->length; i++) {
00184 double tmp = sum;
00185
00186
00187 double x = (fseries->f0 + i * fseries->deltaF) * (fseries->f0 + i * fseries->deltaF) * (fseries->data->data[i].re * fseries->data->data[i].re + fseries->data->data[i].im * fseries->data->data[i].im) + e;
00188
00189 sum += x;
00190
00191 e = tmp - sum;
00192
00193 e += x;
00194 }
00195
00196
00197
00198 sum *= 2;
00199
00200
00201
00202 sum *= LAL_TWOPI * LAL_TWOPI * fseries->deltaF;
00203
00204 return sum;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 REAL8 XLALMeasureEoverRsquared(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross)
00219 {
00220 static const char func[] = "XLALMeasureEoverRsquared";
00221 REAL8FFTPlan *plan;
00222 COMPLEX16FrequencySeries *tilde_hplus, *tilde_hcross;
00223 double e_over_rsquared;
00224 unsigned i;
00225
00226
00227
00228 LAL_CHECK_CONSISTENT_TIME_SERIES(hplus, hcross, XLAL_REAL8_FAIL_NAN);
00229
00230
00231
00232 plan = XLALCreateForwardREAL8FFTPlan(hplus->data->length, 0);
00233 tilde_hplus = XLALCreateCOMPLEX16FrequencySeries(NULL, &hplus->epoch, 0.0, 0.0, &lalDimensionlessUnit, hplus->data->length / 2 + 1);
00234 tilde_hcross = XLALCreateCOMPLEX16FrequencySeries(NULL, &hcross->epoch, 0.0, 0.0, &lalDimensionlessUnit, hcross->data->length / 2 + 1);
00235 if(!plan || !tilde_hplus || !tilde_hcross) {
00236 XLALDestroyCOMPLEX16FrequencySeries(tilde_hplus);
00237 XLALDestroyCOMPLEX16FrequencySeries(tilde_hcross);
00238 XLALDestroyREAL8FFTPlan(plan);
00239 XLAL_ERROR(func, XLAL_EFUNC);
00240 }
00241 i = XLALREAL8TimeFreqFFT(tilde_hplus, hplus, plan);
00242 i |= XLALREAL8TimeFreqFFT(tilde_hcross, hcross, plan);
00243 XLALDestroyREAL8FFTPlan(plan);
00244 if(i) {
00245 XLALDestroyCOMPLEX16FrequencySeries(tilde_hplus);
00246 XLALDestroyCOMPLEX16FrequencySeries(tilde_hcross);
00247 XLAL_ERROR(func, XLAL_EFUNC);
00248 }
00249
00250
00251
00252 e_over_rsquared = (double) LAL_C_SI * LAL_C_SI * LAL_C_SI / (4 * LAL_G_SI) * (XLALMeasureIntHDotSquaredDT(tilde_hplus) + XLALMeasureIntHDotSquaredDT(tilde_hcross));
00253
00254
00255
00256 XLALDestroyCOMPLEX16FrequencySeries(tilde_hplus);
00257 XLALDestroyCOMPLEX16FrequencySeries(tilde_hcross);
00258
00259 return e_over_rsquared;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 int XLALGenerateBandAndTimeLimitedWhiteNoiseBurst(
00310 REAL8TimeSeries **hplus,
00311 REAL8TimeSeries **hcross,
00312 REAL8 duration,
00313 REAL8 frequency,
00314 REAL8 bandwidth,
00315 REAL8 int_hdot_squared,
00316 REAL8 delta_t,
00317 gsl_rng *rng
00318 )
00319 {
00320 static const char func[] = "XLALGenerateBandAndTimeLimitedWhiteNoiseBurst";
00321 int length;
00322 LIGOTimeGPS epoch;
00323 COMPLEX16FrequencySeries *tilde_hplus, *tilde_hcross;
00324 REAL8Window *window;
00325 REAL8FFTPlan *plan;
00326 REAL8 norm_factor;
00327
00328
00329
00330 REAL8 sigma_t_squared = duration * duration / 4.0 - 1.0 / (LAL_PI * LAL_PI * bandwidth * bandwidth);
00331 unsigned i;
00332
00333
00334
00335
00336 if(duration < 0 || bandwidth < 0 || sigma_t_squared < 0 || int_hdot_squared < 0 || delta_t <= 0) {
00337 *hplus = *hcross = NULL;
00338 XLAL_ERROR(func, XLAL_EINVAL);
00339 }
00340
00341
00342
00343
00344 length = (int) floor(30.0 * duration / delta_t / 2.0);
00345 length = 2 * length + 1;
00346
00347
00348
00349 XLALGPSSetREAL8(&epoch, -(length - 1) / 2 * delta_t);
00350
00351
00352
00353 *hplus = XLALCreateREAL8TimeSeries("BTLWNB +", &epoch, 0.0, delta_t, &lalStrainUnit, length);
00354 *hcross = XLALCreateREAL8TimeSeries("BTLWNB x", &epoch, 0.0, delta_t, &lalStrainUnit, length);
00355 if(!*hplus || !*hcross) {
00356 XLALDestroyREAL8TimeSeries(*hplus);
00357 XLALDestroyREAL8TimeSeries(*hcross);
00358 *hplus = *hcross = NULL;
00359 XLAL_ERROR(func, XLAL_EFUNC);
00360 }
00361
00362
00363
00364
00365
00366 gaussian_noise(*hplus, 1, rng);
00367 gaussian_noise(*hcross, 1, rng);
00368
00369
00370
00371
00372
00373 window = XLALCreateGaussREAL8Window((*hplus)->data->length, (((*hplus)->data->length - 1) * delta_t / 2) / sqrt(sigma_t_squared));
00374 if(!window) {
00375 XLALDestroyREAL8TimeSeries(*hplus);
00376 XLALDestroyREAL8TimeSeries(*hcross);
00377 *hplus = *hcross = NULL;
00378 XLAL_ERROR(func, XLAL_EFUNC);
00379 }
00380 for(i = 0; i < window->data->length; i++) {
00381 (*hplus)->data->data[i] *= window->data->data[i];
00382 (*hcross)->data->data[i] *= window->data->data[i];
00383 }
00384 XLALDestroyREAL8Window(window);
00385
00386
00387
00388 plan = XLALCreateForwardREAL8FFTPlan((*hplus)->data->length, 0);
00389 tilde_hplus = XLALCreateCOMPLEX16FrequencySeries(NULL, &epoch, 0.0, 0.0, &lalDimensionlessUnit, (*hplus)->data->length / 2 + 1);
00390 tilde_hcross = XLALCreateCOMPLEX16FrequencySeries(NULL, &epoch, 0.0, 0.0, &lalDimensionlessUnit, (*hcross)->data->length / 2 + 1);
00391 if(!plan || !tilde_hplus || !tilde_hcross) {
00392 XLALDestroyCOMPLEX16FrequencySeries(tilde_hplus);
00393 XLALDestroyCOMPLEX16FrequencySeries(tilde_hcross);
00394 XLALDestroyREAL8FFTPlan(plan);
00395 XLALDestroyREAL8TimeSeries(*hplus);
00396 XLALDestroyREAL8TimeSeries(*hcross);
00397 *hplus = *hcross = NULL;
00398 XLAL_ERROR(func, XLAL_EFUNC);
00399 }
00400 i = XLALREAL8TimeFreqFFT(tilde_hplus, *hplus, plan);
00401 i |= XLALREAL8TimeFreqFFT(tilde_hcross, *hcross, plan);
00402 XLALDestroyREAL8FFTPlan(plan);
00403 if(i) {
00404 XLALDestroyCOMPLEX16FrequencySeries(tilde_hplus);
00405 XLALDestroyCOMPLEX16FrequencySeries(tilde_hcross);
00406 XLALDestroyREAL8TimeSeries(*hplus);
00407 XLALDestroyREAL8TimeSeries(*hcross);
00408 *hplus = *hcross = NULL;
00409 XLAL_ERROR(func, XLAL_EFUNC);
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419 window = XLALCreateGaussREAL8Window(2 * tilde_hplus->data->length + 1, (tilde_hplus->data->length * tilde_hplus->deltaF) / (bandwidth / 2.0));
00420 if(!window) {
00421 XLALDestroyCOMPLEX16FrequencySeries(tilde_hplus);
00422 XLALDestroyCOMPLEX16FrequencySeries(tilde_hcross);
00423 XLALDestroyREAL8TimeSeries(*hplus);
00424 XLALDestroyREAL8TimeSeries(*hcross);
00425 *hplus = *hcross = NULL;
00426 XLAL_ERROR(func, XLAL_EFUNC);
00427 }
00428 XLALResizeREAL8Sequence(window->data, tilde_hplus->data->length - (unsigned) floor(frequency / tilde_hplus->deltaF + 0.5), tilde_hplus->data->length);
00429 for(i = 0; i < window->data->length; i++) {
00430 tilde_hplus->data->data[i].re *= window->data->data[i];
00431 tilde_hplus->data->data[i].im *= window->data->data[i];
00432 tilde_hcross->data->data[i].re *= window->data->data[i];
00433 tilde_hcross->data->data[i].im *= window->data->data[i];
00434 }
00435 XLALDestroyREAL8Window(window);
00436
00437
00438
00439
00440 norm_factor = sqrt(int_hdot_squared / (XLALMeasureIntHDotSquaredDT(tilde_hplus) + XLALMeasureIntHDotSquaredDT(tilde_hcross)));
00441 for(i = 0; i < tilde_hplus->data->length; i++) {
00442 tilde_hplus->data->data[i].re *= norm_factor;
00443 tilde_hplus->data->data[i].im *= norm_factor;
00444 tilde_hcross->data->data[i].re *= norm_factor;
00445 tilde_hcross->data->data[i].im *= norm_factor;
00446 }
00447
00448
00449
00450 plan = XLALCreateReverseREAL8FFTPlan((*hplus)->data->length, 0);
00451 if(!plan) {
00452 XLALDestroyCOMPLEX16FrequencySeries(tilde_hplus);
00453 XLALDestroyCOMPLEX16FrequencySeries(tilde_hcross);
00454 XLALDestroyREAL8TimeSeries(*hplus);
00455 XLALDestroyREAL8TimeSeries(*hcross);
00456 *hplus = *hcross = NULL;
00457 XLAL_ERROR(func, XLAL_EFUNC);
00458 }
00459 i = XLALREAL8FreqTimeFFT(*hplus, tilde_hplus, plan);
00460 i |= XLALREAL8FreqTimeFFT(*hcross, tilde_hcross, plan);
00461 XLALDestroyREAL8FFTPlan(plan);
00462 XLALDestroyCOMPLEX16FrequencySeries(tilde_hplus);
00463 XLALDestroyCOMPLEX16FrequencySeries(tilde_hcross);
00464 if(i) {
00465 XLALDestroyREAL8TimeSeries(*hplus);
00466 XLALDestroyREAL8TimeSeries(*hcross);
00467 *hplus = *hcross = NULL;
00468 XLAL_ERROR(func, XLAL_EFUNC);
00469 }
00470
00471
00472
00473 (*hplus)->deltaT = (*hcross)->deltaT = delta_t;
00474
00475
00476
00477
00478
00479 window = XLALCreateTukeyREAL8Window((*hplus)->data->length, 0.5);
00480 if(!window) {
00481 XLALDestroyREAL8TimeSeries(*hplus);
00482 XLALDestroyREAL8TimeSeries(*hcross);
00483 *hplus = *hcross = NULL;
00484 XLAL_ERROR(func, XLAL_EFUNC);
00485 }
00486 for(i = 0; i < window->data->length; i++) {
00487 (*hplus)->data->data[i] *= window->data->data[i];
00488 (*hcross)->data->data[i] *= window->data->data[i];
00489 }
00490 XLALDestroyREAL8Window(window);
00491
00492
00493
00494 return 0;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 int XLALSimBurstSineGaussian(
00539 REAL8TimeSeries **hplus,
00540 REAL8TimeSeries **hcross,
00541 REAL8 Q,
00542 REAL8 centre_frequency,
00543 REAL8 hrss,
00544 REAL8 eccentricity,
00545 REAL8 polarization,
00546 REAL8 delta_t
00547 )
00548 {
00549 static const char func[] = "XLALSimBurstSineGaussian";
00550 REAL8Window *window;
00551
00552 const double a = 1.0 / sqrt(2.0 - eccentricity * eccentricity);
00553 const double b = a * sqrt(1.0 - eccentricity * eccentricity);
00554
00555 const double hplusrss = hrss * (a * cos(polarization) - b * sin(polarization));
00556 const double hcrossrss = hrss * (b * cos(polarization) + a * sin(polarization));
00557
00558
00559 const double cgrss = sqrt((Q / (4.0 * centre_frequency * sqrt(LAL_PI))) * (1.0 + exp(-Q * Q)));
00560 const double sgrss = sqrt((Q / (4.0 * centre_frequency * sqrt(LAL_PI))) * (1.0 - exp(-Q * Q)));
00561
00562 const double h0plus = hplusrss / cgrss;
00563 const double h0cross = hcrossrss / sgrss;
00564 LIGOTimeGPS epoch;
00565 int length;
00566 unsigned i;
00567
00568
00569
00570
00571
00572 length = (int) floor(30.0 * Q / (LAL_TWOPI * centre_frequency) / delta_t / 2.0);
00573 length = 2 * length + 1;
00574
00575
00576
00577 XLALGPSSetREAL8(&epoch, -(length - 1) / 2 * delta_t);
00578
00579
00580
00581 *hplus = XLALCreateREAL8TimeSeries("sine-Gaussian +", &epoch, 0.0, delta_t, &lalStrainUnit, length);
00582 *hcross = XLALCreateREAL8TimeSeries("sine-Gaussian x", &epoch, 0.0, delta_t, &lalStrainUnit, length);
00583 if(!*hplus || !*hcross) {
00584 XLALDestroyREAL8TimeSeries(*hplus);
00585 XLALDestroyREAL8TimeSeries(*hcross);
00586 *hplus = *hcross = NULL;
00587 XLAL_ERROR(func, XLAL_EFUNC);
00588 }
00589
00590
00591
00592 for(i = 0; i < (*hplus)->data->length; i++) {
00593 const double t = ((int) i - (length - 1) / 2) * delta_t;
00594 const double phi = LAL_TWOPI * centre_frequency * t;
00595 const double fac = exp(-0.5 * phi * phi / (Q * Q));
00596 (*hplus)->data->data[i] = h0plus * fac * cos(phi);
00597 (*hcross)->data->data[i] = h0cross * fac * sin(phi);
00598 }
00599
00600
00601
00602
00603
00604 window = XLALCreateTukeyREAL8Window((*hplus)->data->length, 0.5);
00605 if(!window) {
00606 XLALDestroyREAL8TimeSeries(*hplus);
00607 XLALDestroyREAL8TimeSeries(*hcross);
00608 *hplus = *hcross = NULL;
00609 XLAL_ERROR(func, XLAL_EFUNC);
00610 }
00611 for(i = 0; i < window->data->length; i++) {
00612 (*hplus)->data->data[i] *= window->data->data[i];
00613 (*hcross)->data->data[i] *= window->data->data[i];
00614 }
00615 XLALDestroyREAL8Window(window);
00616
00617 return 0;
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 int XLALGenerateStringCusp(
00648 REAL8TimeSeries **hplus,
00649 REAL8TimeSeries **hcross,
00650 REAL8 amplitude,
00651 REAL8 f_high,
00652 REAL8 delta_t
00653 )
00654 {
00655 static const char func[] = "XLALGenerateStringCusp";
00656 COMPLEX16FrequencySeries *tilde_h;
00657 REAL8FFTPlan *plan;
00658 LIGOTimeGPS epoch;
00659 int length;
00660 int i;
00661
00662 const double f_low = 1.0;
00663
00664
00665
00666 if(amplitude < 0 || f_high < f_low || delta_t <= 0) {
00667 *hplus = *hcross = NULL;
00668 XLAL_ERROR(func, XLAL_EINVAL);
00669 }
00670
00671
00672
00673
00674 length = (int) (15 / f_low / delta_t / 2.0);
00675 length = 2 * length + 1;
00676
00677
00678
00679 XLALGPSSetREAL8(&epoch, -(length - 1) / 2 * delta_t);
00680
00681
00682
00683 *hplus = XLALCreateREAL8TimeSeries("string cusp +", &epoch, 0.0, delta_t, &lalStrainUnit, length);
00684 *hcross = XLALCreateREAL8TimeSeries("string cusp x", &epoch, 0.0, delta_t, &lalStrainUnit, length);
00685 tilde_h = XLALCreateCOMPLEX16FrequencySeries("string cusp +", &epoch, 0.0, 1.0 / (length * delta_t), &lalDimensionlessUnit, length / 2 + 1);
00686 plan = XLALCreateReverseREAL8FFTPlan(length, 0);
00687 if(!*hplus || !*hcross || !tilde_h || !plan) {
00688 XLALDestroyREAL8TimeSeries(*hplus);
00689 XLALDestroyREAL8TimeSeries(*hcross);
00690 XLALDestroyCOMPLEX16FrequencySeries(tilde_h);
00691 XLALDestroyREAL8FFTPlan(plan);
00692 *hplus = *hcross = NULL;
00693 XLAL_ERROR(func, XLAL_EFUNC);
00694 }
00695 XLALUnitMultiply(&tilde_h->sampleUnits, &(*hplus)->sampleUnits, &lalSecondUnit);
00696
00697
00698
00699 memset((*hcross)->data->data, 0, (*hcross)->data->length * sizeof(*(*hcross)->data->data));
00700
00701
00702
00703 for(i = 0; (unsigned) i < tilde_h->data->length; i++) {
00704 double f = tilde_h->f0 + i * tilde_h->deltaF;
00705
00706
00707
00708 tilde_h->data->data[i].re = amplitude * pow((sqrt(1 + f_low * f_low / (f * f))), -8) * pow(f, -4.0 / 3.0);
00709 if(f > f_high)
00710 tilde_h->data->data[i].re *= exp(1 - f / f_high);
00711 tilde_h->data->data[i].im = tilde_h->data->data[i].re;
00712
00713
00714
00715
00716 tilde_h->data->data[i].im *= sin(-LAL_PI * i * (length - 1) / length);
00717 tilde_h->data->data[i].re *= cos(-LAL_PI * i * (length - 1) / length);
00718 }
00719
00720
00721
00722 tilde_h->data->data[0].re = 0;
00723 tilde_h->data->data[0].im = 0;
00724
00725
00726
00727 tilde_h->data->data[tilde_h->data->length - 1].re = 0;
00728 tilde_h->data->data[tilde_h->data->length - 1].im = 0;
00729
00730
00731
00732 i = XLALREAL8FreqTimeFFT(*hplus, tilde_h, plan);
00733 XLALDestroyCOMPLEX16FrequencySeries(tilde_h);
00734 XLALDestroyREAL8FFTPlan(plan);
00735 if(i) {
00736 XLALDestroyREAL8TimeSeries(*hplus);
00737 XLALDestroyREAL8TimeSeries(*hcross);
00738 *hplus = *hcross = NULL;
00739 XLAL_ERROR(func, XLAL_EFUNC);
00740 }
00741
00742
00743
00744 (*hplus)->deltaT = (*hcross)->deltaT = delta_t;
00745
00746
00747
00748
00749 for(i = (*hplus)->data->length - 1; i >= 0; i--)
00750 (*hplus)->data->data[i] -= (*hplus)->data->data[0];
00751
00752
00753
00754 return 0;
00755 }