Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALInspiral 5.0.3.1-ea7c608
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
SnglInspiralUtils.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Alexander Dietz, Drew Keppel, Duncan Brown, Eirini Messaritaki, Jolien Creighton, Patrick Brady, Stephen Fairhurst, Craig Robinson , Thomas Cokelaer
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/*-----------------------------------------------------------------------
21 *
22 * File Name: SnglInspiralUtils.c
23 *
24 * Author: Brady, P. R., Brown, D. A., Fairhurst, S. and Messaritaki, E.
25 *
26 *-----------------------------------------------------------------------
27 */
28
29#include <math.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <lal/LALError.h>
33#include <lal/LALStdlib.h>
34#include <lal/LALStdio.h>
35#include <lal/LIGOMetadataTables.h>
36#include <lal/LIGOMetadataUtils.h>
37#include <lal/LIGOMetadataInspiralUtils.h>
38#include <lal/Date.h>
39#include <lal/SkyCoordinates.h>
40#include <lal/GeneratePPNInspiral.h>
41#include <lal/DetectorSite.h>
42#include <lal/DetResponse.h>
43#include <lal/TimeDelay.h>
44
45/**
46 * \author Brown, D. A., Fairhurst, S. and Messaritaki, E.
47 * \file
48 *
49 * \brief Provides a set of utilities for manipulating \c snglInspiralTables.
50 *
51 * ### Description ###
52 *
53 * The function <tt>LALFreeSnglInspiral()</tt> and XLALFreeSnglInspiral()
54 * free the memory associated to a single inspiral table. The single inspiral
55 * table may point to a linked list of EventIDColumns. Thus, it is necessary to
56 * free all event ids associated with the single inspiral.
57 *
58 * The function <tt>LALSortSnglInspiral()</tt> and <tt>XLALSortSnglInspiral()</tt>
59 * sorts a list of single inspiral tables. The function simply calls qsort with
60 * the appropriate comparison function, \c comparfunc. It then ensures that
61 * the head of the sorted list is returned. There then follow several comparison
62 * functions for single inspiral tables.
63 * \c LALCompareSnglInspiralByTime()
64 * compares the end times of two single inspiral tables, returnng 1 if the first
65 * time is larger, 0 if equal and -1 if the second time is larger.
66 *
67 * <tt>XLALTimeCutSingleInspiral()</tt>takes in a linked list of single inspiral
68 * tables and returns only those which occur after the given \c startTime
69 * and before the \c endTime.
70 *
71 * <tt>XLALIfoCutSingleInspiral()</tt> scans through a linked list of
72 * single inspiral table rows and separates the elements into two lists.
73 * the return value is the head of the list containing rows from the
74 * requested instrument; the original list (the address of whose head
75 * might have changed) contains rows not from the requested instrument.
76 *
77 * ### Algorithm ###
78 *
79 * None.
80 *
81 * ### Uses ###
82 *
83 * LALCalloc(), LALFree(), LALINT8NanoSecIsPlayground().
84 *
85 */
86
87/*
88 * A few quickies for convenience.
89 */
90
92{
93 return(XLALGPSToINT8NS(&x->end));
94}
95
96
99 SnglInspiralTable *eventHead,
100 int(*comparfunc) (const void *, const void *)
101 )
102
103{
104 INT4 i;
105 INT4 numEvents = 0;
106 SnglInspiralTable *thisEvent = NULL;
107 SnglInspiralTable **eventHandle = NULL;
108
109 /* count the number of events in the linked list */
110 for ( thisEvent = eventHead; thisEvent; thisEvent = thisEvent->next )
111 {
112 ++numEvents;
113 }
114 if ( ! numEvents )
115 {
117 "XLALSortSnglInspiral: Empty SnglInspiralTable passed as input\n" );
118 return( eventHead );
119 }
120
121 /* allocate memory for an array of pts to sort and populate array */
122 eventHandle = (SnglInspiralTable **)
123 LALCalloc( numEvents, sizeof(SnglInspiralTable *) );
124 for ( i = 0, thisEvent = eventHead; i < numEvents;
125 ++i, thisEvent = thisEvent->next )
126 {
127 eventHandle[i] = thisEvent;
128 }
129
130 /* qsort the array using the specified function */
131 qsort( eventHandle, numEvents, sizeof(eventHandle[0]), comparfunc );
132
133 /* re-link the linked list in the right order */
134 thisEvent = eventHead = eventHandle[0];
135 for ( i = 1; i < numEvents; ++i )
136 {
137 thisEvent = thisEvent->next = eventHandle[i];
138 }
139 thisEvent->next = NULL;
140
141 /* free the internal memory */
142 LALFree( eventHandle );
143
144 return( eventHead );
145}
146
147
148int
150 const void *a,
151 const void *b
152 )
153
154{
156 const SnglInspiralTable *aPtr = *((const SnglInspiralTable * const *)a);
157 const SnglInspiralTable *bPtr = *((const SnglInspiralTable * const *)b);
158 INT8 ta, tb;
159
160 memset( &status, 0, sizeof(LALStatus) );
161 ta = XLALGPSToINT8NS( &(aPtr->end) );
162 tb = XLALGPSToINT8NS( &(bPtr->end) );
163
164 if ( ta > tb )
165 {
166 return 1;
167 }
168 else if ( ta < tb )
169 {
170 return -1;
171 }
172 else
173 {
174 return 0;
175 }
176}
177
178
179
182 SnglInspiralTable *eventHead,
183 LIGOTimeGPS *startTime,
184 LIGOTimeGPS *endTime
185 )
186
187{
188 SnglInspiralTable *inspiralEventList = NULL;
189 SnglInspiralTable *thisEvent = NULL;
190 SnglInspiralTable *prevEvent = NULL;
191 INT8 startTimeNS = XLALGPSToINT8NS( startTime );
192 INT8 endTimeNS = XLALGPSToINT8NS( endTime );
193
194
195 /* Remove all the triggers before and after the requested */
196 /* gps start and end times */
197
198 thisEvent = eventHead;
199
200 while ( thisEvent )
201 {
202 SnglInspiralTable *tmpEvent = thisEvent;
203 thisEvent = thisEvent->next;
204
205 if ( end_time(tmpEvent) >= startTimeNS &&
206 end_time(tmpEvent) < endTimeNS )
207 {
208 /* keep this template */
209 if ( ! inspiralEventList )
210 {
211 inspiralEventList = tmpEvent;
212 }
213 else
214 {
215 prevEvent->next = tmpEvent;
216 }
217 tmpEvent->next = NULL;
218 prevEvent = tmpEvent;
219 }
220 else
221 {
222 /* discard this template */
224 }
225 }
226 eventHead = inspiralEventList;
227
228 return (eventHead);
229}
230
231
232
235 SnglInspiralTable **eventHead,
236 char *ifo
237 )
238
239{
240 SnglInspiralTable *prevEvent = NULL;
241 SnglInspiralTable *thisEvent = NULL;
242 SnglInspiralTable *ifoHead = NULL;
243 SnglInspiralTable *thisIfoTrig = NULL;
244
245 /* check that eventHead is non-null */
246 if ( ! eventHead )
247 {
249 }
250
251 /* Scan through a linked list of sngl_inspiral tables and return a
252 pointer to the head of a linked list of tables for a specific IFO */
253
254 thisEvent = *eventHead;
255 *eventHead = NULL;
256
257 while ( thisEvent )
258 {
259 if ( ! strcmp( thisEvent->ifo, ifo ) )
260 {
261 /* ifos match so keep this event */
262 if ( ifoHead )
263 {
264 thisIfoTrig = thisIfoTrig->next = thisEvent;
265 }
266 else
267 {
268 ifoHead = thisIfoTrig = thisEvent;
269 }
270
271 /* remove from eventHead list */
272 if ( prevEvent )
273 {
274 prevEvent->next = thisEvent->next;
275 }
276
277 /* move to next event */
278 thisEvent = thisEvent->next;
279 /* terminate ifo list */
280 thisIfoTrig->next = NULL;
281 }
282 else
283 {
284 /* move along the list */
285 if ( ! *eventHead )
286 {
287 *eventHead = thisEvent;
288 }
289
290 prevEvent = thisEvent;
291 thisEvent = thisEvent->next;
292 }
293 }
294
295 return( ifoHead );
296}
297
298
299
301
302{
303 INT4 length;
305
306 if ( !head )
307 {
308 return( 0 );
309 }
310
311 /* count the number of events in the list */
312 for(length = 0, event = head; event; event = event->next)
313 length++;
314
315 return length;
316}
317
318
321 SnglInspiralTable *eventHead,
322 const char *massCut,
323 REAL4 massRangeLow,
324 REAL4 massRangeHigh,
325 REAL4 mass2RangeLow,
326 REAL4 mass2RangeHigh
327 )
328
329{
330 SnglInspiralTable *inspiralEventList = NULL;
331 SnglInspiralTable *thisEvent = NULL;
332 SnglInspiralTable *prevEvent = NULL;
333
334 REAL4 massParam;
335 REAL4 mass2Param;
336 INT4 massBOOL;
337 REAL4 eps = 1.e-08; /* Safeguard against roundoff error in eta */
338
339 /* Remove all the triggers which are not of the desired type */
340
341 thisEvent = eventHead;
342
343 while ( thisEvent )
344 {
345 SnglInspiralTable *tmpEvent = thisEvent;
346 thisEvent = thisEvent->next;
347 massParam = 0;
348 mass2Param = 0;
349
350 if ( ! strcmp(massCut,"mchirp") )
351 {
352 massParam = tmpEvent->mchirp;
353 }
354 else if ( ! strcmp(massCut,"eta") )
355 {
356 massParam = tmpEvent->eta;
357 }
358 else if ( ! strcmp(massCut,"mtotal") )
359 {
360 massParam = tmpEvent->mass1 + tmpEvent->mass2;
361 }
362 else if ( ! strcmp(massCut,"mcomp") )
363 {
364 massParam = tmpEvent->mass1;
365 mass2Param = tmpEvent->mass2;
366 }
367
368 if ( ! strcmp(massCut,"mcomp") )
369 {
370 if ( ( massParam >= massRangeLow ) && ( massParam < massRangeHigh ) &&
371 ( mass2Param >= mass2RangeLow ) && ( mass2Param < mass2RangeHigh ) )
372 {
373 massBOOL = 1;
374 }
375 else
376 {
377 massBOOL = 0;
378 }
379 }
380 else if ( ! strcmp(massCut,"eta") )
381 {
382 if ( ( massParam >= massRangeLow - eps ) &&
383 ( massParam <= massRangeHigh + eps ) )
384 {
385 massBOOL = 1;
386 }
387 else
388 {
389 massBOOL = 0;
390 }
391 }
392 else
393 {
394 if ( ( massParam >= massRangeLow ) && ( massParam < massRangeHigh ) )
395 {
396 massBOOL = 1;
397 }
398 else
399 {
400 massBOOL = 0;
401 }
402 }
403
404 if ( massBOOL )
405 {
406 /* keep this trigger */
407 if ( ! inspiralEventList )
408 {
409 inspiralEventList = tmpEvent;
410 }
411 else
412 {
413 prevEvent->next = tmpEvent;
414 }
415 tmpEvent->next = NULL;
416 prevEvent = tmpEvent;
417 }
418 else
419 {
420 /* discard this template */
422 }
423 }
424
425 eventHead = inspiralEventList;
426 return(eventHead);
427}
#define LALCalloc(m, n)
#define LALFree(p)
SnglInspiralTable * XLALDestroySnglInspiralTableRow(SnglInspiralTable *row)
int LALCompareSnglInspiralByTime(const void *a, const void *b)
SnglInspiralTable * XLALSortSnglInspiral(SnglInspiralTable *eventHead, int(*comparfunc)(const void *, const void *))
SnglInspiralTable * XLALIfoCutSingleInspiral(SnglInspiralTable **eventHead, char *ifo)
SnglInspiralTable * XLALTimeCutSingleInspiral(SnglInspiralTable *eventHead, LIGOTimeGPS *startTime, LIGOTimeGPS *endTime)
static INT8 end_time(const SnglInspiralTable *x)
INT4 XLALCountSnglInspiral(SnglInspiralTable *head)
SnglInspiralTable * XLALMassCut(SnglInspiralTable *eventHead, const char *massCut, REAL4 massRangeLow, REAL4 massRangeHigh, REAL4 mass2RangeLow, REAL4 mass2RangeHigh)
double i
int64_t INT8
int32_t INT4
float REAL4
static const REAL4 eps
static const INT4 a
#define XLAL_ERROR_NULL(...)
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_EIO
INT8 XLALGPSToINT8NS(const LIGOTimeGPS *epoch)
x
CHAR ifo[LIGOMETA_IFO_MAX]
LIGOTimeGPS end
struct tagSnglInspiralTable * next
Definition: _thinca.c:157