LALApps 10.1.0.1-eeff03c
GenerateRing.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Duncan Brown
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful,
10* but WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12* GNU General Public License for more details.
13*
14* You should have received a copy of the GNU General Public License
15* along with with program; see the file COPYING. If not, write to the
16* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17* MA 02110-1301 USA
18*/
19
20#include <math.h>
21
22#include <lal/LALStdio.h>
23#include <lal/LALStdlib.h>
24#include <lal/LALConstants.h>
25#include <lal/Units.h>
26#include <lal/Date.h>
27#include <lal/AVFactories.h>
28#include <lal/SeqFactories.h>
29#include <lal/VectorOps.h>
30#include <Inject.h>
31#include <lal/SimulateCoherentGW.h>
32#include <GenerateRing.h>
33#include <lal/LIGOMetadataTables.h>
34#include <lal/RealFFT.h>
35#include <lal/TimeFreqFFT.h>
36
37#ifdef __GNUC__
38#define UNUSED __attribute__ ((unused))
39#else
40#define UNUSED
41#endif
42
43void
45 LALStatus *stat,
47 REAL4TimeSeries UNUSED *series,
48 SimRingdownTable *simRingdown,
50 )
51
52{
53 UINT4 i; /* number of and index over samples */
54 REAL8 t, dt; /* time, interval */
55 REAL8 gtime ; /* central time, decay time */
56 REAL8 f0, quality; /* frequency and quality factor */
57 REAL8 twopif0; /* 2*pi*f0 */
58 REAL4 h0; /* peak strain for ringdown */
59 REAL4 *fData; /* pointer to frequency data */
60 REAL8 *phiData; /* pointer to phase data */
61 REAL8 init_phase; /*initial phase of injection */
62 REAL4 *aData; /* pointer to frequency data */
63 UINT4 nPointInj; /* number of data points in a block */
64#if 0
65 UINT4 n;
66 REAL8 t0;
67 REAL4TimeSeries signalvec; /* start time of block that injection is injected into */
68 LALTimeInterval interval;
69 INT8 geoc_tns; /* geocentric_start_time of the injection in ns */
70 INT8 block_tns; /* start time of block in ns */
71 REAL8 deltaTns;
72 INT8 inj_diff; /* time between start of segment and injection */
73 LALTimeInterval dummyInterval;
74#endif
75
78
79 /* Make sure parameter and output structures exist. */
81 GENERATERINGH_MSGENUL );
83 GENERATERINGH_MSGENUL );
84
85 /* Make sure output fields don't exist. */
87 GENERATERINGH_MSGEOUT );
89 GENERATERINGH_MSGEOUT );
91 GENERATERINGH_MSGEOUT );
92 ASSERT( !( output->shift ), stat, GENERATERINGH_EOUT,
93 GENERATERINGH_MSGEOUT );
94
95
96 /* Set up some other constants, to avoid repeated dereferencing. */
97 dt = params->deltaT;
98/* N_point = 2 * floor(0.5+ 1/ dt); */
99
100 nPointInj = 163840;
101
102 /* Generic ring parameters */
103 h0 = simRingdown->amplitude;
104 quality = (REAL8)simRingdown->quality;
105 f0 = (REAL8)simRingdown->frequency;
106 twopif0 = f0*LAL_TWOPI;
107 init_phase = simRingdown->phase;
108
109
110 if ( ( output->a = (REAL4TimeVectorSeries *)
111 LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) {
112 ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
113 }
114 memset( output->a, 0, sizeof(REAL4TimeVectorSeries) );
115 if ( ( output->f = (REAL4TimeSeries *)
116 LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) {
117 LALFree( output->a ); output->a = NULL;
118 ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
119 }
120 memset( output->f, 0, sizeof(REAL4TimeSeries) );
121 if ( ( output->phi = (REAL8TimeSeries *)
122 LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) {
123 LALFree( output->a ); output->a = NULL;
124 LALFree( output->f ); output->f = NULL;
125 ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
126 }
127 memset( output->phi, 0, sizeof(REAL8TimeSeries) );
128
129 /* Set output structure metadata fields. */
130 output->position.longitude = simRingdown->longitude;
131 output->position.latitude = simRingdown->latitude;
132 output->position.system = params->system;
133 output->psi = simRingdown->polarization;
134 /* set epoch of output time series to that of the block */
135 output->a->epoch = output->f->epoch = output->phi->epoch = simRingdown->geocent_start_time;
136 output->a->deltaT = params->deltaT;
137 output->f->deltaT = output->phi->deltaT = params->deltaT;
138 output->a->sampleUnits = lalStrainUnit;
139 output->f->sampleUnits = lalHertzUnit;
140 output->phi->sampleUnits = lalDimensionlessUnit;
141 snprintf( output->a->name, LALNameLength, "Ring amplitudes" );
142 snprintf( output->f->name, LALNameLength, "Ring frequency" );
143 snprintf( output->phi->name, LALNameLength, "Ring phase" );
144
145
146 /* Allocate phase and frequency arrays. */
147 LALSCreateVector( stat->statusPtr, &( output->f->data ), nPointInj );
148 BEGINFAIL( stat ) {
149 LALFree( output->a ); output->a = NULL;
150 LALFree( output->f ); output->f = NULL;
151 LALFree( output->phi ); output->phi = NULL;
152 } ENDFAIL( stat );
153
154 LALDCreateVector( stat->statusPtr, &( output->phi->data ), nPointInj );
155 BEGINFAIL( stat ) {
156 TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
157 stat );
158 LALFree( output->a ); output->a = NULL;
159 LALFree( output->f ); output->f = NULL;
160 LALFree( output->phi ); output->phi = NULL;
161 } ENDFAIL( stat );
162
163
164 /* Allocate amplitude array. */
165 {
166 CreateVectorSequenceIn in; /* input to create output->a */
167 in.length = nPointInj;
168 in.vectorLength = 2;
169 LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in );
170 BEGINFAIL( stat ) {
171 TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
172 stat );
173 TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ),
174 stat );
175 LALFree( output->a ); output->a = NULL;
176 LALFree( output->f ); output->f = NULL;
177 LALFree( output->phi ); output->phi = NULL;
178 } ENDFAIL( stat );
179 }
180
181
182 /* set arrays to zero */
183 memset( output->f->data->data, 0, sizeof( REAL4 ) * output->f->data->length );
184 memset( output->phi->data->data, 0, sizeof( REAL8 ) * output->phi->data->length );
185 memset( output->a->data->data, 0, sizeof( REAL4 ) *
186 output->a->data->length * output->a->data->vectorLength );
187
188/* Fill frequency and phase arrays starting at time of injection NOT start */
189 fData = output->f->data->data;
190 phiData = output->phi->data->data;
191 aData = output->a->data->data;
192
193 if ( !( strcmp( simRingdown->waveform, "Ringdown" ) ) )
194 {
195 for ( i = 0; i < nPointInj; i++ )
196 {
197 t = i * dt;
198 gtime = twopif0 / 2 / quality * t ;
199 *(fData++) = f0;
200 *(phiData++) = twopif0 * t+init_phase;
201 *(aData++) = h0 * ( 1.0 + pow( cos( simRingdown->inclination ), 2 ) ) *
202 exp( - gtime );
203 *(aData++) = h0* 2.0 * cos( simRingdown->inclination ) * exp( - gtime );
204 }
205 }
206 else
207 {
208 ABORT( stat, GENERATERINGH_ETYP, GENERATERINGH_MSGETYP );
209 }
210
211
212/* Set output field and return. */
214 RETURN( stat );
215}
216
217
218void
220 LALStatus *stat,
224 INT4 calType
225 )
226
227{
228 UINT4 k;
229 INT4 injStartTime;
230 INT4 injStopTime;
232 COMPLEX8Vector *unity = NULL;
234 RingParamStruc ringParam;
235 REAL4TimeSeries signalvec;
236 SimRingdownTable *simRingdown=NULL;
237 LALDetector *tmpDetector=NULL /*,*nullDetector=NULL*/;
238 COMPLEX8FrequencySeries *transfer = NULL;
239
242
243 /* set up start and end of injection zone TODO: fix this hardwired 10 */
244 injStartTime = series->epoch.gpsSeconds - 10;
245 injStopTime = series->epoch.gpsSeconds + 10 + (INT4)(series->data->length
246 * series->deltaT);
247
248 /*
249 *compute the transfer function
250 */
251
252 /* allocate memory and copy the parameters describing the freq series */
253 memset( &detector, 0, sizeof( DetectorResponse ) );
254 transfer = (COMPLEX8FrequencySeries *)
256 if ( ! transfer )
257 {
258 ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
259 }
260 memcpy( &(transfer->epoch), &(resp->epoch),
261 sizeof(LIGOTimeGPS) );
262 transfer->f0 = resp->f0;
263 transfer->deltaF = resp->deltaF;
264
265 tmpDetector = detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) );
266 /* set the detector site */
267 switch ( series->name[0] )
268 {
269 case 'H':
271 LALWarning( stat, "computing waveform for Hanford." );
272 break;
273 case 'L':
275 LALWarning( stat, "computing waveform for Livingston." );
276 break;
277 default:
278 LALFree( detector.site );
279 detector.site = NULL;
280 tmpDetector = NULL;
281 LALWarning( stat, "Unknown detector site, computing plus mode "
282 "waveform with no time delay" );
283 break;
284 }
285
286 /* set up units for the transfer function */
287 if (XLALUnitDivide( &(detector.transfer->sampleUnits),
288 &lalADCCountUnit, &lalStrainUnit ) == NULL) {
290 }
291
292 /* invert the response function to get the transfer function */
293 LALCCreateVector( stat->statusPtr, &( transfer->data ),
294 resp->data->length );
296
297 LALCCreateVector( stat->statusPtr, &unity, resp->data->length );
299 for ( k = 0; k < resp->data->length; ++k )
300 {
301 unity->data[k] = 1.0;
302 }
303
304 LALCCVectorDivide( stat->statusPtr, transfer->data, unity,
305 resp->data );
307
308 LALCDestroyVector( stat->statusPtr, &unity );
310
311 /* Set up a time series to hold signal in ADC counts */
312 signalvec.deltaT = series->deltaT;
313 if ( ( signalvec.f0 = series->f0 ) != 0 )
314 {
315 ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM );
316 }
317 signalvec.sampleUnits = lalADCCountUnit;
318
319 signalvec.data=NULL;
320 LALSCreateVector( stat->statusPtr, &(signalvec.data),
321 series->data->length );
323
324 /* loop over list of waveforms and inject into data stream */
325 simRingdown = injections;
326 while ( simRingdown )
327 {
328 /* only do the work if the ring is in injection zone */
329 if( (injStartTime - simRingdown->geocent_start_time.gpsSeconds) *
330 (injStopTime - simRingdown->geocent_start_time.gpsSeconds) > 0 )
331 {
332 simRingdown = simRingdown->next;
333 continue;
334 }
335
336 /* set the ring params */
337 ringParam.deltaT = series->deltaT;
338 if( !( strcmp( simRingdown->coordinates, "HORIZON" ) ) )
339 {
341 }
342 else if ( !( strcmp( simRingdown->coordinates, "ZENITH" ) ) )
343 {
344 /* set coordinate system for completeness */
346 detector.site = NULL;
347 }
348 else if ( !( strcmp( simRingdown->coordinates, "GEOGRAPHIC" ) ) )
349 {
351 }
352 else if ( !( strcmp( simRingdown->coordinates, "EQUATORIAL" ) ) )
353 {
355 }
356 else if ( !( strcmp( simRingdown->coordinates, "ECLIPTIC" ) ) )
357 {
359 }
360 else if ( !( strcmp( simRingdown->coordinates, "GALACTIC" ) ) )
361 {
363 }
364 else
366
367 /* generate the ring */
368 memset( &waveform, 0, sizeof(CoherentGW) );
369 LALGenerateRing( stat->statusPtr, &waveform, series, simRingdown, &ringParam );
371
372 /* print the waveform to a file */
373 if ( 0 )
374 {
375 FILE *fp;
376 char fname[512];
377 UINT4 jj, kplus, kcross;
378 snprintf( fname, XLAL_NUM_ELEM(fname),
379 "waveform-%d-%d-%s.txt",
380 simRingdown->geocent_start_time.gpsSeconds,
382 simRingdown->waveform );
383 fp = fopen( fname, "w" );
384
385 for( jj = 0, kplus = 0, kcross = 1; jj < waveform.phi->data->length;
386 ++jj, kplus += 2, kcross +=2 )
387 {
388 fprintf(fp, "%d %e %e %le %e\n", jj,
389 waveform.a->data->data[kplus],
390 waveform.a->data->data[kcross],
391 waveform.phi->data->data[jj],
392 waveform.f->data->data[jj]);
393 }
394 fclose( fp );
395 }
396 /* end */
397#if 0
398 fprintf( stderr, "a->epoch->gpsSeconds = %d\na->epoch->gpsNanoSeconds = %d\n",
399 waveform.a->epoch.gpsSeconds, waveform.a->epoch.gpsNanoSeconds );
400 fprintf( stderr, "phi->epoch->gpsSeconds = %d\nphi->epoch->gpsNanoSeconds = %d\n",
401 waveform.phi->epoch.gpsSeconds, waveform.phi->epoch.gpsNanoSeconds );
402 fprintf( stderr, "f->epoch->gpsSeconds = %d\nf->epoch->gpsNanoSeconds = %d\n",
403 waveform.f->epoch.gpsSeconds, waveform.f->epoch.gpsNanoSeconds );
404#endif
405 /* must set the epoch of signal since it's used by coherent GW */
406 signalvec.epoch = series->epoch;
407 memset( signalvec.data->data, 0, signalvec.data->length * sizeof(REAL4) );
408
409 /* decide which way to calibrate the data; defaul to old way */
410 if( calType )
411 detector.transfer=NULL;
412 else
413 detector.transfer=transfer;
414
415 /* convert this into an ADC signal */
416 LALSimulateCoherentGW( stat->statusPtr,
417 &signalvec, &waveform, &detector );
419
420
421/* print the waveform to a file */
422 if ( 0 )
423 {
424 FILE *fp;
425 char fname[512];
426 UINT4 jj;
427 snprintf( fname, XLAL_NUM_ELEM(fname),
428 "signal-%d-%d-%s.txt",
429 simRingdown->geocent_start_time.gpsSeconds,
431 simRingdown->waveform );
432 fp = fopen( fname, "w" );
433
434 for( jj = 0; jj < signalvec.data->length; ++jj )
435 {
436 fprintf( fp, "%d %le\n", jj, signalvec.data->data[jj] );
437 }
438 fclose( fp );
439 }
440 /* end */
441#if 0
442 fprintf( stderr, "series.epoch->gpsSeconds = %d\nseries.epoch->gpsNanoSeconds = %d\n",
443 series->epoch.gpsSeconds, series->epoch.gpsNanoSeconds );
444 fprintf( stderr, "signalvec->epoch->gpsSeconds = %d\nsignalvec->epoch->gpsNanoSeconds = %d\n",
445 signalvec.epoch.gpsSeconds, signalvec.epoch.gpsNanoSeconds );
446#endif
447 /* if calibration using RespFilt */
448 if( calType == 1 )
449 XLALRespFilt(&signalvec, transfer);
450
451 /* inject the signal into the data channel */
452 LALSSInjectTimeSeries( stat->statusPtr, series, &signalvec );
454
455/* free memory in coherent GW structure. TODO: fix this */
456 LALSDestroyVectorSequence( stat->statusPtr, &( waveform.a->data ) );
458 LALSDestroyVector( stat->statusPtr, &( waveform.f->data ) );
460 LALDDestroyVector( stat->statusPtr, &( waveform.phi->data ) );
462 LALFree( waveform.a ); waveform.a = NULL;
463 LALFree( waveform.f ); waveform.f = NULL;
464 LALFree( waveform.phi ); waveform.phi = NULL;
465
466 /* reset the detector site information in case it changed */
467 detector.site = tmpDetector;
468
469 /* move on to next one */
470 simRingdown = simRingdown->next;
471 }
472
473 /* destroy the signal */
474 LALSDestroyVector( stat->statusPtr, &(signalvec.data) );
476
477 LALCDestroyVector( stat->statusPtr, &( transfer->data ) );
479
480 if ( detector.site ) LALFree( detector.site );
481 LALFree( transfer );
482
484 RETURN( stat );
485}
LALDetectorIndexLLODIFF
LALDetectorIndexLHODIFF
int k
#define LALCalloc(m, n)
#define LALMalloc(n)
#define LALFree(p)
#define ABORT(statusptr, code, mesg)
#define CHECKSTATUSPTR(statusptr)
#define ENDFAIL(statusptr)
#define TRY(func, statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define ABORTXLAL(sp)
#define BEGINFAIL(statusptr)
void LALSimulateCoherentGW(LALStatus *status, REAL4TimeSeries *output, CoherentGW *input, DetectorResponse *detector)
#define fprintf
const char * detector
void LALSDestroyVectorSequence(LALStatus *status, REAL4VectorSequence **vectorSequence)
void LALSCreateVectorSequence(LALStatus *status, REAL4VectorSequence **vectorSequence, CreateVectorSequenceIn *vSeqParams)
REAL4TimeSeries * XLALRespFilt(REAL4TimeSeries *strain, COMPLEX8FrequencySeries *transfer)
const LALDetector lalCachedDetectors[LAL_NUM_DETECTORS]
#define GENERATERINGH_EOUT
Output field a, f, phi, or shift already exists.
Definition: GenerateRing.h:55
#define GENERATERINGH_ENUL
Unexpected null pointer in arguments.
Definition: GenerateRing.h:54
#define GENERATERINGH_EMEM
Out of memory.
Definition: GenerateRing.h:56
void LALGenerateRing(LALStatus *stat, CoherentGW *output, REAL4TimeSeries UNUSED *series, SimRingdownTable *simRingdown, RingParamStruc *params)
Definition: GenerateRing.c:44
void LALRingInjectSignals(LALStatus *stat, REAL4TimeSeries *series, SimRingdownTable *injections, COMPLEX8FrequencySeries *resp, INT4 calType)
Definition: GenerateRing.c:219
#define GENERATERINGH_ETYP
Waveform type not implemented.
Definition: GenerateRing.h:57
void LALSSInjectTimeSeries(LALStatus *, REAL4TimeSeries *output, REAL4TimeSeries *signalvec)
#define LAL_TWOPI
#define XLAL_NUM_ELEM(x)
double REAL8
int64_t INT8
uint32_t UINT4
int32_t INT4
float REAL4
LALNameLength
int LALWarning(LALStatus *status, const char *warning)
COORDINATESYSTEM_GALACTIC
COORDINATESYSTEM_ECLIPTIC
COORDINATESYSTEM_GEOGRAPHIC
COORDINATESYSTEM_HORIZON
COORDINATESYSTEM_EQUATORIAL
const LALUnit lalStrainUnit
const LALUnit lalADCCountUnit
const LALUnit lalHertzUnit
const LALUnit lalDimensionlessUnit
LALUnit * XLALUnitDivide(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
void LALCCreateVector(LALStatus *, COMPLEX8Vector **, UINT4)
void LALDCreateVector(LALStatus *, REAL8Vector **, UINT4)
void LALCDestroyVector(LALStatus *, COMPLEX8Vector **)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
void LALSDestroyVector(LALStatus *, REAL4Vector **)
void LALSCreateVector(LALStatus *, REAL4Vector **, UINT4)
void LALCCVectorDivide(LALStatus *status, COMPLEX8Vector *out, const COMPLEX8Vector *in1, const COMPLEX8Vector *in2)
SimInspiralTable * injections
Definition: inspfrinj.c:339
int i
Definition: inspinj.c:596
waveform
interval
h0
f0
stat
int t
CHAR fname[256]
Definition: spininj.c:211
double t0
COMPLEX8Sequence * data
COMPLEX8 * data
INT4 gpsNanoSeconds
REAL4Sequence * data
LALUnit sampleUnits
LIGOTimeGPS epoch
REAL4 * data
This structure stores the parameters for constructing a burst gravitational waveform.
Definition: GenerateRing.h:79
REAL8 deltaT
requested sampling interval (s)
Definition: GenerateRing.h:80
CoordinateSystem system
coordinate system to assume for simRingdown
Definition: GenerateRing.h:81
CHAR waveform[LIGOMETA_WAVEFORM_MAX]
struct tagSimRingdownTable * next
LIGOTimeGPS geocent_start_time
CHAR coordinates[LIGOMETA_COORDINATES_MAX]
Definition: series.h:36
char * name
Definition: series.h:37
float f0
Definition: series.h:43
float * data
Definition: series.h:46
FILE * fp
int output(const char *outfile, int outtype, REAL4TimeSeries *series)
Definition: view.c:603