LALSimulation  5.4.0.1-fe68b98
LALSimInspiralGeneratorConditioning.c
Go to the documentation of this file.
1 #include <math.h>
2 #include <string.h>
3 #include <lal/LALStdlib.h>
4 #include <lal/LALConstants.h>
5 #include <lal/LALDict.h>
6 #include <lal/TimeSeries.h>
7 #include <lal/FrequencySeries.h>
8 #include <lal/TimeFreqFFT.h>
9 #include <lal/BandPassTimeSeries.h>
10 #include <lal/Date.h>
11 #include <lal/Units.h>
12 #include <lal/LALSimInspiral.h>
13 #include <lal/LALSimInspiralWaveformParams.h>
16 
17 /* Helper struct storing generator and approximant */
18 struct internal_data {
19  LALSimInspiralGenerator *generator;
20  int approx; /* if this is a known named approximant */
21 };
22 
23 /* Free memory */
24 static int finalize(LALSimInspiralGenerator * myself)
25 {
26  struct internal_data *internal_data = myself->internal_data;
27  if (internal_data->generator->finalize)
31  return 0;
32 }
33 
34 /* this routine is used when reference frequency is the starting frequency */
35 static int generate_conditioned_td_waveform_from_td_fallback(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
36 {
37  struct internal_data *internal_data = myself->internal_data;
38  LALSimInspiralGenerator *internal_generator = internal_data->generator;
40 
41  if (internal_generator->generate_td_waveform(hplus, hcross, params, internal_generator) < 0)
43 
44  /* taper the waveform */
45  if (XLALSimInspiralREAL8WaveTaper((*hplus)->data, taper) == XLAL_FAILURE)
47  if (XLALSimInspiralREAL8WaveTaper((*hcross)->data, taper) == XLAL_FAILURE)
49 
50  return 0;
51 }
52 
53 /* Perform conditioning of TD waveform so that the Fourier transform afterwards is sane. Copy of code from XLALSimInspiralTDFromTD().
54  * The redshift correction has been removed, now it is up to the user to apply the proper corrections depending on the meanining of the masses and distance they use.
55  */
56 static int generate_conditioned_td_waveform_from_td(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
57 {
58  struct internal_data *internal_data = myself->internal_data;
59  LALSimInspiralGenerator *internal_generator = internal_data->generator;
61  LALDict *new_params;
62  const double extra_time_fraction = 0.1; /* fraction of waveform duration to add as extra time for tapering */
63  const double extra_cycles = 3.0; /* more extra time measured in cycles at the starting frequency */
64  double original_f_min; /* f_min might be overwritten below, so keep original value */
65  double f_min;
66  double f_ref;
67  double tchirp, tmerge, textra;
68  double fisco, fstart;
69  double m1, m2, s1z, s2z, s;
70  int retval;
71 
78 
79  /* adjust the reference frequency for certain precessing approximants:
80  * if that approximate interprets f_ref==0 to be f_min, set f_ref=f_min;
81  * otherwise do nothing */
83 
84  /* This option recovers the behaviour of SimInspiralTD in the old interface */
85  if (XLALDictLookupINT4Value(params, "condition") == 2)
86  {
87  /* apply redshift correction to dimensionful source-frame quantities */
89  if (z != 0.0) {
90  m1 *= (1.0 + z);
91  m2 *= (1.0 + z);
92  REAL8 distance = XLALSimInspiralWaveformParamsLookupDistance(params) * (1.0 + z); /* change from comoving (transverse) distance to luminosity distance */
96  }
97  /* set redshift to zero so we don't accidentally apply it again later */
98  z = 0.0;
99  if (params)
101  }
102 
103  /* if the requested low frequency is below the lowest Kerr ISCO
104  * frequency then change it to that frequency */
105  fisco = 1.0 / (pow(9.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
106  if (f_min > fisco)
107  f_min = fisco;
108 
109  /* upper bound on the chirp time starting at f_min */
110  tchirp = XLALSimInspiralChirpTimeBound(f_min, m1, m2, s1z, s2z);
111 
112  /* upper bound on the final black hole spin */
114 
115  /* upper bound on the final plunge, merger, and ringdown time */
117 
118  /* extra time to include for all waveforms to take care of situations
119  * where the frequency is close to merger (and is sweeping rapidly):
120  * this is a few cycles at the low frequency */
121  textra = extra_cycles / f_min;
122 
123  /* time domain approximant: condition by generating a waveform
124  * with a lower starting frequency and apply tapers in the
125  * region between that lower frequency and the requested
126  * frequency f_min; here compute a new lower frequency */
127  fstart = XLALSimInspiralChirpStartFrequencyBound((1.0 + extra_time_fraction) * tchirp + tmerge + textra, m1, m2);
128 
129  /* generate the waveform in the time domain starting at fstart */
130  new_params = XLALDictDuplicate(params);
133  retval = internal_generator->generate_td_waveform(hplus, hcross, new_params, internal_generator);
134  XLALDestroyDict(new_params);
135  if (retval < 0)
137 
138  /* condition the time domain waveform by tapering in the extra time
139  * at the beginning and high-pass filtering above original f_min */
140  XLALSimInspiralTDConditionStage1(*hplus, *hcross, extra_time_fraction * tchirp + textra, original_f_min);
141 
142  /* final tapering at the beginning and at the end to remove filter transients */
143 
144  /* waveform should terminate at a frequency >= Schwarzschild ISCO
145  * so taper one cycle at this frequency at the end; should not make
146  * any difference to IMR waveforms */
147  fisco = 1.0 / (pow(6.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
148  XLALSimInspiralTDConditionStage2(*hplus, *hcross, f_min, fisco);
149 
150  return 0;
151 }
152 
153 /* Conditioning of a FD waveform and transform it ot TD. Copy of code from XLALSimInspiralTDFromFD().
154  * The redshift correction has been removed, now it is up to the user to apply the proper corrections depending on the meanining of the masses and distance they use.
155  */
156 static int generate_conditioned_td_waveform_from_fd(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
157 {
158  struct internal_data *internal_data = myself->internal_data;
159  int approx = internal_data->approx;
160  COMPLEX16FrequencySeries *hptilde = NULL;
161  COMPLEX16FrequencySeries *hctilde = NULL;
162  LALDict *new_params;
163  REAL8FFTPlan *plan;
164  size_t chirplen, end, k;
165  double tshift;
166  const double extra_time_fraction = 0.1; /* fraction of waveform duration to add as extra time for tapering */
167  const double extra_cycles = 3.0; /* more extra time measured in cycles at the starting frequency */
168  double original_f_min; /* f_min might be overwritten below, so keep original value */
169  double f_min, f_max, f_ref;
170  double deltaT;
171  double tchirp, tmerge, textra;
172  double fisco, fstart;
173  double m1, m2, s1z, s2z, s;
174  int retval;
175 
179  f_max = 0.5 / deltaT;
184 
185  /* adjust the reference frequency for certain precessing approximants:
186  * if that approximate interprets f_ref==0 to be f_min, set f_ref=f_min;
187  * otherwise do nothing */
189 
190  /* This option recovers the behaviour of SimInspiralTD in the old interface */
191  if (XLALDictLookupINT4Value(params, "condition") == 2)
192  {
193  /* apply redshift correction to dimensionful source-frame quantities */
195  if (z != 0.0) {
196  m1 *= (1.0 + z);
197  m2 *= (1.0 + z);
198  REAL8 distance = XLALSimInspiralWaveformParamsLookupDistance(params) * (1.0 + z); /* change from comoving (transverse) distance to luminosity distance */
202  }
203  /* set redshift to zero so we don't accidentally apply it again later */
204  z = 0.0;
205  if (params)
207  }
208 
209  /* if the requested low frequency is below the lowest Kerr ISCO
210  * frequency then change it to that frequency */
211  fisco = 1.0 / (pow(9.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
212  if (f_min > fisco)
213  f_min = fisco;
214 
215  /* upper bound on the chirp time starting at f_min */
216  tchirp = XLALSimInspiralChirpTimeBound(f_min, m1, m2, s1z, s2z);
217 
218  /* upper bound on the final black hole spin */
220 
221  /* upper bound on the final plunge, merger, and ringdown time */
223 
224  /* extra time to include for all waveforms to take care of situations
225  * where the frequency is close to merger (and is sweeping rapidly):
226  * this is a few cycles at the low frequency */
227  textra = extra_cycles / f_min;
228 
229  /* generate the conditioned waveform in the frequency domain */
230  /* set deltaF = 0 to get a small enough resolution */
231  new_params = XLALDictDuplicate(params);
235  retval = myself->generate_fd_waveform(&hptilde, &hctilde, new_params, myself);
236  XLALDestroyDict(new_params);
237  if (retval < 0)
239 
240  /* we want to make sure that this waveform will give something
241  * sensible if it is later transformed into the time domain:
242  * to avoid the end of the waveform wrapping around to the beginning,
243  * we shift waveform backwards in time and compensate for this
244  * shift by adjusting the epoch -- note that the conditioned
245  * generate_fd_waveform method guarantees that there is the
246  * extra padding to do this */
247  tshift = round(textra / deltaT) * deltaT; /* integer number of samples */
248  for (k = 0; k < hptilde->data->length; ++k) {
249  double complex phasefac = cexp(2.0 * LAL_PI * I * k * hptilde->deltaF * tshift);
250  hptilde->data->data[k] *= phasefac;
251  hctilde->data->data[k] *= phasefac;
252  }
253  XLALGPSAdd(&hptilde->epoch, tshift);
254  XLALGPSAdd(&hctilde->epoch, tshift);
255 
256  /* transform the waveform into the time domain */
257  chirplen = 2 * (hptilde->data->length - 1);
258  *hplus = XLALCreateREAL8TimeSeries("H_PLUS", &hptilde->epoch, 0.0, deltaT, &lalStrainUnit, chirplen);
259  *hcross = XLALCreateREAL8TimeSeries("H_CROSS", &hctilde->epoch, 0.0, deltaT, &lalStrainUnit, chirplen);
260  plan = XLALCreateReverseREAL8FFTPlan(chirplen, 0);
261  if (!(*hplus) || !(*hcross) || !plan) {
268  }
269  XLALREAL8FreqTimeFFT(*hplus, hptilde, plan);
270  XLALREAL8FreqTimeFFT(*hcross, hctilde, plan);
271 
272  /* apply time domain filter at original f_min */
273  XLALHighPassREAL8TimeSeries(*hplus, original_f_min, 0.99, 8);
274  XLALHighPassREAL8TimeSeries(*hcross, original_f_min, 0.99, 8);
275 
276  /* compute how long a chirp we should have */
277  /* revised estimate of chirp length from new start frequency */
278  fstart = XLALSimInspiralChirpStartFrequencyBound((1.0 + extra_time_fraction) * tchirp, m1, m2);
279  tchirp = XLALSimInspiralChirpTimeBound(fstart, m1, m2, s1z, s2z);
280 
281  /* total expected chirp length includes merger */
282  chirplen = round((tchirp + tmerge) / deltaT);
283 
284  /* amount to snip off at the end is tshift */
285  end = (*hplus)->data->length - round(tshift / deltaT);
286 
287  /* snip off extra time at beginning and at the end */
288  XLALResizeREAL8TimeSeries(*hplus, end - chirplen, chirplen);
289  XLALResizeREAL8TimeSeries(*hcross, end - chirplen, chirplen);
290 
291  /* clean up */
295 
296  /* final tapering at the beginning and at the end to remove filter transients */
297 
298  /* waveform should terminate at a frequency >= Schwarzschild ISCO
299  * so taper one cycle at this frequency at the end; should not make
300  * any difference to IMR waveforms */
301  fisco = 1.0 / (pow(6.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
302  XLALSimInspiralTDConditionStage2(*hplus, *hcross, f_min, fisco);
303 
304  return 0;
305 }
306 
307 /* Conditioning a Fourier domain waveform to be properly transformed to the time domain. This code was taken from the original XLALSimInspiralFD() function, corresponding to the FD approximants part.
308  * The redshift correction has been removed, now it is up to the user to apply the proper corrections depending on the meanining of the masses and distance they use.
309  */
310 static int generate_conditioned_fd_waveform_from_fd(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
311 {
312  struct internal_data *internal_data = myself->internal_data;
313  LALSimInspiralGenerator *internal_generator = internal_data->generator;
314  int approx = internal_data->approx;
315  LALDict *new_params;
316  const double extra_time_fraction = 0.1; /* fraction of waveform duration to add as extra time for tapering */
317  const double extra_cycles = 3.0; /* more extra time measured in cycles at the starting frequency */
318  double chirplen, deltaT, deltaF, f_nyquist;
319  double f_min, f_max, f_ref;
320  double tchirp, tmerge, textra, tshift;
321  double fstart, fisco;
322  double m1, m2, s1z, s2z, s;
323  size_t k, k0, k1;
324  int chirplen_exp;
325  int retval;
326  size_t n;
327 
336 
337  /* adjust the reference frequency for certain precessing approximants:
338  * if that approximate interprets f_ref==0 to be f_min, set f_ref=f_min;
339  * otherwise do nothing */
341 
342  /* This option recovers the behaviour of SimInspiralFD in the old interface */
343  if (XLALDictLookupINT4Value(params, "condition") == 2)
344  {
345  /* apply redshift correction to dimensionful source-frame quantities */
347  if (z != 0.0) {
348  m1 *= (1.0 + z);
349  m2 *= (1.0 + z);
350  REAL8 distance = XLALSimInspiralWaveformParamsLookupDistance(params) * (1.0 + z); /* change from comoving (transverse) distance to luminosity distance */
354  }
355  /* set redshift to zero so we don't accidentally apply it again later */
356  z = 0.0;
357  if (params)
359  }
360 
361  /* Apply condition that f_max rounds to the next power-of-two multiple
362  * of deltaF.
363  * Round f_max / deltaF to next power of two.
364  * Set f_max to the new Nyquist frequency.
365  * The length of the chirp signal is then 2 * f_nyquist / deltaF.
366  * The time spacing is 1 / (2 * f_nyquist) */
367  f_nyquist = f_max;
368  if (deltaF != 0) {
369  n = round(f_max / deltaF);
370  if ((n & (n - 1))) { /* not a power of 2 */
371  frexp(n, &chirplen_exp);
372  f_nyquist = ldexp(1.0, chirplen_exp) * deltaF;
373  XLAL_PRINT_WARNING("f_max/deltaF = %g/%g = %g is not a power of two: changing f_max to %g", f_max, deltaF, f_max/deltaF, f_nyquist);
374  }
375  }
376  deltaT = 0.5 / f_nyquist;
377 
378  /* generate a FD waveform and condition it by applying tapers at
379  * frequencies between a frequency below the requested f_min and
380  * f_min; also wind the waveform in phase in case it would wrap-
381  * around at the merger time */
382 
383  /* if the requested low frequency is below the lowest Kerr ISCO
384  * frequency then change it to that frequency */
385  fisco = 1.0 / (pow(9.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
386  if (f_min > fisco)
387  f_min = fisco;
388 
389  /* upper bound on the chirp time starting at f_min */
390  tchirp = XLALSimInspiralChirpTimeBound(f_min, m1, m2, s1z, s2z);
391 
392  /* upper bound on the final plunge, merger, and ringdown time */
393  switch (approx) {
394  case TaylorF2:
395  case TaylorF2Ecc:
396  case TaylorF2NLTides:
397  case SpinTaylorF2:
398  case TaylorF2RedSpin:
400  case SpinTaylorT4Fourier:
401  /* inspiral-only models: no merger time */
402  tmerge = 0.0;
403  break;
404  default:
405  /* IMR model: estimate plunge and merger time */
406  /* sometimes these waveforms have phases that
407  * cause them to wrap-around an amount equal to
408  * the merger-ringodwn time, so we will undo
409  * that here */
412  break;
413  }
414 
415  /* new lower frequency to start the waveform: add some extra early
416  * part over which tapers may be applied, the extra amount being
417  * a fixed fraction of the chirp time; add some additional padding
418  * equal to a few extra cycles at the low frequency as well for
419  * safety and for other routines to use */
420  textra = extra_cycles / f_min;
421  fstart = XLALSimInspiralChirpStartFrequencyBound((1.0 + extra_time_fraction) * tchirp, m1, m2);
422 
423  /* revise (over-)estimate of chirp from new start frequency */
424  tchirp = XLALSimInspiralChirpTimeBound(fstart, m1, m2, s1z, s2z);
425 
426  /* need a long enough segment to hold a whole chirp with some padding */
427  /* length of the chirp in samples */
428  chirplen = round((tchirp + tmerge + 2.0 * textra) / deltaT);
429  /* make chirplen next power of two */
430  frexp(chirplen, &chirplen_exp);
431  chirplen = ldexp(1.0, chirplen_exp);
432  /* frequency resolution */
433  if (deltaF == 0.0)
434  deltaF = 1.0 / (chirplen * deltaT);
435  else if (deltaF > 1.0 / (chirplen * deltaT))
436  XLAL_PRINT_WARNING("Specified frequency interval of %g Hz is too large for a chirp of duration %g s", deltaF, chirplen * deltaT);
437 
438  /* generate the waveform in the frequency domain starting at fstart */
439  new_params = XLALDictDuplicate(params);
442  XLALSimInspiralWaveformParamsInsertDeltaF(new_params, deltaF);
443  retval = internal_generator->generate_fd_waveform(hplus, hcross, new_params, internal_generator);
444  XLALDestroyDict(new_params);
445  if (retval < 0)
447 
448  /* taper frequencies between fstart and f_min */
449  k0 = round(fstart / (*hplus)->deltaF);
450  k1 = round(f_min / (*hplus)->deltaF);
451  /* make sure it is zero below fstart */
452  for (k = 0; k < k0; ++k) {
453  (*hplus)->data->data[k] = 0.0;
454  (*hcross)->data->data[k] = 0.0;
455  }
456  /* taper between fstart and f_min */
457  for ( ; k < k1; ++k) {
458  double w = 0.5 - 0.5 * cos(LAL_PI * (k - k0) / (double)(k1 - k0));
459  (*hplus)->data->data[k] *= w;
460  (*hcross)->data->data[k] *= w;
461  }
462  /* make sure Nyquist frequency is zero */
463  (*hplus)->data->data[(*hplus)->data->length - 1] = 0.0;
464  (*hcross)->data->data[(*hcross)->data->length - 1] = 0.0;
465 
466  /* we want to make sure that this waveform will give something
467  * sensible if it is later transformed into the time domain:
468  * to avoid the end of the waveform wrapping around to the beginning,
469  * we shift waveform backwards in time and compensate for this
470  * shift by adjusting the epoch */
471  tshift = round(tmerge / deltaT) * deltaT; /* integer number of time samples */
472  for (k = 0; k < (*hplus)->data->length; ++k) {
473  double complex phasefac = cexp(2.0 * LAL_PI * I * k * deltaF * tshift);
474  (*hplus)->data->data[k] *= phasefac;
475  (*hcross)->data->data[k] *= phasefac;
476  }
477  XLALGPSAdd(&(*hplus)->epoch, tshift);
478  XLALGPSAdd(&(*hcross)->epoch, tshift);
479 
480  return 0;
481 }
482 
483 /* Transform a Fourier domain waveform to the time domain. This code was taken from the original XLALSimInspiralFD() function, corresponding to the TD approximants part.
484  * The redshift correction has been removed, now it is up to the user to apply the proper corrections depending on the meanining of the masses and distance they use.
485  */
486 static int generate_conditioned_fd_waveform_from_td(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
487 {
488  struct internal_data *internal_data = myself->internal_data;
489  int approx = internal_data->approx;
490  REAL8TimeSeries *hp = NULL;
491  REAL8TimeSeries *hc = NULL;
492  LALDict *new_params;
493  REAL8FFTPlan *plan;
494  double chirplen, deltaT, deltaF, f_nyquist;
495  double f_min, f_max, f_ref;
496  int chirplen_exp;
497  int retval;
498  size_t n;
499 
504 
505  /* adjust the reference frequency for certain precessing approximants:
506  * if that approximate interprets f_ref==0 to be f_min, set f_ref=f_min;
507  * otherwise do nothing */
509 
510  /* This option recovers the behaviour of SimInspiralFD in the old interface */
511  if (XLALDictLookupINT4Value(params, "condition") == 2)
512  {
513  /* apply redshift correction to dimensionful source-frame quantities */
515  if (z != 0.0) {
518  REAL8 distance = XLALSimInspiralWaveformParamsLookupDistance(params) * (1.0 + z); /* change from comoving (transverse) distance to luminosity distance */
522  }
523  /* set redshift to zero so we don't accidentally apply it again later */
524  z = 0.0;
525  if (params)
527  }
528 
529 
530  /* Apply condition that f_max rounds to the next power-of-two multiple
531  * of deltaF.
532  * Round f_max / deltaF to next power of two.
533  * Set f_max to the new Nyquist frequency.
534  * The length of the chirp signal is then 2 * f_nyquist / deltaF.
535  * The time spacing is 1 / (2 * f_nyquist) */
536  f_nyquist = f_max;
537  if (deltaF != 0) {
538  n = round(f_max / deltaF);
539  if ((n & (n - 1))) { /* not a power of 2 */
540  frexp(n, &chirplen_exp);
541  f_nyquist = ldexp(1.0, chirplen_exp) * deltaF;
542  XLAL_PRINT_WARNING("f_max/deltaF = %g/%g = %g is not a power of two: changing f_max to %g", f_max, deltaF, f_max/deltaF, f_nyquist);
543  }
544  }
545  deltaT = 0.5 / f_nyquist;
546 
547  /* generate conditioned waveform in time domain */
548  new_params = XLALDictDuplicate(params);
551  retval = myself->generate_td_waveform(&hp, &hc, new_params, myself);
552  XLALDestroyDict(new_params);
553  if (retval < 0)
555 
556  /* frequency resolution */
557  if (deltaF == 0.0) {
558  /* round length of time domain signal to next power of two */
559  chirplen = hp->data->length;
560  frexp(chirplen, &chirplen_exp);
561  chirplen = ldexp(1.0, chirplen_exp);
562  deltaF = 1.0 / (chirplen * hp->deltaT);
563  } else {
564  /* set chirp length using precomputed Nyquist */
565  chirplen = 2 * f_nyquist / deltaF;
566  if (chirplen < hp->data->length)
567  XLAL_PRINT_WARNING("Specified frequency interval of %g Hz is too large for a chirp of duration %g s with Nyquist frequency %g Hz. The inspiral will be truncated.", deltaF, hp->data->length * deltaT, f_nyquist);
568  }
569 
570  /* resize waveforms to the required length */
571  XLALResizeREAL8TimeSeries(hp, hp->data->length - (size_t) chirplen, (size_t) chirplen);
572  XLALResizeREAL8TimeSeries(hc, hc->data->length - (size_t) chirplen, (size_t) chirplen);
573 
574  /* put the waveform in the frequency domain */
575  /* (the units will correct themselves) */
576  *hplus = XLALCreateCOMPLEX16FrequencySeries("FD H_PLUS", &hp->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
577  *hcross = XLALCreateCOMPLEX16FrequencySeries("FD H_CROSS", &hc->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
578  plan = XLALCreateForwardREAL8FFTPlan((size_t) chirplen, 0);
579  XLALREAL8TimeFreqFFT(*hcross, hc, plan);
580  XLALREAL8TimeFreqFFT(*hplus, hp, plan);
581 
582  /* clean up */
586 
587  return 0;
588 }
589 
590 //static int generate_conditioned_td_modes(SphHarmTimeSeries **hlm, LALDict *params, LALSimInspiralGenerator *myself);
591 
592 //static int generate_conditioned_fd_modes(SphHarmFrequencySeries **hlm, LALDict *params, LALSimInspiralGenerator *myself);
593 
594 /* Function to assign the proper conditioning generator method for a given approximant. */
596 {
598 
603 
604  generator->internal_data = internal_data;
605  generator->finalize = finalize;
606 
607  if (internal_data->generator->generate_td_waveform) {
608  if (internal_data->approx == -1) {
609  /* Not a recognized approximant:
610  * assume we can use regular conditioning */
611  generator->generate_td_waveform = generate_conditioned_td_waveform_from_td;
612  } else {
613  /* If using approximants for which reference frequency is the starting frequency
614  * generate using XLALSimInspiralChooseTDWaveform and apply the
615  * LAL Taper 'LAL_SIM_INSPIRAL_TAPER_START' instead of
616  * XLALSimInspiralTDConditionStage1 and XLALSimInspiralTDConditionStage2
617  * as is done in XLALSimInspiralTDFromTD.
618  * This is because XLALSimInspiralTDFromTD modifies the start frequency
619  * which is not always possible with NR_hdf5 waveforms.
620  * Do the same (ChooseTDWaveform+LALTaper) if using approximants for
621  * which a starting frequency of zero is allowed, as determined from
622  * XLALSimInspiralGetAllowZeroMinFreqFromApproximant. This is because
623  * XLALSimInspiralTDFromTD does not properly handle f_min=0. For models
624  * that allow f_min=0, this (ChooseTDWaveform+LALTaper) is the behaviour
625  * independent of what f_min is passed.
626  */
627 
628  // Check whether for the given approximant reference frequency is the starting frequency
630  // Check whether for the given approximant, f_min=0 is allowed.
632 
633  if (spin_freq_flag == LAL_SIM_INSPIRAL_SPINS_CASEBYCASE || spin_freq_flag == LAL_SIM_INSPIRAL_SPINS_FLOW || allow_zero_fmin_flag == LAL_SIM_INSPIRAL_ALLOW_ZERO_FMIN)
635  else
636  generator->generate_td_waveform = generate_conditioned_td_waveform_from_td;
637  }
638  } else if (internal_data->generator->generate_fd_waveform)
639  generator->generate_td_waveform = generate_conditioned_td_waveform_from_fd;
640 
641  if (internal_data->generator->generate_fd_waveform)
642  generator->generate_fd_waveform = generate_conditioned_fd_waveform_from_fd;
643  else if (internal_data->generator->generate_td_waveform)
644  generator->generate_fd_waveform = generate_conditioned_fd_waveform_from_td;
645 
646  /* FUTURE: implement routines for conditioning modes */
647  // generator->generate_td_modes = generate_conditioned_td_modes;
648  // generator->generate_fd_modes = generate_conditioned_fd_modes;
649 
650 
651  return 0;
652 }
653 
654 /* Function to assign standard conditioning. Currently this is `generate_conditioned_td_waveform_from_td`. */
656 {
658 }
int XLALHighPassREAL8TimeSeries(REAL8TimeSeries *series, REAL8 frequency, REAL8 amplitude, INT4 filtorder)
void XLALDestroyDict(LALDict *dict)
LALDict * XLALDictDuplicate(LALDict *old)
INT4 XLALDictLookupINT4Value(LALDict *dict, const char *key)
#define LALMalloc(n)
#define LALFree(p)
REAL8 XLALSimInspiralChirpStartFrequencyBound(REAL8 tchirp, REAL8 m1, REAL8 m2)
Routine to compute an underestimate of the starting frequency for a given chirp time.
REAL8 XLALSimInspiralChirpTimeBound(REAL8 fstart, REAL8 m1, REAL8 m2, REAL8 s1, REAL8 s2)
Routine to compute an overestimate of the inspiral time from a given frequency.
int XLALSimInspiralTDConditionStage1(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, REAL8 textra, REAL8 f_min)
First stage of conditioning of time-domain waveforms.
int XLALSimInspiralGetSpinFreqFromApproximant(Approximant approx)
REAL8 XLALSimInspiralMergeTimeBound(REAL8 m1, REAL8 m2)
Routine to compute an overestimate of the merger time.
int XLALSimInspiralGetAllowZeroMinFreqFromApproximant(Approximant approx)
REAL8 XLALSimInspiralRingdownTimeBound(REAL8 M, REAL8 s)
Routine to compute an overestimate of the ringdown time.
REAL8 XLALSimInspiralFinalBlackHoleSpinBound(REAL8 S1z, REAL8 S2z)
Routine to compute an overestimate of a final black hole dimensionless spin.
int XLALSimInspiralTDConditionStage2(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, REAL8 f_min, REAL8 f_max)
Second stage of conditioning of time-domain waveforms.
static int finalize(LALSimInspiralGenerator *myself)
static int generate_conditioned_fd_waveform_from_td(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
int XLALSimInspiralGeneratorAddConditioningForApproximant(LALSimInspiralGenerator *generator, int approximant)
static int generate_conditioned_td_waveform_from_td_fallback(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
static int generate_conditioned_td_waveform_from_td(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
static int generate_conditioned_td_waveform_from_fd(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
int XLALSimInspiralGeneratorAddStandardConditioning(LALSimInspiralGenerator *generator)
static int generate_conditioned_fd_waveform_from_fd(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, LALDict *params, LALSimInspiralGenerator *myself)
REAL8 XLALSimInspiralWaveformParamsLookupMass1(LALDict *params)
Compute mass1 from any possible combination of 2 mass parameters inserted in the LALDict.
REAL8 XLALSimInspiralWaveformParamsLookupMass2(LALDict *params)
Compute mass2 from any possible combination of 2 mass parameters inserted in the LALDict.
REAL8 XLALSimInspiralWaveformParamsLookupSpin2z(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupSpin1z(LALDict *params)
int XLALSimInspiralWaveformParamsInsertMass1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertF22Ref(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupF22Start(LALDict *params)
int XLALSimInspiralWaveformParamsInsertDeltaF(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupRedshift(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupDeltaF(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupDeltaT(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupFMax(LALDict *params)
int XLALSimInspiralWaveformParamsInsertDeltaT(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupDistance(LALDict *params)
int XLALSimInspiralWaveformParamsInsertF22Start(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertRedshift(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupF22Ref(LALDict *params)
int XLALSimInspiralWaveformParamsInsertFMax(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertMass2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertDistance(LALDict *params, REAL8 value)
int s
Definition: bh_qnmode.c:137
const double w
sigmaKerr data[0]
#define FIX_REFERENCE_FREQUENCY(f_ref, f_min, approximant)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
#define LAL_MSUN_SI
#define LAL_PI
#define LAL_MTSUN_SI
double REAL8
LALSimInspiralApplyTaper
Enumeration to specify the tapering method to apply to the waveform.
SpinFreq
AllowZeroMinFreq
@ LAL_SIM_INSPIRAL_TAPER_START
Taper the start of the waveform.
@ LAL_SIM_INSPIRAL_SPINS_CASEBYCASE
These approximants have nonprecessing spins.
@ LAL_SIM_INSPIRAL_SPINS_FLOW
These approximants are parameterized by the spins at f_ref.
@ TaylorF2RedSpinTidal
TaylorF2 waveforms for non-precessing spins, defined in terms of a single (reduced-spin) parameter [A...
@ TaylorF2RedSpin
TaylorF2 waveforms for non-precessing spins, defined in terms of a single (reduced-spin) parameter [A...
@ TaylorF2NLTides
The standard stationary phase approximation including a phenomenological model of nonlinear tidal eff...
@ TaylorF2Ecc
The standard stationary phase approximation with eccentricity; Outputs a frequency-domain wave.
@ SpinTaylorT4Fourier
Frequency domain (generic spins) inspiral only waveforms based on TaylorT4, arXiv: 1408....
@ SpinTaylorF2
Spinning case F2 models (single spin only).
@ TaylorF2
The standard stationary phase approximation; Outputs a frequency-domain wave.
@ LAL_SIM_INSPIRAL_ALLOW_ZERO_FMIN
int XLALSimInspiralREAL8WaveTaper(REAL8Vector *signalvec, LALSimInspiralApplyTaper bookends)
void XLALDestroyREAL8FFTPlan(REAL8FFTPlan *plan)
REAL8FFTPlan * XLALCreateReverseREAL8FFTPlan(UINT4 size, int measurelvl)
REAL8FFTPlan * XLALCreateForwardREAL8FFTPlan(UINT4 size, int measurelvl)
int XLALREAL8TimeFreqFFT(COMPLEX16FrequencySeries *freq, const REAL8TimeSeries *tser, const REAL8FFTPlan *plan)
int XLALREAL8FreqTimeFFT(REAL8TimeSeries *tser, const COMPLEX16FrequencySeries *freq, const REAL8FFTPlan *plan)
REAL8TimeSeries * XLALResizeREAL8TimeSeries(REAL8TimeSeries *series, int first, size_t length)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
const LALUnit lalStrainUnit
const LALUnit lalDimensionlessUnit
#define XLAL_ERROR(...)
#define XLAL_PRINT_WARNING(...)
XLAL_EFUNC
XLAL_FAILURE
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
end
string approximant
COMPLEX16Sequence * data
COMPLEX16 * data
REAL8Sequence * data
LIGOTimeGPS epoch
LALSimInspiralGenerator * generator
Definition: burst.c:245
double f_min
Definition: unicorn.c:22
double deltaT
Definition: unicorn.c:24
double f_max
Definition: unicorn.c:23