LALApps 10.1.0.1-eeff03c
StringSearch.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Jolien Creighton, Kipp Cannon, Patrick Brady, Xavier Siemens
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/* Cosmic string search code */
22/* */
23/* X. Siemens, J. Creighton, F. Robinet, and K. Cannon */
24/* */
25/* UWM/LAL - December 2009 */
26/*********************************************************************************/
27
28#include <config.h>
29
30#include <complex.h>
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <fcntl.h>
34#include <stdio.h>
35#include <string.h>
36#include <stdlib.h>
37#include <math.h>
38#include <time.h>
39#include <glob.h>
40#include <errno.h>
41#include <stdarg.h>
42
43#include <gsl/gsl_rng.h>
44#include <gsl/gsl_randist.h>
45#include <gsl/gsl_roots.h>
46
47#include <lal/LALDatatypes.h>
48#include <lal/LALgetopt.h>
49#include <lal/LALStdlib.h>
50#include <lal/LALStdio.h>
51#include <lal/FileIO.h>
52#include <lal/AVFactories.h>
53#include <lal/LALCache.h>
54#include <lal/LALFrStream.h>
55#include <lal/Window.h>
56#include <lal/LALConstants.h>
57#include <lal/BandPassTimeSeries.h>
58#include <lal/AVFactories.h>
59#include <lal/ResampleTimeSeries.h>
60#include <lal/TimeFreqFFT.h>
61#include <lal/RealFFT.h>
62#include <lal/PrintFTSeries.h>
63#include <lal/Date.h>
64#include <lal/Units.h>
65
66#include <lal/LIGOMetadataTables.h>
67#include <lal/LIGOMetadataUtils.h>
68#include <lal/SnglBurstUtils.h>
69
70#include <lal/LIGOLwXML.h>
71#include <lal/LIGOLwXMLRead.h>
72
73#include <lal/FrequencySeries.h>
74#include <lal/TimeSeries.h>
75#include <lal/GenerateBurst.h>
76
77#include <LALAppsVCSInfo.h>
78
79#define TESTSTATUS( pstat ) \
80 if ( (pstat)->statusCode ) { REPORTSTATUS(pstat); return 100; } else ((void)0)
81
82#define MAXTEMPLATES 50
83
84
85/* FIXME: should be "lalapps_StringSearch" to match the executable */
86/* requires post-processing codes to be updated */
87#define PROGRAM_NAME "StringSearch"
88#define CVS_REVISION "$Revision$"
89#define CVS_SOURCE "$Source$"
90#define CVS_DATE "$Date$"
91
92
93/***************************************************************************/
94
95/* STRUCTURES */
96struct CommandLineArgsTag {
97 REAL8 samplerate; /* desired sample rate */
98 REAL8 fbankstart; /* lowest frequency of templates */
99 REAL8 fbankhighfcutofflow; /* lowest high frequency cut-off */
100 REAL8 fmismatchmax; /* maximal mismatch allowed from 1 template to the next */
101 char *FrCacheFile; /* Frame cache file */
102 char *InjectionFile; /* LIGO/Virgo xml injection file */
103 char *TemplateFile; /* File with the list of fcutoff for a static template bank */
104 char *ChannelName; /* Name of channel to be read in from frames */
105 char *outputFileName; /* Name of xml output filename */
106 LIGOTimeGPS GPSStart; /* GPS start time of segment to be analysed */
107 LIGOTimeGPS GPSEnd; /* GPS end time of segment to be analysed */
108 INT4 ShortSegDuration; /* Number of fixed length sub-segments between GPSStart and GPSEnd */
109 REAL8 TruncSecs; /* Half the number of seconds truncated at beginning and end of a chunk */
110 REAL8 power; /* Kink (-5/3) or cusp (-4/3) frequency power law */
111 REAL8 threshold; /* event SNR threshold */
112 INT4 fakenoiseflag; /* =0 if real noise =1 if fake gaussian noise */
113 INT4 whitespectrumflag; /* =0 if spectrum is to be computed =1 for white spectrum */
114 LIGOTimeGPS trigstarttime; /* GPS start time of allowed triggers */
115 REAL8 cluster; /* =0.0 if events are not to be clustered = clustering time otherwise */
116 INT4 pad; /* seconds of padding */
117 double chi2cut[3]; /* chi2 cut parameters */
118 INT4 printspectrumflag; /* flag set to 1 if user wants to print the spectrum */
119 INT4 printfilterflag; /* flag set to 1 if user wants to print the filter in the frequency domain */
120 INT4 printfirflag; /* flag set to 1 if user wants to print the filter in the time domain */
121 INT4 printsnrflag; /* flag set to 1 if user wants to print the snr */
122 INT4 printdataflag; /* flag set to 1 if user wants to print the data */
123 INT4 printinjectionflag; /* flag set to 1 if user wants to print the injection(s) */
124 char *comment; /* for "comment" columns in some tables */
125};
126
127typedef
128struct StringTemplateTag {
129 INT4 findex; /* Template frequency index */
130 REAL8 f; /* Template frequency */
131 REAL8 norm; /* Template normalisation */
132 REAL8 mismatch; /* Template mismatch relative to last one */
133 REAL8FrequencySeries *StringFilter; /* Frequency domain filter corresponding to this template */
134 REAL8Vector *waveform_t; /* Template waveform - time-domain */
135 COMPLEX16Vector *waveform_f; /* Template waveform - frequency domain */
136 REAL8Vector *auto_cor; /* Auto-correlation vector */
137 INT4 chi2_index; /* index to compute chi2 */
139
140/***************************************************************************/
141
142/* time window for trigger clustering */
143/* FIXME: global variables = BAD BAD BAD! (my fault -- Kipp) */
144static double cluster_window; /* seconds */
145
146/***************************************************************************/
147
148/* FUNCTION PROTOTYPES */
149
150/* Reads the command line */
151int ReadCommandLine(int argc,char *argv[],struct CommandLineArgsTag *CLA, const ProcessTable *process, ProcessParamsTable **paramaddpoint);
152
153/* Reads the template bank file */
154int ReadTemplateFile(struct CommandLineArgsTag CLA, int *NTemplates_fix, REAL8 *fcutoff_fix);
155
156/* Reads raw data (or puts in fake gaussian noise with a sigma=10^-20) */
158
159/* Adds injections if an xml injection file is given */
161
162/* DownSamples data */
164
165/* Computes the average spectrum */
166REAL8FrequencySeries *AvgSpectrum(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht, unsigned seg_length, REAL8FFTPlan *fplan);
167
168/* Creates the template bank based on the spectrum */
169int CreateTemplateBank(struct CommandLineArgsTag CLA, unsigned seg_length, REAL8FrequencySeries *Spec, StringTemplate *strtemplate, int *NTemplates, REAL8 *fcutoff_fix, int NTemplates_fix, REAL8FFTPlan *rplan);
170
171/* Creates the frequency domain string cusp or kink filters */
172int CreateStringFilters(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht, unsigned seg_length, REAL8FrequencySeries *Spec, StringTemplate *strtemplate, int NTemplates, REAL8FFTPlan *fplan, REAL8FFTPlan *rplan);
173
174/* Filters the data through the template banks */
175int FindStringBurst(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht, unsigned seg_length, const StringTemplate *strtemplate, int NTemplates, REAL8FFTPlan *fplan, REAL8FFTPlan *rplan, SnglBurst **head);
176
177/* Finds events above SNR threshold specified */
178int FindEvents(struct CommandLineArgsTag CLA, const StringTemplate *strtemplate,
179 const REAL8TimeSeries *vector, SnglBurst **head);
180
181/* Writes out the xml file with the events it found */
182int OutputEvents(const struct CommandLineArgsTag *CLA, ProcessTable *proctable, ProcessParamsTable *procparamtable, SnglBurst *events);
183
184/* Frees the memory */
185int FreeMem(StringTemplate *strtemplate, int NTemplates);
186
187/* Clustering comparison function */
188static int XLALCompareStringBurstByTime(const SnglBurst * const *, const SnglBurst * const *);
189
190/* Cluster functions */
191static void XLALStringBurstCluster(SnglBurst *, const SnglBurst *);
192static void XLALClusterSnglBurstTable(SnglBurst **, int (*)(const SnglBurst * const *, const SnglBurst * const *), int (*)(const SnglBurst * const *, const SnglBurst * const *), void (*)(SnglBurst *, const SnglBurst *));
193
194
195/************************************* MAIN PROGRAM *************************************/
196
197int main(int argc,char *argv[])
198{
200 unsigned seg_length;
201 StringTemplate strtemplate[MAXTEMPLATES];
202 int NTemplates;
203 int NTemplates_fix; /* number of template given by the template bank file */
204 REAL8 fcutoff_fix[MAXTEMPLATES]; /* high frequency cutoffs given by the template bank file */
205 SnglBurst *events=NULL;
207 ProcessParamsTable *procparams = NULL;
208 REAL8TimeSeries *ht; /* strain data */
209 REAL8FFTPlan *fplan; /* fft plan */
210 REAL8FFTPlan *rplan; /* fft plan */
211 REAL8FrequencySeries *Spec; /* average spectrum */
212
213
214 /* create the process and process params tables */
216 XLALGPSTimeNow(&(process->start_time));
218 exit(1);
219
220 /****** ReadCommandLine ******/
221 XLALPrintInfo("ReadCommandLine()\n");
222 if (ReadCommandLine(argc,argv,&CommandLineArgs, process, &procparams)) return 1;
223 XLALPrintInfo("\t%c%c detector\n",CommandLineArgs.ChannelName[0],CommandLineArgs.ChannelName[1]);
224 /* set the trigger cluster window global variable */
226
227 /****** ReadTemplatefile ******/
228 if (CommandLineArgs.TemplateFile != NULL) {
229 XLALPrintInfo("ReadTemplateFile()\n");
230 if (ReadTemplateFile(CommandLineArgs,&NTemplates_fix,fcutoff_fix)) return 3;
231 }
232
233 /****** ReadData ******/
234 XLALPrintInfo("ReadData()\n");
236 if (!ht) return 4;
237
238 /****** AddInjections ******/
239 if (CommandLineArgs.InjectionFile != NULL) {
240 XLALPrintInfo("AddInjections()\n");
241 if (AddInjections(CommandLineArgs, ht)) return 5;
242 if ( CommandLineArgs.printinjectionflag ) LALDPrintTimeSeries( ht, "injection.txt" );
243 }
244
245 if ( CommandLineArgs.printdataflag ){
246 unsigned p;
247 for (p=0; p<ht->data->length; p++)
248 fprintf(stdout,"%1.15e\n",ht->data->data[p]);
249 return 0;
250 }
251
252 /****** DownSample ******/
253 XLALPrintInfo("DownSample()\n");
254 if (DownSample(CommandLineArgs, ht)) return 8;
255
256 /****** XLALResizeREAL8TimeSeries ******/
257 XLALPrintInfo("XLALResizeREAL8TimeSeries()\n");
258 /* re-size the time series to remove the pad */
259 ht = XLALResizeREAL8TimeSeries(ht, (int)round(CommandLineArgs.pad/ht->deltaT),
260 ht->data->length-2*(int)round(CommandLineArgs.pad/ht->deltaT));
261
262 /****** FFT plans ******/
263 seg_length = round(CommandLineArgs.ShortSegDuration / ht->deltaT);
264 fplan = XLALCreateForwardREAL8FFTPlan( seg_length, 1 );
265 rplan = XLALCreateReverseREAL8FFTPlan( seg_length, 1 );
266 if(!fplan || !rplan) {
269 return 9;
270 }
271
272 /****** AvgSpectrum ******/
273 XLALPrintInfo("AvgSpectrum()\n");
274 Spec = AvgSpectrum(CommandLineArgs, ht, seg_length, fplan);
275 if (!Spec) return 9;
276 if (CommandLineArgs.printspectrumflag) LALDPrintFrequencySeries( Spec, "Spectrum.txt" );
277
278 /****** CreateTemplateBank ******/
279 XLALPrintInfo("CreateTemplateBank()\n");
280 if (CreateTemplateBank(CommandLineArgs, seg_length, Spec, strtemplate, &NTemplates, fcutoff_fix, NTemplates_fix, rplan)) return 10;
281
282 /****** CreateStringFilters ******/
283 XLALPrintInfo("CreateStringFilters()\n");
284 if (CreateStringFilters(CommandLineArgs, ht, seg_length, Spec, strtemplate, NTemplates, fplan, rplan)) return 11;
286 Spec = NULL;
287
288 /****** FindStringBurst ******/
289 XLALPrintInfo("FindStringBurst()\n");
290 if (FindStringBurst(CommandLineArgs, ht, seg_length, strtemplate, NTemplates, fplan, rplan, &events)) return 12;
294
295 /****** XLALClusterSnglBurstTable ******/
296 XLALPrintInfo("XLALClusterSnglBurstTable()\n");
297 if (CommandLineArgs.cluster != 0.0 && events)
299
300 /****** XLALSnglBurstAssignIDs ******/
301 XLALPrintInfo("XLALSnglBurstAssignIDs()\n");
303 XLALSnglBurstAssignIDs(events, process->process_id, 0);
304
305 /****** OutputEvents ******/
306 XLALPrintInfo("OutputEvents()\n");
307 if (OutputEvents(&CommandLineArgs, process, procparams, events)) return 13;
308
309 /****** FreeMem ******/
310 XLALPrintInfo("FreeMem()\n");
314 if (FreeMem(strtemplate, NTemplates)) return 14;
315
316 XLALPrintInfo("StringJob is done\n");
317
318 return 0;
319}
320
321
322/**************************** MAIN PROGRAM ENDS ********************************/
323
324/*******************************************************************************/
325
326/*
327 * Check if two string events overlap in time. The peak times are uncertain
328 * to whatever the high frequency cutoff is
329 */
330
331
333 const SnglBurst * const *a,
334 const SnglBurst * const *b
335)
336
337{
338 double delta_t = XLALGPSDiff(&(*a)->peak_time, &(*b)->peak_time);
339
341 return(1);
343 return(-1);
344 return(0);
345}
346
347
348/**
349 * cluster events a and b, storing result in a; takes one with largest snr
350 */
352 SnglBurst *a,
353 const SnglBurst *b
354)
355{
356 if(b->snr > a->snr)
357 *a = *b;
358}
359
360
361/**
362 * Recursively cluster a linked list of SnglBurst events until the list
363 * stops changing. testfunc() should return 0 if the two given events are to
364 * be clustered. If bailoutfunc() is provided (not NULL), then testfunc() will
365 * be used to sort the trigger list before each clustering pass and
366 * bailoutfunc() will be called to check for the option of terminating the
367 * inner loop early. In the ideal case, use of bailoutfunc() converts this
368 * algorithm from O(n^3) to order O(n log n). The clusterfunc() should replace
369 * the SnglBurst event pointed to by its first argument with the cluster
370 * of that event and the event pointed to by the second argument.
371 */
373 SnglBurst **list,
374 int (*bailoutfunc)(const SnglBurst * const *, const SnglBurst * const *),
375 int (*testfunc)(const SnglBurst * const *, const SnglBurst * const *),
376 void (*clusterfunc)(SnglBurst *, const SnglBurst *)
377)
378{
379 int did_cluster;
380 SnglBurst *a, *b, *prev;
381
382 do {
383 did_cluster = 0;
384
385 if(bailoutfunc)
387
388 for(a = *list; a; a = a->next)
389 for(prev = a, b = a->next; b; b = prev->next) {
390 if(!testfunc((const SnglBurst * const *) &a, (const SnglBurst * const *) &b)) {
391 clusterfunc(a, b);
392 prev->next = b->next;
394 did_cluster = 1;
395 } else if(bailoutfunc && bailoutfunc((const SnglBurst * const *) &a, (const SnglBurst * const *) &b))
396 break;
397 else
398 prev = b;
399 }
400 } while(did_cluster);
401}
402
403
404/*******************************************************************************/
405
407 TimeSlide *time_slide_table_head;
408 SimBurst *sim_burst_table_head;
409 COMPLEX16FrequencySeries *response = NULL;
410
411 /* Get info from injection file */
412 time_slide_table_head = XLALTimeSlideTableFromLIGOLw(CLA.InjectionFile);
413 sim_burst_table_head = XLALSimBurstTableFromLIGOLw(CLA.InjectionFile);
414 if(!time_slide_table_head || !sim_burst_table_head)
415 return 1;
416
417 /* Construct response function for null stream */
418 if(0) { /* FIXME: put proper test for null stream here */
419 /* reduce injection amplitude by 10x for null stream. injection will
420 * be Fourier transformed, and the transform divided by this function
421 * bin-by-bin, rounding to the closest available bin */
422 response = XLALCreateCOMPLEX16FrequencySeries("", &ht->epoch, 0.0, 1.0, &lalDimensionlessUnit, 1);
423 if(!response)
424 return 1;
425 response->data->data[0] = 10;
426 }
427
428 /* Inject the signals into ht */
429 if(XLALBurstInjectSignals(ht, sim_burst_table_head, time_slide_table_head, response)) return 1;
431
432 /* free the injection table */
433 XLALDestroyTimeSlideTable(time_slide_table_head);
434 XLALDestroySimBurstTable(sim_burst_table_head);
435
436 return 0;
437}
438
439/*******************************************************************************/
440
442 const ProcessTable *process,
443 const char *type, const char *param, const char *value){
445 snprintf((*proc_param)->program, LIGOMETA_PROGRAM_MAX, PROGRAM_NAME);
446 snprintf((*proc_param)->type, LIGOMETA_TYPE_MAX, "%s", type);
447 snprintf((*proc_param)->param, LIGOMETA_PARAM_MAX, "--%s", param);
448 snprintf((*proc_param)->value, LIGOMETA_VALUE_MAX, "%s", value);
449
450 return(&(*proc_param)->next);
451}
452
453#define ADD_PROCESS_PARAM(process, type) \
454 do { paramaddpoint = add_process_param(paramaddpoint, process, type, long_options[option_index].name, LALoptarg); } while(0)
455
456/*******************************************************************************/
457
458int OutputEvents(const struct CommandLineArgsTag *CLA, ProcessTable *proctable, ProcessParamsTable *procparamtable, SnglBurst *events){
459 LIGOLwXMLStream *xml;
461 char ifo[3];
462
463 strncpy( ifo, CLA->ChannelName, 2 );
464 XLAL_LAST_ELEM(ifo) = '\0';
465
466 if (!CLA->outputFileName){
467 CHAR outfilename[256];
468 snprintf(outfilename, sizeof(outfilename)-1, "%s-STRINGSEARCH-%d-%d.xml", ifo, CLA->GPSStart.gpsSeconds, CLA->GPSEnd.gpsSeconds - CLA->GPSEnd.gpsSeconds);
469 XLAL_LAST_ELEM(outfilename) = '\0';
470 xml = XLALOpenLIGOLwXMLFile(outfilename);
471 } else
472 xml = XLALOpenLIGOLwXMLFile(CLA->outputFileName);
473
474 /* finish populating process table */
475 snprintf(proctable->ifos, LIGOMETA_IFOS_MAX, "%s", ifo);
476 XLALGPSTimeNow(&(proctable->end_time));
477
478 /* write process table */
479 if(XLALWriteLIGOLwXMLProcessTable(xml, proctable)) return -1;
480
481 /* write process params table */
482 if(XLALWriteLIGOLwXMLProcessParamsTable(xml, procparamtable)) return -1;
483
484 /* create the search summary table */
486 /* the number of nodes for a standalone job is always 1 */
487 searchsumm->nnodes = 1;
488 /* store the input and output start and end times */
489 searchsumm->in_start_time = CLA->GPSStart;
490 searchsumm->in_end_time = CLA->GPSEnd;
491 if (XLALGPSToINT8NS(&CLA->trigstarttime) > 0)
492 searchsumm->out_start_time = CLA->trigstarttime;
493 else {
494 searchsumm->out_start_time = CLA->GPSStart;
495 XLALGPSAdd(&searchsumm->out_start_time, CLA->ShortSegDuration/4+CLA->pad);
496 }
497 searchsumm->out_end_time = CLA->GPSEnd;
498 XLALGPSAdd(&searchsumm->out_end_time, -CLA->ShortSegDuration/4-CLA->pad);
499 snprintf(searchsumm->ifos, LIGOMETA_IFOS_MAX, "%s", ifo);
500 searchsumm->nevents = XLALSnglBurstTableLength(events);
501
502 /* write search_summary table */
505
506 /* burst table */
507 if(XLALWriteLIGOLwXMLSnglBurstTable(xml, events)) return -1;
508
510
511 return 0;
512}
513
514/*******************************************************************************/
515
516int FindEvents(struct CommandLineArgsTag CLA, const StringTemplate *strtemplate, const REAL8TimeSeries *vector, SnglBurst **head){
517 unsigned p;
518 INT4 pmax, pend, pstart;
519
520 /* print the snr to stdout */
521 if (CLA.printsnrflag)
522 for ( p = vector->data->length/4 ; p < 3*vector->data->length/4; p++ )
523 fprintf(stdout,"%p %e\n", strtemplate, vector->data->data[p]);
524
525 /* Now find event in the inner half */
526 for ( p = vector->data->length/4 ; p < 3*vector->data->length/4; p++ ){
527 REAL8 maximum_snr = 0.0;
528 pmax=p;
529
530 /* Do we have the start of a cluster? */
531 if ( (fabs(vector->data->data[p]) > CLA.threshold) && (XLALGPSDiff(&vector->epoch, &CLA.trigstarttime) + p * vector->deltaT >= 0)){
532 SnglBurst *new;
533 REAL8 chi2, ndof;
534 int pp;
535 pend=p; pstart=p;
536
537 /* Clustering in time: While we are above threshold, or within clustering time of the last point above threshold... */
538 while( ((fabs(vector->data->data[p]) > CLA.threshold) || ((p-pend)* vector->deltaT < (float)(CLA.cluster)) )
539 && p<3*vector->data->length/4){
540
541 /* This keeps track of the largest SNR point of the cluster */
542 if(fabs(vector->data->data[p]) > maximum_snr){
543 maximum_snr=fabs(vector->data->data[p]);
544 pmax=p;
545 }
546 /* pend is the last point above threshold */
547 if ( (fabs(vector->data->data[p]) > CLA.threshold))
548 pend = p;
549
550 p++;
551 }
552
553 /* compute \chi^{2} */
554 chi2=0, ndof=0;
555 for(pp=-strtemplate->chi2_index; pp<strtemplate->chi2_index; pp++){
556 chi2 += (vector->data->data[pmax+pp]-vector->data->data[pmax]*strtemplate->auto_cor->data[vector->data->length/2+pp])*(vector->data->data[pmax+pp]-vector->data->data[pmax]*strtemplate->auto_cor->data[vector->data->length/2+pp]);
557 ndof += (1-strtemplate->auto_cor->data[vector->data->length/2+pp]*strtemplate->auto_cor->data[vector->data->length/2+pp]);
558 }
559
560 /* Apply the \chi^{2} cut */
561 if( CLA.chi2cut[0] > -9999
562 && CLA.chi2cut[1] > -9999
563 && CLA.chi2cut[2] > -9999 )
564 if(log10(chi2/ndof)>CLA.chi2cut[0]
565 && log10(chi2/ndof)> CLA.chi2cut[1]*log10(fabs(maximum_snr))+CLA.chi2cut[2]) continue;
566
567 /* prepend a new event to the linked list */
568 new = XLALCreateSnglBurst();
569 if ( ! new )
571 new->next = *head;
572 *head = new;
573
574 /* Now copy stuff into event */
575 strncpy( new->ifo, CLA.ChannelName, 2 );
576 new->ifo[2] = 0;
577 strncpy( new->search, "StringCusp", sizeof( new->search ) );
578 strncpy( new->channel, CLA.ChannelName, sizeof( new->channel ) - 1);
579
580 /* compute start and peak time and duration, give 1 sample of fuzz on
581 * both sides */
582 new->start_time = new->peak_time = vector->epoch;
583 XLALGPSAdd(&new->peak_time, pmax * vector->deltaT);
584 XLALGPSAdd(&new->start_time, (pstart - 1) * vector->deltaT);
585 new->duration = vector->deltaT * ( pend - pstart + 2 );
586
587 new->central_freq = (strtemplate->f+CLA.fbankstart)/2.0;
588 new->bandwidth = strtemplate->f-CLA.fbankstart;
589 new->snr = maximum_snr;
590 new->amplitude = vector->data->data[pmax]/strtemplate->norm;
591 new->chisq = chi2;
592 new->chisq_dof = ndof;
593 }
594 }
595
596 return 0;
597}
598
599/*******************************************************************************/
600
601int FindStringBurst(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht, unsigned seg_length, const StringTemplate *strtemplate, int NTemplates, REAL8FFTPlan *fplan, REAL8FFTPlan *rplan, SnglBurst **head){
602 int i,m;
603 unsigned p;
605
606 /* create vector that will hold FFT of data; metadata will be populated
607 * by FFT function */
608 vtilde = XLALCreateCOMPLEX16FrequencySeries( ht->name, &ht->epoch, ht->f0, 0.0, &lalDimensionlessUnit, seg_length / 2 + 1 );
609
610 /* loop over templates */
611 for (m = 0; m < NTemplates; m++){
612 /* loop over overlapping chunks */
613 for(i=0; i < 2*(ht->data->length*ht->deltaT)/CLA.ShortSegDuration - 1 ;i++){
614 /* extract overlapping chunk of data */
615 REAL8TimeSeries *vector = XLALCutREAL8TimeSeries(ht, i * seg_length / 2, seg_length);
616
617 /* FFT it */
618 if(XLALREAL8TimeFreqFFT( vtilde, vector, fplan )) return 1;
619
620 /* multiply FT of data and String Filter */
621 for ( p = 0 ; p < vtilde->data->length; p++ )
622 vtilde->data->data[p] *= strtemplate[m].StringFilter->data->data[p];
623
624 /* reverse FFT it */
625 if(XLALREAL8FreqTimeFFT( vector, vtilde, rplan )) return 1;
626 vector->deltaT = ht->deltaT; /* gets mucked up by round-off */
627
628 /* normalise the result by template normalisation
629 factor of 2 is from match-filter definition */
630 for ( p = 0 ; p < vector->data->length; p++ )
631 vector->data->data[p] *= 2.0 / strtemplate[m].norm;
632
633 /* find triggers */
634 if(FindEvents(CLA, &strtemplate[m], vector, head)) return 1;
635
636 /*
637 if(m==10){
638 for ( int ii = 0 ; ii < vector->data->length; ii++ )
639 printf("%.3e\n",vector->data->data[ii]);
640 }
641 */
642 /* free chunk */
644 }
645 }
646
648
649 return 0;
650}
651
652
653/*******************************************************************************/
654
655int CreateStringFilters(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht, unsigned seg_length, REAL8FrequencySeries *Spec, StringTemplate *strtemplate, int NTemplates, REAL8FFTPlan *fplan, REAL8FFTPlan *rplan){
656 int m;
657 unsigned p;
658 COMPLEX16FrequencySeries *vtilde; /* frequency-domain vector workspace */
659 REAL8TimeSeries *vector; /* time-domain vector workspace */
660
661 vector = XLALCreateREAL8TimeSeries( ht->name, &ht->epoch, ht->f0, ht->deltaT, &ht->sampleUnits, seg_length );
662 vtilde = XLALCreateCOMPLEX16FrequencySeries( ht->name, &ht->epoch, ht->f0, 1.0 / (vector->data->length * vector->deltaT), &lalDimensionlessUnit, vector->data->length / 2 + 1 );
663
664 for (m = 0; m < NTemplates; m++){
665 /* Initialize the filter */
666 strtemplate[m].StringFilter = XLALCreateREAL8FrequencySeries(CLA.ChannelName, &CLA.GPSStart, 0, Spec->deltaF, &lalStrainUnit, Spec->data->length);
667
668 /* populate vtilde with the template divided by the noise */
669 for ( p = 0; p < vtilde->data->length; p++ ){
670 vtilde->data->data[p] = sqrt(strtemplate[m].waveform_f->data[p]/Spec->data->data[p]);
671 }
672
673 /* reverse FFT vtilde into vector */
674 if(XLALREAL8FreqTimeFFT( vector, vtilde, rplan )) return 1;
675 /* this gets mucked up by round-off each time through the loop */
676 vector->deltaT = ht->deltaT;
677
678 /* perform the truncation; the truncation is CLA.TruncSecs/2 because
679 we are dealing with the sqrt of the filter at the moment*/
680 if(CLA.TruncSecs != 0.0)
681 memset( vector->data->data + (int)round(CLA.TruncSecs/2/vector->deltaT), 0,
682 ( vector->data->length - 2 * (int)round(CLA.TruncSecs/2/vector->deltaT))
683 * sizeof( *vector->data->data ) );
684
685 /* forward fft the truncated vector into vtilde */
686 if(XLALREAL8TimeFreqFFT( vtilde, vector, fplan )) return 1;
687 /* this gets mucked up by round-off each time through the loop */
688 vtilde->deltaF = 1.0 / (vector->data->length * vector->deltaT);
689
690 /* store the square magnitude in the filter */
691 for ( p = 0 ; p < vtilde->data->length; p++ )
692 strtemplate[m].StringFilter->data->data[p] = creal(vtilde->data->data[p]) * creal(vtilde->data->data[p]) + cimag(vtilde->data->data[p]) * cimag(vtilde->data->data[p]);
693
694 /* set DC and Nyquist to 0 */
695 strtemplate[m].StringFilter->data->data[0] = strtemplate[m].StringFilter->data->data[strtemplate[m].StringFilter->data->length-1] = 0;
696
697 /* print out the frequency domain filter */
698 if (CLA.printfilterflag){
699 CHAR filterfilename[256];
700 snprintf(filterfilename, sizeof(filterfilename)-1, "Filter-%d.txt", m);
701 XLAL_LAST_ELEM(filterfilename) = '\0';
702 LALDPrintFrequencySeries( strtemplate[m].StringFilter, filterfilename );
703 }
704
705 /* print out the time domain FIR filter */
706 if (CLA.printfirflag){
707 char filterfilename[256];
708
709 strncpy(vector->name, "fir filter", LALNameLength);
710 for ( p = 0 ; p < vtilde->data->length; p++ ) {
711 vtilde->data->data[p] = creal(vtilde->data->data[p]) * creal(vtilde->data->data[p]) + cimag(vtilde->data->data[p]) * cimag(vtilde->data->data[p]);
712 }
713 vtilde->data->data[0] = vtilde->data->data[vtilde->data->length - 1] = 0.0;
714 XLALREAL8FreqTimeFFT( vector, vtilde, rplan );
715
716 snprintf(filterfilename, sizeof(filterfilename)-1, "FIRFilter-%d.txt", m);
717 XLAL_LAST_ELEM(filterfilename) = '\0';
718 LALDPrintTimeSeries( vector, filterfilename );
719 }
720 }
721
724
725 return 0;
726}
727
728/*******************************************************************************/
729
730/* compute (t2|t2) and (t1|t2) */
731static void compute_t2t2_and_t1t2(double power, const REAL8FrequencySeries *Spec, const REAL8Vector *integral, double last_templates_f_cut, double f_cut, double *t2t2, double *t1t2)
732{
733 unsigned i = round((last_templates_f_cut - Spec->f0) / Spec->deltaF);
734
735 *t2t2 = *t1t2 = integral->data[i];
736
737 for(i++; i < Spec->data->length; i++) {
738 double f = Spec->f0 + i * Spec->deltaF;
739
740 if(f < f_cut) {
741 *t2t2 += 4 * pow(pow(f, power), 2) / Spec->data->data[i] * Spec->deltaF;
742 *t1t2 += 4 * pow(pow(f, power), 2) * exp(1 - f / last_templates_f_cut) / Spec->data->data[i] * Spec->deltaF;
743 } else {
744 *t2t2 += 4 * pow(pow(f, power) * exp(1 - f / f_cut), 2) / Spec->data->data[i] * Spec->deltaF;
745 *t1t2 += 4 * pow(pow(f, power), 2) * exp(1 - f / last_templates_f_cut) * exp(1 - f / f_cut) / Spec->data->data[i] * Spec->deltaF;
746 }
747 }
748}
749
757};
758
759static double compute_epsilon_minus_desired(double f_cut, void *params)
760{
762 double epsilon;
763 double t1t1 = pow(p->last_templates_norm, 2);
764 double t2t2, t1t2;
765
766 compute_t2t2_and_t1t2(p->string_spectrum_power, p->Spec, p->integral, p->last_templates_f_cut, f_cut, &t2t2, &t1t2);
767
768 /* "epsilon" is the mismatch between two templates. in this case we've
769 * computed it between a template with a cut-off frequency placed at
770 * f_cut a template with a cut-off frequency placed at
771 * last_templates_f_cut */
772 epsilon = 1 - t1t2 / sqrt(t1t1 * t2t2);
773
774 /* the "desired epsilon" is the template bank mismatch provided on the
775 * command line, by writing a function that returns the difference
776 * between the measured epsilon and the value requested by the user we
777 * can use a root-solver to find the f_cut that gives the desired epsilon
778 * with repsect to the previous template */
779 return epsilon - p->desired_epsilon;
780}
781
783{
785 .desired_epsilon = desired_epsilon,
786 .string_spectrum_power = string_spectrum_power,
787 .Spec = Spec,
788 .integral = integral,
789 .last_templates_f_cut = last_templates_f_cut,
790 .last_templates_norm = last_templates_norm
791 };
792 gsl_function F = {
794 .params = &params
795 };
796 gsl_root_fsolver *solver;
797 /* we seek an f_cut bracketed by these values */
798 double flo = last_templates_f_cut;
799 double fhi = Spec->f0 + (Spec->data->length - 1) * Spec->deltaF;
800
801 /* if there isn't enough mismatch to place another template between the
802 * previous one and fhi, return fhi. note that we must ensure that the
803 * last template has exactly this frequency to cause the template
804 * construction loop to terminate */
806 return fhi;
807
808 /* iterate the bisection algorithm until fhi and flo are less than 1
809 * frequency bin apart */
810 solver = gsl_root_fsolver_alloc(gsl_root_fsolver_bisection);
811 gsl_root_fsolver_set(solver, &F, flo, fhi);
812 do {
813 gsl_root_fsolver_iterate(solver);
814 flo = gsl_root_fsolver_x_lower(solver);
815 fhi = gsl_root_fsolver_x_upper(solver);
816 } while(fhi - flo >= Spec->deltaF);
817 gsl_root_fsolver_free(solver);
818
819 /* return the mid-point as f_cut */
820 return (fhi + flo) / 2;
821}
822
823int CreateTemplateBank(struct CommandLineArgsTag CLA, unsigned seg_length, REAL8FrequencySeries *Spec, StringTemplate *strtemplate, int *NTemplates, REAL8 *fcutoff_fix, int NTemplates_fix, REAL8FFTPlan *rplan){
824 REAL8 f_cut, t1t1, t2t2, t1t2, norm, slope0, slope1;
825 int m, f_low_cutoff_index, extr_ctr;
826 unsigned p;
828 REAL8Vector *vector; /* time-domain vector workspace */
829 COMPLEX16Vector *vtilde; /* frequency-domain vector workspace */
830
831 *NTemplates = 0;
832
833 /* populate integral */
835 memset(integral->data, 0, integral->length * sizeof(*integral->data));
836 for( p = round((CLA.fbankstart - Spec->f0) / Spec->deltaF) ; p < integral->length; p++ ) {
837 integral->data[p] = 4 * pow(pow(Spec->f0 + p * Spec->deltaF, CLA.power), 2) / Spec->data->data[p] * Spec->deltaF;
838 if(p > 0)
839 integral->data[p] += integral->data[p - 1];
840 }
841
842 /* Use static template bank or...*/
843 if(CLA.TemplateFile){
844 compute_t2t2_and_t1t2(CLA.power, Spec, integral, CLA.fbankstart, fcutoff_fix[0], &t1t1, &t1t2);
845
846 strtemplate[0].findex = round((fcutoff_fix[0] - Spec->f0) / Spec->deltaF);
847 strtemplate[0].f = fcutoff_fix[0];
848 strtemplate[0].mismatch = 0.0;
849 strtemplate[0].norm = sqrt(t1t1);
850 XLALPrintInfo("%% Templ. frequency sigma mismatch\n");
851 XLALPrintInfo("%% %d %1.3e %1.3e %1.3e\n",0,strtemplate[0].f,strtemplate[0].norm, strtemplate[0].mismatch);
852 *NTemplates = NTemplates_fix;
853
854 for (m = 1; m < NTemplates_fix; m++){
855 compute_t2t2_and_t1t2(CLA.power, Spec, integral, fcutoff_fix[m-1], fcutoff_fix[m], &t2t2, &t1t2);
856
857 strtemplate[m].findex = round((fcutoff_fix[m] - Spec->f0) / Spec->deltaF);
858 strtemplate[m].f = fcutoff_fix[m];
859 strtemplate[m].norm = sqrt(t2t2);
860 strtemplate[m].mismatch = 1 - t1t2 / sqrt(t1t1 * t2t2);
861 XLALPrintInfo("%% %d %1.3e %1.3e %1.3e\n", m, strtemplate[m].f, strtemplate[m].norm, strtemplate[m].mismatch);
862 t1t1 = t2t2;
863 }
864 }
865
866 /* ... or compute an "adapted" bank */
867 else{
868 f_cut = CLA.fbankhighfcutofflow;
869
870 /* compute (t1|t1) for fist template. we can do this by re-using the
871 * (t2|t2),(t1|t2) function with the correct inputs. t1t2 result is
872 * meaningless and not used */
873 compute_t2t2_and_t1t2(CLA.power, Spec, integral, CLA.fbankstart, f_cut, &t1t1, &t1t2);
874
875 strtemplate[0].findex = round((f_cut - Spec->f0) / Spec->deltaF);
876 strtemplate[0].f = f_cut;
877 strtemplate[0].mismatch = 0.0;
878 strtemplate[0].norm = sqrt(t1t1);
879 XLALPrintInfo("%% Templ. frequency sigma mismatch\n");
880 XLALPrintInfo("%% %d %1.3e %1.3e %1.3e\n",*NTemplates,strtemplate[0].f,strtemplate[0].norm, strtemplate[0].mismatch);
881 *NTemplates = 1;
882
883 /* find the next cutoffs given the maximal mismatch, until we hit the
884 * highest frequency. note that the algorithm will hit that frequency
885 * bin by construction */
886 while(strtemplate[*NTemplates - 1].findex < (int) Spec->data->length - 1) {
887 f_cut = next_f_cut(CLA.fmismatchmax, CLA.power, Spec, integral, strtemplate[*NTemplates-1].f, strtemplate[*NTemplates-1].norm);
888
889 compute_t2t2_and_t1t2(CLA.power, Spec, integral, strtemplate[*NTemplates-1].f, f_cut, &t2t2, &t1t2);
890
891 strtemplate[*NTemplates].findex = round((f_cut - Spec->f0) / Spec->deltaF);
892 strtemplate[*NTemplates].f = f_cut;
893 strtemplate[*NTemplates].norm = sqrt(t2t2);
894 strtemplate[*NTemplates].mismatch = 1 - t1t2 / sqrt(t1t1 * t2t2);
895 XLALPrintInfo("%% %d %1.3e %1.3e %1.3e\n", *NTemplates, strtemplate[*NTemplates].f, strtemplate[*NTemplates].norm, strtemplate[*NTemplates].mismatch);
896 (*NTemplates)++;
897 if(*NTemplates == MAXTEMPLATES){
898 XLALPrintError("Too many templates for code... Exiting\n");
899 return 1;
900 }
901 t1t1 = t2t2;
902 }
903 }
904
906
907 /* Now, the point is to store the template waveform vector */
908 vector = XLALCreateREAL8Vector( seg_length);
909 vtilde = XLALCreateCOMPLEX16Vector( vector->length / 2 + 1 );
910 f_low_cutoff_index = round(CLA.fbankstart/ Spec->deltaF);
911 for (m = 0; m < *NTemplates; m++){
912 /* create the space for the waveform vectors */
913 strtemplate[m].waveform_f = XLALCreateCOMPLEX16Vector( vtilde->length );
914 strtemplate[m].waveform_t = XLALCreateREAL8Vector( vector->length );
915 strtemplate[m].auto_cor = XLALCreateREAL8Vector( vector->length );
916
917 /* set all frequencies below the low freq cutoff to zero */
918 memset(strtemplate[m].waveform_f->data, 0, f_low_cutoff_index*sizeof(*strtemplate[m].waveform_f->data));
919
920 /* populate the rest with the template waveform */
921 for ( p = f_low_cutoff_index; p < strtemplate[m].waveform_f->length; p++ ){
922 double f = Spec->f0 + p * Spec->deltaF;
923 if(f<=strtemplate[m].f)
924 strtemplate[m].waveform_f->data[p] = pow(f, CLA.power);
925 else
926 strtemplate[m].waveform_f->data[p] = pow(f, CLA.power)*exp(1-f/strtemplate[m].f);
927 }
928
929 /* set DC and Nyquist to zero */
930 strtemplate[m].waveform_f->data[0] = strtemplate[m].waveform_f->data[strtemplate[m].waveform_f->length - 1] = 0.0;
931
932 /* whiten and convolve the template with itself, store in vtilde.
933 * template is assumed to be real-valued */
934 for (p=0 ; p< vtilde->length; p++)
935 vtilde->data[p] = pow(creal(strtemplate[m].waveform_f->data[p]), 2) / Spec->data->data[p];
936
937 /* reverse FFT */
938 if(XLALREAL8ReverseFFT(vector, strtemplate[m].waveform_f, rplan)) return 1;
939 if(XLALREAL8ReverseFFT(strtemplate[m].auto_cor, vtilde, rplan)) return 1;
940
941 /* The vector is reshuffled in the right order */
942 for ( p = 0 ; p < vector->length / 2; p++ ){
943 strtemplate[m].waveform_t->data[p] = vector->data[vector->length/2+p]*Spec->deltaF;
944 strtemplate[m].waveform_t->data[vector->length/2+p] = vector->data[p]*Spec->deltaF;
945 }
946
947 /* Normalize the autocorrelation by the central value */
948 norm=strtemplate[m].auto_cor->data[0];
949 for ( p = 0 ; p < strtemplate[m].auto_cor->length; p++ )
950 strtemplate[m].auto_cor->data[p] /= norm;
951
952 /* The vector is reshuffled in the right order */
953 memcpy(vector->data, strtemplate[m].auto_cor->data, vector->length * sizeof(*vector->data));
954 for ( p = 0 ; p < vector->length/2; p++ ){
955 strtemplate[m].auto_cor->data[p] = vector->data[vector->length/2+p];
956 strtemplate[m].auto_cor->data[vector->length/2+p] = vector->data[p];
957 }
958
959 /* search for the index of the 3rd extremum */
960 extr_ctr=0;
961 strtemplate[m].chi2_index=0;
962 for ( p = strtemplate[m].waveform_t->length/2+1; p< strtemplate[m].waveform_t->length-1; p++ ){
963 slope1 = strtemplate[m].waveform_t->data[p+1]-strtemplate[m].waveform_t->data[p];
964 slope0 = strtemplate[m].waveform_t->data[p]-strtemplate[m].waveform_t->data[p-1];
965 strtemplate[m].chi2_index++;
966 if(slope0*slope1<0){
967 extr_ctr++;
968 if(extr_ctr==2) break;
969 }
970 }
971 }
972
975
976 return 0;
977}
978
979
980/*******************************************************************************/
981REAL8FrequencySeries *AvgSpectrum(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht, unsigned seg_length, REAL8FFTPlan *fplan){
983 Spec = XLALCreateREAL8FrequencySeries(CLA.ChannelName, &CLA.GPSStart, 0, 0, &lalStrainUnit, seg_length / 2 + 1);
984 if(!Spec)
986
987 if (CLA.fakenoiseflag && CLA.whitespectrumflag){
988 unsigned p;
989 for ( p = 0 ; p < Spec->data->length; p++ )
990 /* FIXME: shouldn't this be 2 * \Delta f */
991 Spec->data->data[p]=2/(1.0/ht->deltaT);
992 Spec->deltaF=1/(seg_length*ht->deltaT);
993 } else{
994 unsigned segmentStride = seg_length/2;
995 REAL8Window *window = XLALCreateHannREAL8Window( seg_length );
996 if(!window)
998
999 if(XLALREAL8AverageSpectrumMedianMean( Spec, ht, seg_length, segmentStride, window, fplan ))
1001
1002 XLALDestroyREAL8Window( window );
1003 }
1004
1005 return Spec;
1006}
1007
1008/*******************************************************************************/
1009
1011 if(XLALResampleREAL8TimeSeries(ht, 1.0/CLA.samplerate)) return 1;
1012 return 0;
1013}
1014
1015/*******************************************************************************/
1016
1018 unsigned p;
1019 REAL8TimeSeries *ht = NULL;
1020
1021 if(CLA.fakenoiseflag) {
1022 /* create random data set */
1023 gsl_rng *rng = gsl_rng_alloc(gsl_rng_mt19937);
1024 FILE *devrandom;
1025 int errorcode;
1026 unsigned long seed;
1027
1028 if(!(devrandom=fopen("/dev/urandom","r"))){
1029 XLALPrintError("Unable to open device /dev/urandom\n");
1030 return NULL;
1031 }
1032 errorcode=fread(&seed, sizeof(seed), 1, devrandom);
1033 if(errorcode!=1){
1034 XLALPrintError("Error reading /dev/urandom file!\n");
1035 return NULL;
1036 }
1037 fclose(devrandom);
1038 gsl_rng_set(rng, seed);
1039
1040 /* hard-code sample rate of simulated noise to 16384 Hz */
1041 ht = XLALCreateREAL8TimeSeries("white noise", &CLA.GPSStart, 0.0, 1.0 / 16384, &lalDimensionlessUnit, XLALGPSDiff(&CLA.GPSEnd, &CLA.GPSStart) * 16384);
1042 for(p = 0; p < ht->data->length; p++)
1043 ht->data->data[p] = gsl_ran_gaussian(rng, 1.0);
1044 gsl_rng_free(rng);
1045 } else {
1046 LALCache *cache;
1047 LALFrStream *stream;
1048 LALTYPECODE series_type;
1049
1050 /* create Frame cache, open frame stream and delete frame cache */
1051 cache = XLALCacheImport(CLA.FrCacheFile);
1052 if(!cache)
1054 stream = XLALFrStreamCacheOpen(cache);
1056 if(!stream)
1058
1059 /* turn on checking for missing data */
1061
1062 /* get the data type */
1063 series_type = XLALFrStreamGetTimeSeriesType(CLA.ChannelName, stream);
1064 if((int) series_type < 0) {
1065 XLALFrStreamClose(stream);
1067 }
1068
1069 /* read data */
1070 switch(series_type) {
1071 case LAL_S_TYPE_CODE: {
1072 /* read single-precision data */
1073 REAL4TimeSeries *ht_V = XLALFrStreamReadREAL4TimeSeries(stream, CLA.ChannelName, &CLA.GPSStart, XLALGPSDiff(&CLA.GPSEnd, &CLA.GPSStart), 0);
1074 if(!ht_V) {
1075 XLALFrStreamClose(stream);
1077 }
1078
1079 /* cast to double precision */
1081 if(!ht) {
1082 XLALFrStreamClose(stream);
1084 }
1085
1086 /* clean up */
1088 break;
1089 }
1090
1091 case LAL_D_TYPE_CODE:
1092 /* read double-precision data */
1093 ht = XLALFrStreamReadREAL8TimeSeries(stream, CLA.ChannelName, &CLA.GPSStart, XLALGPSDiff(&CLA.GPSEnd, &CLA.GPSStart), 0);
1094 if(!ht) {
1095 XLALFrStreamClose(stream);
1097 }
1098 break;
1099
1100 default:
1101 XLALFrStreamClose(stream);
1103 }
1104
1105 /* close */
1106 XLALFrStreamClose(stream);
1107
1108 /* FIXME: ARGH!!! frame files cannot be trusted to provide units for
1109 * their contents! */
1111 }
1112
1113 return ht;
1114}
1115
1116/*******************************************************************************/
1117
1118int ReadTemplateFile(struct CommandLineArgsTag CLA, int *NTemplates_fix, REAL8 *fcutoff_fix){
1119
1120 SnglBurst *templates=NULL, *templates_root=NULL;
1121 int i;
1122
1123 /* Initialize */
1124 *NTemplates_fix=0;
1125
1126 /* Get templates from burst table */
1127 templates_root = XLALSnglBurstTableFromLIGOLw(CLA.TemplateFile);
1128
1129 for(templates = templates_root; templates != NULL; templates = templates->next){
1130 fcutoff_fix[*NTemplates_fix]=templates->central_freq + (templates->bandwidth)/2;
1131 *NTemplates_fix=*NTemplates_fix+1;
1132 if(*NTemplates_fix==MAXTEMPLATES){
1133 XLALPrintError("Too many templates (> %d)\n",MAXTEMPLATES);
1134 return 1;
1135 }
1136 }
1137
1138 /* Check that the bank has at least one template */
1139 if(*NTemplates_fix<=0){
1140 XLALPrintError("Empty template bank\n");
1141 return 1;
1142 }
1143
1144 /* Check that the frequencies are well ordered */
1145 for(i=0; i<*NTemplates_fix-1; i++){
1146 if(fcutoff_fix[i]>fcutoff_fix[i+1]){
1147 XLALPrintError("The templates frequencies are not sorted by frequencies\n");
1148 return 1;
1149 }
1150 }
1151
1152 /* check that the highest frequency is below the Nyquist frequency */
1153 if(fcutoff_fix[*NTemplates_fix-1]>CLA.samplerate/2){
1154 XLALPrintError("The templates frequencies go beyond the Nyquist frequency\n");
1155 return 1;
1156 }
1157
1158 return 0;
1159}
1160
1161/*******************************************************************************/
1162
1163int ReadCommandLine(int argc,char *argv[],struct CommandLineArgsTag *CLA, const ProcessTable *process, ProcessParamsTable **paramaddpoint){
1164 static char default_comment[] = "";
1165 INT4 errflg = 0;
1166 struct LALoption long_options[] = {
1167 {"bank-freq-start", required_argument, NULL, 'L'},
1168 {"bank-lowest-hifreq-cutoff", required_argument, NULL, 'H'},
1169 {"max-mismatch", required_argument, NULL, 'M'},
1170 {"threshold", required_argument, NULL, 't'},
1171 {"frame-cache", required_argument, NULL, 'F'},
1172 {"channel", required_argument, NULL, 'C'},
1173 {"output", required_argument, NULL, 'o'},
1174 {"gps-end-time", required_argument, NULL, 'E'},
1175 {"gps-start-time", required_argument, NULL, 'S'},
1176 {"injection-file", required_argument, NULL, 'i'},
1177 {"short-segment-duration", required_argument, NULL, 'd'},
1178 {"settling-time", required_argument, NULL, 'T'},
1179 {"sample-rate", required_argument, NULL, 's'},
1180 {"trig-start-time", required_argument, NULL, 'g'},
1181 {"pad", required_argument, NULL, 'p'},
1182 {"chi2par0", required_argument, NULL, 'A'},
1183 {"chi2par1", required_argument, NULL, 'B'},
1184 {"chi2par2", required_argument, NULL, 'G'},
1185 {"template-bank", required_argument, NULL, 'K'},
1186 {"cusp-search", no_argument, NULL, 'c'},
1187 {"kink-search", no_argument, NULL, 'k'},
1188 {"test-gaussian-data", no_argument, NULL, 'n'},
1189 {"test-white-spectrum", no_argument, NULL, 'w'},
1190 {"cluster-events", required_argument, NULL, 'l'},
1191 {"print-spectrum", no_argument, NULL, 'a'},
1192 {"print-fd-filter", no_argument, NULL, 'b'},
1193 {"print-snr", no_argument, NULL, 'r'},
1194 {"print-td-filter", no_argument, NULL, 'x'},
1195 {"print-data", no_argument, NULL, 'y'},
1196 {"print-injection", no_argument, NULL, 'z'},
1197 {"user-tag", required_argument, NULL, 'j'},
1198 {"help", no_argument, NULL, 'h'},
1199 {0, 0, 0, 0}
1200 };
1201 char args[] = "hnckwabrxyzlj:f:L:M:D:H:t:F:C:E:S:i:v:d:T:s:g:o:p:A:B:G:K:";
1202
1203 LALoptarg = NULL;
1204
1205 /* Initialize default values */
1206 CLA->fbankstart=0.0;
1207 CLA->fbankhighfcutofflow=0.0;
1208 CLA->fmismatchmax=0.05;
1209 CLA->FrCacheFile=NULL;
1210 CLA->InjectionFile=NULL;
1211 CLA->TemplateFile=NULL;
1212 CLA->ChannelName=NULL;
1213 CLA->outputFileName=NULL;
1214 XLALINT8NSToGPS(&CLA->GPSStart, 0);
1215 XLALINT8NSToGPS(&CLA->GPSEnd, 0);
1216 CLA->ShortSegDuration=0;
1217 CLA->TruncSecs=0;
1218 CLA->power=0.0;
1219 CLA->threshold=0.0;
1220 CLA->fakenoiseflag=0;
1221 CLA->whitespectrumflag=0;
1222 CLA->samplerate=4096.0;
1223 XLALINT8NSToGPS(&CLA->trigstarttime, 0);
1224 CLA->cluster=0.0;
1225 CLA->pad=0;
1226 CLA->printfilterflag=0;
1227 CLA->printspectrumflag=0;
1228 CLA->printsnrflag=0;
1229 CLA->printfirflag=0;
1230 CLA->printdataflag=0;
1231 CLA->printinjectionflag=0;
1232 CLA->comment=default_comment;
1233
1234 /* initialise chi2cut */
1235 memset(CLA->chi2cut, 0, sizeof(CLA->chi2cut));
1236 CLA->chi2cut[0]=CLA->chi2cut[1]=CLA->chi2cut[2]=-9999.1;
1237
1238 /* Scan through list of command line arguments */
1239 while ( 1 )
1240 {
1241 int option_index = 0; /* LALgetopt_long stores long option here */
1242 int c;
1243
1244 c = LALgetopt_long_only( argc, argv, args, long_options, &option_index );
1245 if ( c == -1 ) /* end of options */
1246 break;
1247
1248 switch ( c )
1249 {
1250 case 's':
1251 /* resample to this sample rate */
1252 CLA->samplerate=atof(LALoptarg);
1253 ADD_PROCESS_PARAM(process, "float");
1254 break;
1255 case 'H':
1256 /* lowest high frequency cutoff */
1257 CLA->fbankhighfcutofflow=atof(LALoptarg);
1258 ADD_PROCESS_PARAM(process, "float");
1259 break;
1260 case 'M':
1261 /* Maximal mismatch */
1262 CLA->fmismatchmax=atof(LALoptarg);
1263 ADD_PROCESS_PARAM(process, "float");
1264 break;
1265 case 'L':
1266 /* low frequency cutoff */
1267 CLA->fbankstart=atof(LALoptarg);
1268 ADD_PROCESS_PARAM(process, "float");
1269 break;
1270 case 't':
1271 /* low frequency cutoff */
1272 CLA->threshold=atof(LALoptarg);
1273 ADD_PROCESS_PARAM(process, "float");
1274 break;
1275 case 'F':
1276 /* name of frame cache file */
1277 CLA->FrCacheFile=LALoptarg;
1278 ADD_PROCESS_PARAM(process, "string");
1279 break;
1280 case 'C':
1281 /* name channel */
1282 CLA->ChannelName=LALoptarg;
1283 ADD_PROCESS_PARAM(process, "string");
1284 break;
1285 case 'i':
1286 /* name of xml injection file */
1287 CLA->InjectionFile=LALoptarg;
1288 ADD_PROCESS_PARAM(process, "string");
1289 break;
1290 case 'K':
1291 /* name of txt template file */
1292 CLA->TemplateFile=LALoptarg;
1293 ADD_PROCESS_PARAM(process, "string");
1294 break;
1295 case 'o':
1296 /* name of xml injection file */
1297 CLA->outputFileName=LALoptarg;
1298 ADD_PROCESS_PARAM(process, "string");
1299 break;
1300 case 'S':
1301 /* GPS start time of search */
1302 if(XLALStrToGPS(&CLA->GPSStart, LALoptarg, NULL)) {
1303 fprintf(stderr,"range error parsing \"%s\"", LALoptarg);
1304 return 1;
1305 }
1306 ADD_PROCESS_PARAM(process, "string");
1307 break;
1308 case 'E':
1309 /* GPS end time time of search */
1310 if(XLALStrToGPS(&CLA->GPSEnd, LALoptarg, NULL)) {
1311 fprintf(stderr,"range error parsing \"%s\"", LALoptarg);
1312 return 1;
1313 }
1314 ADD_PROCESS_PARAM(process, "string");
1315 break;
1316 case 'd':
1317 /* Number of segment to break-up search into */
1318 CLA->ShortSegDuration=atoi(LALoptarg);
1319 ADD_PROCESS_PARAM(process, "int");
1320 break;
1321 case 'T':
1322 /* Half the number of seconds that are trown out at the start and at the end of a short chunk */
1323 CLA->TruncSecs=atof(LALoptarg);
1324 ADD_PROCESS_PARAM(process, "int");
1325 break;
1326 case 'g':
1327 /* start time of allowed triggers */
1328 if(XLALStrToGPS(&CLA->trigstarttime, LALoptarg, NULL)) {
1329 fprintf(stderr,"range error parsing \"%s\"", LALoptarg);
1330 return 1;
1331 }
1332 ADD_PROCESS_PARAM(process, "string");
1333 break;
1334 case 'p':
1335 /* start time of allowed triggers */
1336 CLA->pad=atoi(LALoptarg);
1337 ADD_PROCESS_PARAM(process, "int");
1338 break;
1339 case 'A':
1340 /* chi2 cut parameter 0 */
1341 CLA->chi2cut[0]=atof(LALoptarg);
1342 ADD_PROCESS_PARAM(process, "float");
1343 break;
1344 case 'B':
1345 /* chi2 cut parameter 1 */
1346 CLA->chi2cut[1]=atof(LALoptarg);
1347 ADD_PROCESS_PARAM(process, "float");
1348 break;
1349 case 'G':
1350 /* chi2 cut parameter 2 */
1351 CLA->chi2cut[2]=atof(LALoptarg);
1352 ADD_PROCESS_PARAM(process, "float");
1353 break;
1354 case 'c':
1355 /* cusp power law */
1356 CLA->power=-4.0/3.0;
1357 ADD_PROCESS_PARAM(process, "string");
1358 break;
1359 case 'k':
1360 /* kink power law */
1361 CLA->power=-5.0/3.0;
1362 ADD_PROCESS_PARAM(process, "string");
1363 break;
1364 case 'n':
1365 /* fake gaussian noise flag */
1366 CLA->fakenoiseflag=1;
1367 ADD_PROCESS_PARAM(process, "string");
1368 break;
1369 case 'w':
1370 /* fake gaussian noise flag */
1371 CLA->whitespectrumflag=1;
1372 ADD_PROCESS_PARAM(process, "string");
1373 break;
1374 case 'l':
1375 /* fake gaussian noise flag */
1376 CLA->cluster=atof(LALoptarg);
1377 ADD_PROCESS_PARAM(process, "string");
1378 break;
1379 case 'a':
1380 /* fake gaussian noise flag */
1381 CLA->printspectrumflag=1;
1382 ADD_PROCESS_PARAM(process, "string");
1383 break;
1384 case 'b':
1385 /* fake gaussian noise flag */
1386 CLA->printfilterflag=1;
1387 ADD_PROCESS_PARAM(process, "string");
1388 break;
1389 case 'j':
1390 /* --user-tag */
1391 CLA->comment = LALoptarg;
1392 ADD_PROCESS_PARAM(process, "string");
1393 break;
1394 case 'r':
1395 /* fake gaussian noise flag */
1396 CLA->printsnrflag=1;
1397 ADD_PROCESS_PARAM(process, "string");
1398 break;
1399 case 'x':
1400 /* fake gaussian noise flag */
1401 CLA->printfirflag=1;
1402 ADD_PROCESS_PARAM(process, "string");
1403 break;
1404 case 'y':
1405 /* fake gaussian noise flag */
1406 CLA->printdataflag=1;
1407 ADD_PROCESS_PARAM(process, "string");
1408 break;
1409 case 'z':
1410 /* fake gaussian noise flag */
1411 CLA->printinjectionflag=1;
1412 ADD_PROCESS_PARAM(process, "string");
1413 break;
1414 case 'h':
1415 /* print usage/help message */
1416 fprintf(stdout,"All arguments are required except -n, -h, -w, -g, -o, -x, -y, -z, -b, -r -a, -l, -p, -T and -i. One of -k or -c must be specified. They are:\n");
1417 fprintf(stdout,"\t--sample-rate (-s)\t\tFLOAT\t Desired sample rate (Hz).\n");
1418 fprintf(stdout,"\t--bank-lowest-hifreq-cutoff (-H)\tFLOAT\t Template bank lowest high frequency cut-off.\n");
1419 fprintf(stdout,"\t--max-mismatch (-M)\tFLOAT\t Maximal mismatch allowed from 1 template to the next.\n");
1420 fprintf(stdout,"\t--bank-freq-start (-L)\tFLOAT\t Template bank low frequency cut-off.\n");
1421 fprintf(stdout,"\t--threshold (-t)\t\tFLOAT\t SNR threshold.\n");
1422 fprintf(stdout,"\t--frame-cache (-F)\t\tSTRING\t Name of frame cache file.\n");
1423 fprintf(stdout,"\t--channel (-C)\t\tSTRING\t Name of channel.\n");
1424 fprintf(stdout,"\t--injection-file (-i)\t\tSTRING\t Name of xml injection file.\n");
1425 fprintf(stdout,"\t--template-bank (-K)\t\tSTRING\t Name of txt template file.\n");
1426 fprintf(stdout,"\t--output (-o)\t\tSTRING\t Name of xml output file.\n");
1427 fprintf(stdout,"\t--gps-start-time (-S)\t\tINTEGER\t GPS start time.\n");
1428 fprintf(stdout,"\t--gps-end-time (-E)\t\tINTEGER\t GPS end time.\n");
1429 fprintf(stdout,"\t--settling-time (-T)\t\tINTEGER\t Number of seconds to truncate filter.\n");
1430 fprintf(stdout,"\t--trig-start-time (-g)\t\tINTEGER\t GPS start time of triggers to consider.\n");
1431 fprintf(stdout,"\t--pad (-p)\t\tINTEGER\t Pad the data with these many seconds at beginning and end.\n");
1432 fprintf(stdout,"\t--chi2par0 (-A)\t\tFLOAT\t parameter[0] for the chi2 selection.\n");
1433 fprintf(stdout,"\t--chi2par1 (-B)\t\tFLOAT\t parameter[1] for the chi2 selection.\n");
1434 fprintf(stdout,"\t--chi2par2 (-G)\t\tFLOAT\t parameter[2] for the chi2 selection.\n");
1435 fprintf(stdout,"\t--short-segment-duration (-d)\t\tINTEGER\t Duration of short segments. They will overlap by 50%s. \n","%");
1436 fprintf(stdout,"\t--kink-search (-k)\t\tFLAG\t Specifies a search for string kinks.\n");
1437 fprintf(stdout,"\t--cusp-search (-c)\t\tFLAG\t Specifies a search for string cusps.\n");
1438 fprintf(stdout,"\t--test-gaussian-data (-n)\tFLAG\t Use unit variance fake gaussian noise.\n");
1439 fprintf(stdout,"\t--test-white-spectrum (-w)\tFLAG\t Use constant white noise (used only in combination with fake gaussian noise; otherwise ignored).\n");
1440 fprintf(stdout,"\t--cluster-events (-l)\tREAL4\t Cluster events with input timescale.\n");
1441 fprintf(stdout,"\t--print-spectrum (-a)\tFLAG\t Prints the spectrum to Spectrum.txt.\n");
1442 fprintf(stdout,"\t--print-fd-filter (-b)\tFLAG\t Prints the frequency domain filter to Filter-<template no>.txt.\n");
1443 fprintf(stdout,"\t--print-td-filter (-r)\tFLAG\t Prints the time domain filter to FIRFilter-<template no>.txt.\n");
1444 fprintf(stdout,"\t--print-snr (-x)\tFLAG\t Prints the snr to stdout.\n");
1445 fprintf(stdout,"\t--print-data (-y)\tFLAG\t Prints the post-processed (HP filtered, downsampled, padding removed, with injections) data to data.txt.\n");
1446 fprintf(stdout,"\t--print-injection (-z)\tFLAG\t Prints the injeciton data to injection.txt.\n");
1447 fprintf(stdout,"\t--help (-h)\t\t\tFLAG\t Print this message.\n");
1448 fprintf(stdout,"eg %s --sample-rate 4096 --bank-freq-start 30 --bank-lowest-hifreq-cutoff 200 --settling-time 0.1 --short-segment-duration 4 --cusp-search --cluster-events 0.1 --pad 4 --threshold 4 --output ladida.xml --frame-cache cache/H-H1_RDS_C01_LX-795169179-795171015.cache --channel H1:LSC-STRAIN --gps-start-time 795170318 --gps-end-time 795170396\n", argv[0]);
1449 exit(0);
1450 break;
1451 default:
1452 /* unrecognized option */
1453 errflg++;
1454 fprintf(stderr,"Unrecognized option argument %c\n",c);
1455 exit(1);
1456 break;
1457 }
1458 }
1459
1460 if(CLA->fbankstart == 0.0)
1461 {
1462 fprintf(stderr,"No low frequency for frequency bank specified.\n");
1463 fprintf(stderr,"Try %s -h \n",argv[0]);
1464 return 1;
1465 }
1466 if(! CLA->TemplateFile && CLA->fbankhighfcutofflow == 0.0)
1467 {
1468 fprintf(stderr,"No template bank lowest high frequency cutoff specified.\n");
1469 fprintf(stderr,"Try %s -h \n",argv[0]);
1470 return 1;
1471 }
1472 if(CLA->threshold == 0.0)
1473 {
1474 fprintf(stderr,"No SNR threshold specified.\n");
1475 fprintf(stderr,"Try %s -h \n",argv[0]);
1476 return 1;
1477 }
1478 if(CLA->power == 0.0)
1479 {
1480 fprintf(stderr,"Cusp or kink search not specified. \n");
1481 fprintf(stderr,"Try %s -h \n",argv[0]);
1482 return 1;
1483 }
1484 if(CLA->FrCacheFile == NULL)
1485 {
1486 fprintf(stderr,"No frame cache file specified.\n");
1487 fprintf(stderr,"Try %s -h \n",argv[0]);
1488 return 1;
1489 }
1490 if(CLA->ChannelName == NULL)
1491 {
1492 fprintf(stderr,"No channel name specified.\n");
1493 fprintf(stderr,"Try %s -h \n",argv[0]);
1494 return 1;
1495 }
1496 if(!(CLA->ChannelName[0] == 'V' || CLA->ChannelName[0] == 'H' || CLA->ChannelName[0] == 'L'))
1497 {
1498 fprintf(stderr,"The channel name is not well specified\n");
1499 fprintf(stderr,"It should start with H1, H2, L1 or V1\n");
1500 fprintf(stderr,"Try %s -h \n",argv[0]);
1501 return 1;
1502 }
1503 if(XLALGPSToINT8NS(&CLA->GPSStart) == 0)
1504 {
1505 fprintf(stderr,"No GPS start time specified.\n");
1506 fprintf(stderr,"Try %s -h \n",argv[0]);
1507 return 1;
1508 }
1509 if(CLA->GPSStart.gpsNanoSeconds)
1510 {
1511 fprintf(stderr,"Only integer values allowed for --gps-start-time.\n");
1512 return 1;
1513 }
1514 if(XLALGPSToINT8NS(&CLA->GPSEnd) == 0)
1515 {
1516 fprintf(stderr,"No GPS end time specified.\n");
1517 fprintf(stderr,"Try %s -h \n",argv[0]);
1518 return 1;
1519 }
1520 if(CLA->GPSEnd.gpsNanoSeconds)
1521 {
1522 fprintf(stderr,"Only integer values allowed for --gps-end-time.\n");
1523 return 1;
1524 }
1525 if(CLA->ShortSegDuration == 0)
1526 {
1527 fprintf(stderr,"Short segment duration not specified (they overlap by 50%s).\n","%");
1528 fprintf(stderr,"Try %s -h \n",argv[0]);
1529 return 1;
1530 }
1531
1532 /* Some consistency checking */
1533 {
1534 int big_seg_length=XLALGPSDiff(&CLA->GPSEnd, &CLA->GPSStart)-2*CLA->pad;
1535
1536 REAL4 x=((float)big_seg_length/(float)CLA->ShortSegDuration)-0.5;
1537
1538 if((int)x != x){
1539 fprintf(stderr,"The total duration of the segment T and the short segment duration\n");
1540 fprintf(stderr,"Should obey the following rule: T/t - 0.5 shold be an odd integer.\n");
1541 return 1;
1542 }
1543 if(((int)x)%2 != 1){
1544 fprintf(stderr,"The total duration of the segment T and the short segment duration\n");
1545 fprintf(stderr,"Should obey the following rule: T/t - 0.5 shold be an odd integer.\n");
1546 return 1;
1547 }
1548
1549 if( CLA->ShortSegDuration/4.0 < CLA->TruncSecs){
1550 fprintf(stderr,"Short segment length t=%d is too small to accomodate truncation time requested.\n", CLA->ShortSegDuration);
1551 fprintf(stderr,"Need short segment t(=%d) to be >= 4 x Truncation length (%f).\n",CLA->ShortSegDuration,CLA->TruncSecs);
1552 return 1;
1553 }
1554 }
1555
1556 return errflg;
1557}
1558
1559/*******************************************************************************/
1560
1561int FreeMem(StringTemplate *strtemplate, int NTemplates){
1562 int m;
1563
1564 for (m=0; m < NTemplates; m++)
1565 XLALDestroyREAL8FrequencySeries(strtemplate[m].StringFilter);
1566
1568
1569 return 0;
1570}
1571
1572/*******************************************************************************/
int XLALStrToGPS(LIGOTimeGPS *t, const char *nptr, char **endptr)
const LALVCSInfo lalAppsVCSIdentInfo
Identable VCS and build information for LALApps.
void LALCheckMemoryLeaks(void)
int LALgetopt_long_only(int argc, char *const *argv, const char *options, const struct LALoption *long_options, int *opt_index)
char * LALoptarg
#define no_argument
#define required_argument
int XLALCloseLIGOLwXMLFile(LIGOLwXMLStream *xml)
LIGOLwXMLStream * XLALOpenLIGOLwXMLFile(const char *path)
int XLALWriteLIGOLwXMLSnglBurstTable(LIGOLwXMLStream *, const SnglBurst *)
int XLALWriteLIGOLwXMLProcessTable(LIGOLwXMLStream *, const ProcessTable *)
int XLALWriteLIGOLwXMLProcessParamsTable(LIGOLwXMLStream *, const ProcessParamsTable *)
int XLALWriteLIGOLwXMLSearchSummaryTable(LIGOLwXMLStream *, const SearchSummaryTable *)
SnglBurst * XLALSnglBurstTableFromLIGOLw(const char *filename)
TimeSlide * XLALTimeSlideTableFromLIGOLw(const char *filename)
SimBurst * XLALSimBurstTableFromLIGOLw(const char *filename)
#define LIGOMETA_IFOS_MAX
#define LIGOMETA_TYPE_MAX
#define LIGOMETA_PROGRAM_MAX
#define LIGOMETA_VALUE_MAX
#define LIGOMETA_PARAM_MAX
void XLALDestroyProcessParamsTable(ProcessParamsTable *)
SearchSummaryTable * XLALCreateSearchSummaryTableRow(const ProcessTable *)
void XLALDestroyTimeSlideTable(TimeSlide *)
void XLALDestroySimBurstTable(SimBurst *head)
ProcessTable * XLALCreateProcessTableRow(void)
void XLALDestroyProcessTable(ProcessTable *)
int XLALPopulateProcessTable(ProcessTable *ptable, const char *program_name, const char *cvs_revision, const char *cvs_source, const char *cvs_date, long process_id)
ProcessParamsTable * XLALCreateProcessParamsTableRow(const ProcessTable *)
void XLALDestroySearchSummaryTable(SearchSummaryTable *)
SnglBurst * XLALCreateSnglBurst(void)
void XLALDestroySnglBurstTable(SnglBurst *head)
long XLALSnglBurstAssignIDs(SnglBurst *head, long process_id, long event_id)
SnglBurst * XLALDestroySnglBurst(SnglBurst *event)
struct CommandLineArgsTag CommandLineArgs
int XLALSnglBurstTableLength(SnglBurst *head)
int XLALCompareSnglBurstByPeakTimeAndSNR(const SnglBurst *const *a, const SnglBurst *const *b)
SnglBurst ** XLALSortSnglBurst(SnglBurst **head, int(*comparefunc)(const SnglBurst *const *, const SnglBurst *const *))
#define fprintf
int DownSample(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht)
#define MAXTEMPLATES
Definition: StringSearch.c:82
int main(int argc, char *argv[])
Definition: StringSearch.c:197
static void XLALStringBurstCluster(SnglBurst *, const SnglBurst *)
cluster events a and b, storing result in a; takes one with largest snr
Definition: StringSearch.c:351
#define ADD_PROCESS_PARAM(process, type)
Definition: StringSearch.c:453
int FindStringBurst(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht, unsigned seg_length, const StringTemplate *strtemplate, int NTemplates, REAL8FFTPlan *fplan, REAL8FFTPlan *rplan, SnglBurst **head)
Definition: StringSearch.c:601
#define PROGRAM_NAME
Definition: StringSearch.c:87
int CreateTemplateBank(struct CommandLineArgsTag CLA, unsigned seg_length, REAL8FrequencySeries *Spec, StringTemplate *strtemplate, int *NTemplates, REAL8 *fcutoff_fix, int NTemplates_fix, REAL8FFTPlan *rplan)
Definition: StringSearch.c:823
static ProcessParamsTable ** add_process_param(ProcessParamsTable **proc_param, const ProcessTable *process, const char *type, const char *param, const char *value)
Definition: StringSearch.c:441
static int XLALCompareStringBurstByTime(const SnglBurst *const *, const SnglBurst *const *)
Definition: StringSearch.c:332
int FreeMem(StringTemplate *strtemplate, int NTemplates)
REAL8TimeSeries * ReadData(struct CommandLineArgsTag CLA)
static double compute_epsilon_minus_desired(double f_cut, void *params)
Definition: StringSearch.c:759
int ReadTemplateFile(struct CommandLineArgsTag CLA, int *NTemplates_fix, REAL8 *fcutoff_fix)
REAL8FrequencySeries * AvgSpectrum(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht, unsigned seg_length, REAL8FFTPlan *fplan)
Definition: StringSearch.c:981
static double cluster_window
Definition: StringSearch.c:144
int ReadCommandLine(int argc, char *argv[], struct CommandLineArgsTag *CLA, const ProcessTable *process, ProcessParamsTable **paramaddpoint)
static void XLALClusterSnglBurstTable(SnglBurst **, int(*)(const SnglBurst *const *, const SnglBurst *const *), int(*)(const SnglBurst *const *, const SnglBurst *const *), void(*)(SnglBurst *, const SnglBurst *))
Recursively cluster a linked list of SnglBurst events until the list stops changing.
Definition: StringSearch.c:372
int OutputEvents(const struct CommandLineArgsTag *CLA, ProcessTable *proctable, ProcessParamsTable *procparamtable, SnglBurst *events)
Definition: StringSearch.c:458
int CreateStringFilters(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht, unsigned seg_length, REAL8FrequencySeries *Spec, StringTemplate *strtemplate, int NTemplates, REAL8FFTPlan *fplan, REAL8FFTPlan *rplan)
Definition: StringSearch.c:655
static void compute_t2t2_and_t1t2(double power, const REAL8FrequencySeries *Spec, const REAL8Vector *integral, double last_templates_f_cut, double f_cut, double *t2t2, double *t1t2)
Definition: StringSearch.c:731
int AddInjections(struct CommandLineArgsTag CLA, REAL8TimeSeries *ht)
Definition: StringSearch.c:406
static double next_f_cut(double desired_epsilon, double string_spectrum_power, const REAL8FrequencySeries *Spec, const REAL8Vector *integral, double last_templates_f_cut, double last_templates_norm)
Definition: StringSearch.c:782
int FindEvents(struct CommandLineArgsTag CLA, const StringTemplate *strtemplate, const REAL8TimeSeries *vector, SnglBurst **head)
Definition: StringSearch.c:516
const double pp
sigmaKerr data[0]
LIGOTimeGPS * XLALGPSTimeNow(LIGOTimeGPS *gpstime)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
REAL8FrequencySeries * XLALCreateREAL8FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL8FrequencySeries(REAL8FrequencySeries *series)
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
void XLALDestroyCache(LALCache *cache)
LALCache * XLALCacheImport(const char *fname)
LALTYPECODE
double REAL8
#define XLAL_LAST_ELEM(x)
char CHAR
int32_t INT4
float REAL4
LAL_S_TYPE_CODE
LAL_D_TYPE_CODE
LALNameLength
int XLALFrStreamClose(LALFrStream *stream)
LALFrStream * XLALFrStreamCacheOpen(LALCache *cache)
int XLALFrStreamSetMode(LALFrStream *stream, int mode)
LAL_FR_STREAM_VERBOSE_MODE
LALTYPECODE XLALFrStreamGetTimeSeriesType(const char *chname, LALFrStream *stream)
REAL8TimeSeries * XLALFrStreamReadREAL8TimeSeries(LALFrStream *stream, const char *chname, const LIGOTimeGPS *start, REAL8 duration, size_t lengthlimit)
REAL4TimeSeries * XLALFrStreamReadREAL4TimeSeries(LALFrStream *stream, const char *chname, const LIGOTimeGPS *start, REAL8 duration, size_t lengthlimit)
void LALDPrintFrequencySeries(REAL8FrequencySeries *series, const CHAR *filename)
void LALDPrintTimeSeries(REAL8TimeSeries *series, const CHAR *filename)
static const INT4 m
static const INT4 a
int XLALREAL8ReverseFFT(REAL8Vector *output, const COMPLEX16Vector *input, const REAL8FFTPlan *plan)
void XLALDestroyREAL8FFTPlan(REAL8FFTPlan *plan)
REAL8FFTPlan * XLALCreateReverseREAL8FFTPlan(UINT4 size, int measurelvl)
REAL8FFTPlan * XLALCreateForwardREAL8FFTPlan(UINT4 size, int measurelvl)
int XLALResampleREAL8TimeSeries(REAL8TimeSeries *series, REAL8 dt)
int XLALREAL8TimeFreqFFT(COMPLEX16FrequencySeries *freq, const REAL8TimeSeries *tser, const REAL8FFTPlan *plan)
int XLALREAL8FreqTimeFFT(REAL8TimeSeries *tser, const COMPLEX16FrequencySeries *freq, const REAL8FFTPlan *plan)
int XLALREAL8AverageSpectrumMedianMean(REAL8FrequencySeries *spectrum, const REAL8TimeSeries *tseries, UINT4 seglen, UINT4 stride, const REAL8Window *window, const REAL8FFTPlan *plan)
REAL8TimeSeries * XLALConvertREAL4TimeSeriesToREAL8(const REAL4TimeSeries *series)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
REAL8TimeSeries * XLALResizeREAL8TimeSeries(REAL8TimeSeries *series, int first, size_t length)
void XLALDestroyREAL4TimeSeries(REAL4TimeSeries *series)
REAL8TimeSeries * XLALCutREAL8TimeSeries(const REAL8TimeSeries *series, size_t first, size_t length)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
const LALUnit lalStrainUnit
const LALUnit lalDimensionlessUnit
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
COMPLEX16Vector * XLALCreateCOMPLEX16Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
void XLALDestroyCOMPLEX16Vector(COMPLEX16Vector *vector)
void XLALDestroyREAL8Window(REAL8Window *window)
REAL8Window * XLALCreateHannREAL8Window(UINT4 length)
#define XLAL_ERROR_NULL(...)
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_ERROR(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_EFUNC
XLAL_EINVAL
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
REAL8 XLALGPSDiff(const LIGOTimeGPS *t1, const LIGOTimeGPS *t0)
LIGOTimeGPS * XLALINT8NSToGPS(LIGOTimeGPS *epoch, INT8 ns)
INT8 XLALGPSToINT8NS(const LIGOTimeGPS *epoch)
int XLALBurstInjectSignals(REAL8TimeSeries *h, const SimBurst *sim_burst, const TimeSlide *time_slide_table_head, const COMPLEX16FrequencySeries *response)
char * ifo
Definition: gwf2xml.c:57
REAL8 norm
Definition: inspinj.c:572
int i
Definition: inspinj.c:596
args
type
head
f
searchsumm
dictionary testfunc
dictionary bailoutfunc
dictionary clusterfunc
int delta_t
c
chi2
float
seed
mismatch
COMPLEX16Sequence * data
COMPLEX16 * data
const char *const vcsDate
const char *const vcsStatus
const char *const vcsId
INT4 gpsNanoSeconds
CHAR ifos[LIGOMETA_IFOS_MAX]
LIGOTimeGPS end_time
REAL8Sequence * data
REAL8Sequence * data
LALUnit sampleUnits
LIGOTimeGPS epoch
CHAR name[LALNameLength]
REAL8 * data
REAL4 central_freq
REAL4 bandwidth
struct tagSnglBurst * next
REAL8FrequencySeries * StringFilter
Definition: StringSearch.c:133
REAL8Vector * auto_cor
Definition: StringSearch.c:136
REAL8Vector * waveform_t
Definition: StringSearch.c:134
COMPLEX16Vector * waveform_f
Definition: StringSearch.c:135
const REAL8FrequencySeries * Spec
Definition: StringSearch.c:753