GenerateBurst.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007 Jolien Creighton, Patrick Brady, Saikat Ray-Majumder,
00003  * Xavier Siemens, Teviet Creighton, Kipp Cannon
00004  *
00005  * This program is free software; you can redistribute it and/or modify it
00006  * under the terms of the GNU General Public License as published by the
00007  * Free Software Foundation; either version 2 of the License, or (at your
00008  * option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License along
00016  * with with program; see the file COPYING. If not, write to the Free
00017  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018  * 02111-1307  USA
00019  */
00020 
00021 
00022 /*
00023  * ============================================================================
00024  *
00025  *                                  Preamble
00026  *
00027  * ============================================================================
00028  */
00029 
00030 
00031 #include <string.h>
00032 #include <gsl/gsl_rng.h>
00033 #include <lal/Date.h>
00034 #include <lal/GenerateBurst.h>
00035 #include <lal/LALConstants.h>
00036 #include <lal/LALDatatypes.h>
00037 #include <lal/LALDetectors.h>
00038 #include <lal/LALSimBurst.h>
00039 #include <lal/LALSimulation.h>
00040 #include <lal/LIGOMetadataTables.h>
00041 #include <lal/TimeSeries.h>
00042 
00043 
00044 NRCSID(GENERATEBURSTC, "$Id: GenerateBurst.c,v 1.52 2008/08/26 21:34:04 kipp Exp $");
00045 
00046 
00047 /*
00048  * ============================================================================
00049  *
00050  *                              sim_burst Nexus
00051  *
00052  * ============================================================================
00053  */
00054 
00055 
00056 /*
00057  * Generate the + and x time series for a single sim_burst table row.
00058  * Note:  only the row pointed to by sim_burst is processed, the linked
00059  * list is not iterated over.
00060  */
00061 
00062 
00063 int XLALGenerateSimBurst(
00064         REAL8TimeSeries **hplus,
00065         REAL8TimeSeries **hcross,
00066         const SimBurst *sim_burst,
00067         double delta_t
00068 )
00069 {
00070         static const char func[] = "XLALGenerateSimBurst";
00071 
00072         if(!strcmp(sim_burst->waveform, "BTLWNB")) {
00073                 /* E_{GW}/r^{2} is in M_{sun} / pc^{2}, so we multiply by
00074                  * (M_{sun} c^2) to convert to energy/pc^{2}, and divide by
00075                  * (distance/pc)^{2} to convert to energy/distance^{2},
00076                  * which is then multiplied by (4 G / c^3) to convert to a
00077                  * value of \int \dot{h}^{2} \diff t.  From the values of
00078                  * the LAL constants, the total factor multiplying
00079                  * egw_over_rsquared is 1.8597e-21. */
00080 
00081                 double int_hdot_squared_dt = sim_burst->egw_over_rsquared * LAL_MSUN_SI * 4 * LAL_G_SI / LAL_C_SI / LAL_PC_SI / LAL_PC_SI;
00082 
00083                 /* the waveform number is interpreted as the seed for GSL's
00084                  * Mersenne twister random number generator */
00085                 gsl_rng *rng = gsl_rng_alloc(gsl_rng_mt19937);
00086 
00087                 if(!rng)
00088                         XLAL_ERROR(func, XLAL_ENOMEM);
00089                 gsl_rng_set(rng, sim_burst->waveform_number);
00090 
00091                 XLALPrintInfo("%s(): BTLWNB: f = %.16g Hz, df = %.16g Hz, dt = %.16g s, hdot^2 = %.16g\n", func, sim_burst->frequency, sim_burst->bandwidth, sim_burst->duration, int_hdot_squared_dt);
00092                 if(XLALGenerateBandAndTimeLimitedWhiteNoiseBurst(hplus, hcross, sim_burst->duration, sim_burst->frequency, sim_burst->bandwidth, int_hdot_squared_dt, delta_t, rng)) {
00093                         gsl_rng_free(rng);
00094                         XLAL_ERROR(func, XLAL_EFUNC);
00095                 }
00096                 gsl_rng_free(rng);
00097         } else if(!strcmp(sim_burst->waveform, "StringCusp")) {
00098                 XLALPrintInfo("%s(): string cusp: A = %.16g, fhigh = %.16g Hz\n", func, sim_burst->amplitude, sim_burst->frequency);
00099                 if(XLALGenerateStringCusp(hplus, hcross, sim_burst->amplitude, sim_burst->frequency, delta_t))
00100                         XLAL_ERROR(func, XLAL_EFUNC);
00101         } else if(!strcmp(sim_burst->waveform, "SineGaussian")) {
00102                 XLALPrintInfo("%s(): sine-Gaussian: f = %.16g Hz, Q = %.16g, hrss = %.16g\n", func, sim_burst->frequency, sim_burst->q, sim_burst->hrss);
00103                 if(XLALSimBurstSineGaussian(hplus, hcross, sim_burst->q, sim_burst->frequency, sim_burst->hrss, sim_burst->pol_ellipse_e, sim_burst->pol_ellipse_angle, delta_t))
00104                         XLAL_ERROR(func, XLAL_EFUNC);
00105         } else {
00106                 /* unrecognized waveform */
00107                 XLALPrintError("%s(): error: unrecognized waveform\n", func);
00108                 XLAL_ERROR(func, XLAL_EINVAL);
00109         }
00110 
00111         /* done */
00112 
00113         return 0;
00114 }
00115 
00116 
00117 /*
00118  * Convenience wrapper to iterate over the entries in a sim_burst linked
00119  * list and inject them into a time series.  Passing NULL for the response
00120  * disables it (input time series is strain).
00121  */
00122 
00123 
00124 int XLALBurstInjectSignals(
00125         REAL8TimeSeries *series,
00126         const SimBurst *sim_burst,
00127         const COMPLEX16FrequencySeries *response
00128 )
00129 {
00130         static const char func[] = "XLALBurstInjectSignals";
00131         /* to be deduced from the time series' channel name */
00132         const LALDetector *detector;
00133         /* FIXME:  fix the const entanglement so as to get rid of this */
00134         LALDetector detector_copy;
00135         /* + and x time series for injection waveform */
00136         REAL8TimeSeries *hplus, *hcross;
00137         /* injection time series as added to detector's */
00138         REAL8TimeSeries *h;
00139         /* skip injections whose geocentre times are more than this many
00140          * seconds outside of the target time series */
00141         const double injection_window = 600.0;
00142 
00143         /* turn the first two characters of the channel name into a
00144          * detector */
00145 
00146         detector = XLALInstrumentNameToLALDetector(series->name);
00147         if(!detector)
00148                 XLAL_ERROR(func, XLAL_EFUNC);
00149         XLALPrintInfo("%s(): channel name is '%s', instrument appears to be '%s'\n", func, series->name, detector->frDetector.prefix);
00150         detector_copy = *detector;
00151 
00152         /* iterate over injections */
00153 
00154         for(; sim_burst; sim_burst = sim_burst->next) {
00155                 /* skip injections whose "times" are too far outside of the
00156                  * target time series */
00157 
00158                 if(XLALGPSDiff(&series->epoch, &sim_burst->time_geocent_gps) > injection_window || XLALGPSDiff(&sim_burst->time_geocent_gps, &series->epoch) > (series->data->length * series->deltaT + injection_window))
00159                         continue;
00160 
00161                 /* construct the h+ and hx time series for the injection
00162                  * waveform.  in the time series produced by this function,
00163                  * t = 0 is the "time" of the injection. */
00164 
00165                 if(XLALGenerateSimBurst(&hplus, &hcross, sim_burst, series->deltaT))
00166                         XLAL_ERROR(func, XLAL_EFUNC);
00167 
00168                 /* add the time of the injection at the geocentre to the
00169                  * start times of the h+ and hx time series.  after this,
00170                  * their epochs mark the start of those time series at the
00171                  * geocentre. */
00172 
00173                 XLALGPSAddGPS(&hcross->epoch, &sim_burst->time_geocent_gps);
00174                 XLALGPSAddGPS(&hplus->epoch, &sim_burst->time_geocent_gps);
00175 
00176                 /* project the wave onto the detector to produce the strain
00177                  * in the detector. */
00178 
00179                 h = XLALSimDetectorStrainREAL8TimeSeries(hplus, hcross, sim_burst->ra, sim_burst->dec, sim_burst->psi, &detector_copy);
00180                 XLALDestroyREAL8TimeSeries(hplus);
00181                 XLALDestroyREAL8TimeSeries(hcross);
00182                 if(!h)
00183                         XLAL_ERROR(func, XLAL_EFUNC);
00184 
00185                 /* add the injection strain time series to the detector
00186                  * data */
00187 
00188                 if(XLALSimAddInjectionREAL8TimeSeries(series, h, response)) {
00189                         XLALDestroyREAL8TimeSeries(h);
00190                         XLAL_ERROR(func, XLAL_EFUNC);
00191                 }
00192                 XLALDestroyREAL8TimeSeries(h);
00193         }
00194 
00195         /* done */
00196 
00197         return 0;
00198 }

Generated on Thu Aug 28 03:12:18 2008 for LAL by  doxygen 1.5.2