Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALApps 10.1.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
binj.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2007 Kipp Cannon, Lisa M. Goggin, Patrick Brady, Saikat
3 * Ray-Majumder, Xavier Siemens
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with with program; see the file COPYING. If not, write to the Free
17 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 */
20
21
22/*
23 * ============================================================================
24 *
25 * Preamble
26 *
27 * ============================================================================
28 */
29
30
31#include "config.h"
32
33#include <ctype.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <time.h>
38#include <math.h>
39#include <limits.h>
40#include <gsl/gsl_rng.h>
41#include <gsl/gsl_randist.h>
42
43
44#include <lal/Date.h>
45#include <lal/LALgetopt.h>
46#include <lal/GenerateBurst.h>
47#include <lal/LALConstants.h>
48#include <lal/LALSimBurst.h>
49#include <lal/LALStdio.h>
50#include <lal/LALStdlib.h>
51#include <lal/LIGOLwXML.h>
52#include <lal/LIGOLwXMLRead.h>
53#include <lal/LIGOMetadataTables.h>
54#include <lal/LIGOMetadataUtils.h>
55#include <lal/TimeDelay.h>
56#include <lal/TimeSeries.h>
57#include <lal/XLALError.h>
58
59#include <LALAppsVCSInfo.h>
60
61#define CVS_REVISION "$Revision$"
62#define CVS_SOURCE "$Source$"
63#define CVS_DATE "$Date$"
64#define PROGRAM_NAME "lalapps_binj"
65
66
67/*
68 * ============================================================================
69 *
70 * Command Line
71 *
72 * ============================================================================
73 */
74
75
81};
82
83
84struct options {
88 double ra;
89 double dec;
90 double maxA;
91 double minA;
96 double maxEoverr2;
97 double minEoverr2;
98 double maxf;
99 double minf;
100 double maxhrss;
101 double minhrss;
102 char *output;
103 double q;
104 unsigned long seed;
105 double time_step;
106 double jitter;
108 char *user_tag;
109};
110
111
112static struct options options_defaults(void)
113{
114 struct options defaults;
115
116 defaults.gps_start_time = -1;
117 defaults.gps_end_time = -1;
118 defaults.population = -1;
119 defaults.ra = XLAL_REAL8_FAIL_NAN;
120 defaults.dec = XLAL_REAL8_FAIL_NAN;
127 defaults.maxf = XLAL_REAL8_FAIL_NAN;
128 defaults.minf = XLAL_REAL8_FAIL_NAN;
129 defaults.maxhrss = XLAL_REAL8_FAIL_NAN;
130 defaults.minhrss = XLAL_REAL8_FAIL_NAN;
131 defaults.minA = XLAL_REAL8_FAIL_NAN;
132 defaults.maxA = XLAL_REAL8_FAIL_NAN;
133 defaults.output = NULL;
134 defaults.q = XLAL_REAL8_FAIL_NAN;
135 defaults.seed = 0;
136 defaults.time_step = 210.0 / LAL_PI;
137 defaults.jitter = 0.0;
138 defaults.time_slide_file = NULL;
139 defaults.user_tag = NULL;
140
141 return defaults;
142}
143
144
145static void print_usage(void)
146{
147 fprintf(stderr,
148"lalapps_binj [options]\n" \
149"\n" \
150"Options:\n" \
151"\n" \
152"--gps-end-time seconds\n" \
153"--gps-start-time seconds\n" \
154" Bounds of interval in which to synthesize injections.\n" \
155"\n" \
156"--help\n" \
157" display this message\n" \
158"\n" \
159"--max-amplitude value\n" \
160"--min-amplitude value\n" \
161" Set the bounds of the injection ampltiudes. These only affect\n" \
162" string cusp injections.\n" \
163"\n" \
164"--max-bandwidth hertz\n" \
165"--min-bandwidth hertz\n" \
166" Set the bounds of the injection bandwidthds. These only affect\n" \
167" btlwnb waveforms.\n" \
168"\n" \
169 ); fprintf(stderr,
170"--max-duration seconds\n" \
171"--min-duration seconds\n" \
172" Set the bounds of the injection durations. These only affect\n" \
173" btlwnb waveforms.\n" \
174"\n" \
175"--max-e-over-r2 value\n" \
176"--min-e-over-r2 value\n" \
177" Set the bounds of the range of equivalent isotropic radiated\n" \
178" energies of btlwnb waveforms. The units are M_{sun} / pc^{2} (solar\n" \
179" masses per parsec^{2}).\n" \
180"\n" \
181 ); fprintf(stderr,
182"--max-frequency hertz\n" \
183"--min-frequency hertz\n" \
184" Set the bounds of the injection frequencies. These are the centre\n" \
185" frequencies of sine-Gaussians and btlwnb waveforms, and the\n" \
186" high-frequency cut-offs of string cusp waveforms.\n" \
187"\n" \
188"--max-hrss value\n" \
189"--min-hrss value\n" \
190 ); fprintf(stderr,
191" Set the bounds of the injection h_{rss} values. These only affect\n" \
192" sine-Gaussian injections. (Actually, these set the bounds of the\n" \
193" product of the waveform's hrss and its duration, which makes the\n" \
194" injections lie along the 50 efficiency curve better. To convert to\n" \
195" real hrss multiply by sqrt(2) pi f/Q.) \n" \
196"\n" \
197 ); fprintf(stderr,
198"--output filename\n" \
199" Select output name (default is too hard to explain).\n" \
200"\n" \
201"--population name\n" \
202" Select the injection population to synthesize. Allowed values are\n" \
203" \"targeted\", \"string_cusp\", and \"all_sky_sinegaussian\",\n" \
204" \"all_sky_btlwnb\".\n" \
205"\n" \
206"--q value\n" \
207" Set the Q for sine-Gaussian injections.\n" \
208"\n" \
209"--ra-dec ra,dec\n" \
210" Set the right-ascension and declination of the sky location from which\n" \
211" injections should originate when generating a targeted population.\n" \
212" Co-ordinates are in radians.\n" \
213"\n" \
214 ); fprintf(stderr,
215"--seed value\n" \
216" Set the random number generator's seed (0 = off, default = 0).\n" \
217"\n" \
218"--time-step value\n" \
219" Set the time betwen injections in seconds (default = 210 / pi).\n" \
220"\n" \
221"--jitter value\n" \
222" Give the injection time a random offset within a centered window with a\n" \
223" length specified by this parameter. Value is in seconds, default is 0.\n" \
224"\n" \
225"--time-slide-file filename\n" \
226" Set the name of the LIGO Light-Weight XML file from which to load\n" \
227" the time slide table. The document must contain exactly 1 time\n" \
228" slide vector, and only the contents of the process, process_params,\n" \
229" search_summary (optional), sim_burst (optional), and time_slide tables\n" \
230" will be copied into " PROGRAM_NAME "'s output.\n" \
231"\n" \
232"--user-tag string\n" \
233" Set the user tag in the process and search summary tables to this.\n"
234 );
235}
236
237
238static ProcessParamsTable **add_process_param(ProcessParamsTable **proc_param, const ProcessTable *process, const char *type, const char *param, const char *value)
239{
241 snprintf((*proc_param)->program, sizeof((*proc_param)->program), "%s", PROGRAM_NAME);
242 snprintf((*proc_param)->type, sizeof((*proc_param)->type), "%s", type);
243 snprintf((*proc_param)->param, sizeof((*proc_param)->param), "--%s", param);
244 snprintf((*proc_param)->value, sizeof((*proc_param)->value), "%s", value);
245
246 return &(*proc_param)->next;
247}
248
249
250#define ADD_PROCESS_PARAM(process, type) \
251 do { paramaddpoint = add_process_param(paramaddpoint, process, type, long_options[option_index].name, LALoptarg); } while(0)
252
253
254static struct options parse_command_line(int *argc, char **argv[], const ProcessTable *process, ProcessParamsTable **paramaddpoint)
255{
257 int c;
258 int option_index;
259 struct LALoption long_options[] = {
260 {"gps-end-time", required_argument, NULL, 'A'},
261 {"gps-start-time", required_argument, NULL, 'B'},
262 {"help", no_argument, NULL, 'C'},
263 {"max-amplitude", required_argument, NULL, 'D'},
264 {"min-amplitude", required_argument, NULL, 'E'},
265 {"max-bandwidth", required_argument, NULL, 'F'},
266 {"min-bandwidth", required_argument, NULL, 'G'},
267 {"max-duration", required_argument, NULL, 'H'},
268 {"min-duration", required_argument, NULL, 'I'},
269 {"max-e-over-r2", required_argument, NULL, 'S'},
270 {"min-e-over-r2", required_argument, NULL, 'T'},
271 {"max-frequency", required_argument, NULL, 'J'},
272 {"min-frequency", required_argument, NULL, 'K'},
273 {"max-hrss", required_argument, NULL, 'L'},
274 {"min-hrss", required_argument, NULL, 'M'},
275 {"output", required_argument, NULL, 'V'},
276 {"population", required_argument, NULL, 'N'},
277 {"q", required_argument, NULL, 'O'},
278 {"ra-dec", required_argument, NULL, 'U'},
279 {"seed", required_argument, NULL, 'P'},
280 {"time-step", required_argument, NULL, 'Q'},
281 {"time-slide-file", required_argument, NULL, 'W'},
282 {"jitter", required_argument, NULL, 'X'},
283 {"user-tag", required_argument, NULL, 'R'},
284 {NULL, 0, NULL, 0}
285 };
286
287 do switch(c = LALgetopt_long(*argc, *argv, "", long_options, &option_index)) {
288 case 'A':
290 {
291 LIGOTimeGPS tmp;
292 XLALStrToGPS(&tmp, LALoptarg, NULL);
294 }
295 if(xlalErrno) {
296 fprintf(stderr, "invalid --%s (%s specified)\n", long_options[option_index].name, LALoptarg);
297 exit(1);
298 }
299 ADD_PROCESS_PARAM(process, "lstring");
300 break;
301
302 case 'B':
304 {
305 LIGOTimeGPS tmp;
306 XLALStrToGPS(&tmp, LALoptarg, NULL);
308 }
309 if(xlalErrno) {
310 fprintf(stderr, "invalid --%s (%s specified)\n", long_options[option_index].name, LALoptarg);
311 exit(1);
312 }
313 ADD_PROCESS_PARAM(process, "lstring");
314 break;
315
316 case 'C':
317 print_usage();
318 exit(0);
319
320 case 'D':
321 options.maxA = atof(LALoptarg);
322 ADD_PROCESS_PARAM(process, "real_8");
323 break;
324
325 case 'E':
326 options.minA = atof(LALoptarg);
327 ADD_PROCESS_PARAM(process, "real_8");
328 break;
329
330 case 'F':
332 ADD_PROCESS_PARAM(process, "real_8");
333 break;
334
335 case 'G':
337 ADD_PROCESS_PARAM(process, "real_8");
338 break;
339
340 case 'H':
342 ADD_PROCESS_PARAM(process, "real_8");
343 break;
344
345 case 'I':
347 ADD_PROCESS_PARAM(process, "real_8");
348 break;
349
350 case 'J':
351 options.maxf = atof(LALoptarg);
352 ADD_PROCESS_PARAM(process, "real_8");
353 break;
354
355 case 'K':
356 options.minf = atof(LALoptarg);
357 ADD_PROCESS_PARAM(process, "real_8");
358 break;
359
360 case 'L':
361 options.maxhrss = atof(LALoptarg);
362 ADD_PROCESS_PARAM(process, "real_8");
363 break;
364
365 case 'M':
366 options.minhrss = atof(LALoptarg);
367 ADD_PROCESS_PARAM(process, "real_8");
368 break;
369
370 case 'N':
371 if(!strcmp(LALoptarg, "targeted"))
373 else if(!strcmp(LALoptarg, "string_cusp"))
375 else if(!strcmp(LALoptarg, "all_sky_sinegaussian"))
377 else if(!strcmp(LALoptarg, "all_sky_btlwnb"))
379 else {
380 fprintf(stderr, "error: unrecognized population \"%s\"", LALoptarg);
381 exit(1);
382 }
383 ADD_PROCESS_PARAM(process, "lstring");
384 break;
385
386 case 'O':
387 options.q = atof(LALoptarg);
388 ADD_PROCESS_PARAM(process, "real_8");
389 break;
390
391 case 'P':
393 ADD_PROCESS_PARAM(process, "int_8u");
394 break;
395
396 case 'Q':
398 ADD_PROCESS_PARAM(process, "real_8");
399 break;
400
401 case 'R':
403 ADD_PROCESS_PARAM(process, "lstring");
404 break;
405
406 case 'S':
408 ADD_PROCESS_PARAM(process, "real_8");
409 break;
410
411 case 'T':
413 ADD_PROCESS_PARAM(process, "real_8");
414 break;
415
416 case 'U':
417 {
418 char *end;
419 options.ra = strtod(LALoptarg, &end);
420 while(isspace(*end))
421 end++;
422 if(*end != ',') {
423 fprintf(stderr, "error: cannot parse --ra-dec \"%s\"\n", LALoptarg);
424 exit(1);
425 }
426 options.dec = strtod(end + 1, &end);
427 while(isspace(*end))
428 end++;
429 if(*end != '\0') {
430 fprintf(stderr, "error: cannot parse --ra-dec \"%s\"\n", LALoptarg);
431 exit(1);
432 }
433 }
434 ADD_PROCESS_PARAM(process, "lstring");
435 break;
436
437 case 'V':
439 break;
440
441 case 'W':
443 ADD_PROCESS_PARAM(process, "lstring");
444 break;
445
446 case 'X':
447 options.jitter = atof(LALoptarg);
448 ADD_PROCESS_PARAM(process, "lstring");
449 break;
450
451 case 0:
452 /* option sets a flag */
453 break;
454
455 case -1:
456 /* end of arguments */
457 break;
458
459 case '?':
460 /* unrecognized option */
461 print_usage();
462 exit(1);
463
464 case ':':
465 /* missing argument for an option */
466 print_usage();
467 exit(1);
468 } while(c != -1);
469
470 /* check some of the input parameters for consistency */
471 if(options.maxA < options.minA) {
472 fprintf(stderr, "error: --max-amplitude < --min-amplitude\n");
473 exit(1);
474 }
476 fprintf(stderr, "error: --max-bandwidth < --min-bandwidth\n");
477 exit(1);
478 }
480 fprintf(stderr, "error: --max-duration < --min-duration\n");
481 exit(1);
482 }
483 if(options.maxf < options.minf) {
484 fprintf(stderr, "error: --max-frequency < --min-frequency\n");
485 exit(1);
486 }
488 fprintf(stderr, "error: --max-hrss < --min-hrss\n");
489 exit(1);
490 }
491
492 if(options.gps_start_time == -1 || options.gps_end_time == -1) {
493 fprintf(stderr, "--gps-start-time and --gps-end-time are both required\n");
494 exit(1);
495 }
497 fprintf(stderr, "error: --gps-end-time < --gps-start-time\n");
498 exit(1);
499 }
501 fprintf(stderr, "--time-slide-file is required\n");
502 exit(1);
503 }
504
505 switch(options.population) {
510 break;
511
512 default:
513 fprintf(stderr, "error: --population is required\n");
514 exit(1);
515 }
516
517 if(!options.output) {
518 int max_length = 100; /* ARGH: ugly */
519 options.output = calloc(max_length + 1, sizeof(*options.output));
520 if(options.user_tag)
521 snprintf(options.output, max_length, "HL-INJECTIONS_%s-%d-%d.xml", options.user_tag, (int) (options.gps_start_time / LAL_INT8_C(1000000000)), (int) ((options.gps_end_time - options.gps_start_time) / LAL_INT8_C(1000000000)));
522 else
523 snprintf(options.output, max_length, "HL-INJECTIONS-%d-%d.xml", (int) (options.gps_start_time / LAL_INT8_C(1000000000)), (int) ((options.gps_end_time - options.gps_start_time) / LAL_INT8_C(1000000000)));
524 }
525
526 return options;
527}
528
529
530/*
531 * ============================================================================
532 *
533 * XML Handling
534 *
535 * ============================================================================
536 */
537
538
539#define DEFINELIGOLWTABLEAPPEND(funcroot, rowtype) \
540static rowtype *XLAL ## funcroot ## Append(rowtype *head, rowtype *row) \
541{ \
542 rowtype *tail; \
543 if(!head) \
544 return row; \
545 for(tail = head; tail->next; tail = tail->next); \
546 tail->next = row; \
547 return head; \
548}
549
550
553DEFINELIGOLWTABLEAPPEND(TimeSlideTable, TimeSlide)
555DEFINELIGOLWTABLEAPPEND(SimBurstTable, SimBurst)
556
557
558static int load_tisl_file_and_merge(const char *filename, ProcessTable **process_table_head, ProcessParamsTable **process_params_table_head, TimeSlide **time_slide_table_head, SearchSummaryTable **search_summary_table_head, SimBurst **sim_burst_table_head)
559{
560 ProcessTable *tisl_process_table_head, *process_row;
561 ProcessParamsTable *tisl_process_params_table_head, *process_params_row;
562 SearchSummaryTable *tisl_search_summary_table_head;
563 TimeSlide *tisl_time_slide_table_head, *time_slide_row;
564 SearchSummaryTable *search_summary_row;
565 SimBurst *tisl_sim_burst_table_head, *sim_burst_row;
566 long process_id;
567
568 /* load the tables from the time slide document */
569
570 tisl_process_table_head = XLALProcessTableFromLIGOLw(filename);
571 if(!tisl_process_table_head)
572 return -1;
573 tisl_process_params_table_head = XLALProcessParamsTableFromLIGOLw(filename);
574 if(!tisl_process_params_table_head)
575 return -1;
576 tisl_time_slide_table_head = XLALTimeSlideTableFromLIGOLw(filename);
577 if(!tisl_time_slide_table_head)
578 return -1;
579 if(XLALLIGOLwHasTable(filename, "search_summary")) {
580 tisl_search_summary_table_head = XLALSearchSummaryTableFromLIGOLw(filename);
581 if(!tisl_search_summary_table_head)
582 return -1;
583 } else
584 tisl_search_summary_table_head = NULL;
585 if(XLALLIGOLwHasTable(filename, "sim_burst")) {
586 tisl_sim_burst_table_head = XLALSimBurstTableFromLIGOLw(filename);
587 if(!tisl_sim_burst_table_head)
588 return -1;
589 }
590 tisl_sim_burst_table_head = NULL;
591
592 /* check for more than one time slide in the document */
593
594 for(time_slide_row = tisl_time_slide_table_head->next; time_slide_row; time_slide_row = time_slide_row->next)
595 if(time_slide_row->time_slide_id != tisl_time_slide_table_head->time_slide_id) {
596 fprintf(stderr, "error: time slide file \"%s\" contains more than 1 offset vector", filename);
597 return -1;
598 }
599
600 /* find the next available process ID and reassign binj's rows to
601 * avoid collisions */
602
603 process_id = XLALProcessTableGetNextID(tisl_process_table_head);
604 for(process_row = *process_table_head; process_row; process_row = process_row->next)
605 process_row->process_id = process_id;
606 for(process_params_row = *process_params_table_head; process_params_row; process_params_row = process_params_row->next)
607 process_params_row->process_id = process_id;
608 for(search_summary_row = *search_summary_table_head; search_summary_row; search_summary_row = search_summary_row->next)
609 search_summary_row->process_id = process_id;
610 for(sim_burst_row = *sim_burst_table_head; sim_burst_row; sim_burst_row = sim_burst_row->next)
611 sim_burst_row->process_id = process_id;
612
613 /* append our rows to the process and process params tables */
614
615 *process_table_head = XLALProcessTableAppend(tisl_process_table_head, *process_table_head);
616 *process_params_table_head = XLALProcessParamsTableAppend(tisl_process_params_table_head, *process_params_table_head);
617 *time_slide_table_head = XLALTimeSlideTableAppend(tisl_time_slide_table_head, *time_slide_table_head);
618 *search_summary_table_head = XLALSearchSummaryTableAppend(tisl_search_summary_table_head, *search_summary_table_head);
619 *sim_burst_table_head = XLALSimBurstTableAppend(tisl_sim_burst_table_head, *sim_burst_table_head);
620
621 /* done */
622
623 return 0;
624}
625
626
627static int qsort_strcmp(char **a, char **b)
628{
629 return strcmp(*a, *b);
630}
631
632
633static int set_instruments(ProcessTable *process, TimeSlide *time_slide_table_head)
634{
635 char *ifos = process->ifos;
636 char **time_slide_instruments;
637 int n_instruments, n;
638 TimeSlide *time_slide;
639
640 /* count the rows in the time_slide table */
641 for(n_instruments = 0, time_slide = time_slide_table_head; time_slide; n_instruments++, time_slide = time_slide->next);
642
643 /* allocate an array of pointers to the instrument values and sort
644 * in alphabetical order */
645 time_slide_instruments = malloc(n_instruments * sizeof(*time_slide_instruments));
646 if(!time_slide_instruments)
647 return -1;
648 for(n = 0, time_slide = time_slide_table_head; time_slide; n++, time_slide = time_slide->next)
649 time_slide_instruments[n] = time_slide->instrument;
650 qsort(time_slide_instruments, n_instruments, sizeof(*time_slide_instruments), (int (*)(const void *, const void *)) qsort_strcmp);
651
652 /* merge into a comma-delimited string */
653 for(n = 0; n < n_instruments; n++) {
654 int copied;
655 copied = snprintf(ifos, sizeof(process->ifos) - (ifos - process->ifos), "%s%s", time_slide_instruments[n], n < n_instruments - 1 ? "," : "");
656 if(copied < 2 + (n < n_instruments - 1 ? 1 : 0)) {
657 fprintf(stderr, "error: too many instruments for process table's ifos column\n");
658 free(time_slide_instruments);
659 return -1;
660 }
661 ifos += copied;
662 }
663 free(time_slide_instruments);
664 return 0;
665}
666
667
668/*
669 * ============================================================================
670 *
671 * Sequences
672 *
673 * ============================================================================
674 */
675
676
677#if 0
678/*
679 * Repeating arithmetic sequence.
680 */
681
682
683static double sequence_arithmetic_next(double low, double high, double delta)
684{
685 static int i = 0;
686 double x = low + delta * i++;
687
688 if(high < low || high - low < delta)
689 return XLAL_REAL8_FAIL_NAN;
690
691 if(x > high) {
692 i = 1;
693 return low;
694 }
695
696 return x;
697}
698#endif
699
700
701/*
702 * Repeating geometric sequence.
703 */
704
705
706static double sequence_geometric_next(double low, double high, double ratio)
707{
708 static unsigned i = 0;
709 double x = low * pow(ratio, i++);
710
711 if(high < low || high / low < ratio)
712 return XLAL_REAL8_FAIL_NAN;
713
714 if(x > high) {
715 i = 1;
716 return low;
717 }
718
719 return x;
720}
721
722
723#if 0
724/*
725 * Random amplitude presets.
726 */
727
728
729static double sequence_preset_next(gsl_rng *rng)
730{
731 static const double presets[] = {
732 1e-22,
733 2e-22,
734 5e-22,
735 1e-21,
736 2e-21,
737 5e-21,
738 1e-20
739 };
740
741 return presets[gsl_rng_uniform_int(rng, XLAL_NUM_ELEM(presets))];
742}
743#endif
744
745
746/*
747 * ============================================================================
748 *
749 * Logarithmically-Distributed Random Variable
750 *
751 * ============================================================================
752 */
753
754
755/*
756 * Return a random number in the range [a, b), whose logarithm is uniformly
757 * distributed
758 */
759
760
761static double ran_flat_log(gsl_rng *rng, double a, double b)
762{
763 return exp(gsl_ran_flat(rng, log(a), log(b)));
764}
765
766
767/*
768 * Logarithmically-distributed random(ish) sequence. Same as
769 * sequence_geometric_next() but where each repetition of the sequence has
770 * a random factor applied whose logarithm is uniformly distributed. The
771 * result is a random variable whose logarithm is uniformly distributed on
772 * average, but in which neighbouring numbers are separated by a guaranteed
773 * minimum ratio.
774 */
775
776
777static double ran_flat_log_discrete(gsl_rng *rng, double a, double b, double ratio)
778{
779 static double factor = 0.0;
780 double x = sequence_geometric_next(a, b / ratio, ratio);
781
782 if(x == a)
783 /* sequence has looped. must happen first time through */
784 factor = ran_flat_log(rng, 1.0, ratio);
785
786 return x * factor;
787}
788
789
790/*
791 * ============================================================================
792 *
793 * String Cusp Simulations
794 *
795 * ============================================================================
796 */
797
798
799/*
800 * \theta is the angle the line of sight makes with the cusp. \theta^{2}
801 * is distributed uniformly, and the high frequency cut-off of the
802 * injection is \propto \theta^{-3}. So we first solve for the limits of
803 * \theta^{2} from the low- and high bounds of the frequency band of
804 * interest, pick a uniformly-distributed number in that range, and convert
805 * back to a high frequency cut-off.
806 */
807
808
809static double random_string_cusp_fhigh(double flow, double fhigh, gsl_rng *rng)
810{
811 const double thetasqmin = pow(fhigh, -2.0 / 3.0);
812 const double thetasqmax = pow(flow, -2.0 / 3.0);
813 const double thetasq = gsl_ran_flat(rng, thetasqmin, thetasqmax);
814
815 return pow(thetasq, -3.0 / 2.0);
816}
817
818
819/*
820 * Uniform sky location, and uniform polarization orientation.
821 */
822
823
824static void random_location_and_polarization(double *ra, double *dec, double *psi, gsl_rng *rng)
825{
826 *ra = gsl_ran_flat(rng, 0, LAL_TWOPI);
827 *dec = asin(gsl_ran_flat(rng, -1, +1));
828 *psi = gsl_ran_flat(rng, 0, LAL_TWOPI);
829}
830
831
832/*
833 * Pick a random string cusp injection.
834 */
835
836
837static SimBurst *random_string_cusp(double flow, double fhigh, double Alow, double Ahigh, gsl_rng *rng)
838{
839 SimBurst *sim_burst = XLALCreateSimBurst();
840
841 if(!sim_burst)
842 return NULL;
843
844 strcpy(sim_burst->waveform, "StringCusp");
845
846 /* high frequency cut-off and amplitude */
847
848 sim_burst->frequency = random_string_cusp_fhigh(flow, fhigh, rng);
849 sim_burst->amplitude = ran_flat_log(rng, Alow, Ahigh);
850
851 /* sky location and wave frame orientation */
852
853 random_location_and_polarization(&sim_burst->ra, &sim_burst->dec, &sim_burst->psi, rng);
854
855 /* string cusp waveform generator makes a linearly polarized
856 * waveform in the + polarization. it ignores these parameters,
857 * but just for consistency we populate them appropriately */
858
859 sim_burst->pol_ellipse_e = 1.0;
860 sim_burst->pol_ellipse_angle = 0.0;
861
862 return sim_burst;
863}
864
865
866/*
867 * ============================================================================
868 *
869 * BTLWNB Injections
870 *
871 * ============================================================================
872 */
873
874
875/*
876 * Pick a random band- and time-limited white noise burst.
877 */
878
879
880static SimBurst *random_directed_btlwnb(double ra, double dec, double psi, double minf, double maxf, double minband, double maxband, double mindur, double maxdur, double minEoverr2, double maxEoverr2, gsl_rng *rng)
881{
882 REAL8TimeSeries *hplus, *hcross;
883 SimBurst *sim_burst = XLALCreateSimBurst();
884
885 if(!sim_burst)
886 return NULL;
887
888 strcpy(sim_burst->waveform, "BTLWNB");
889
890 /* sky location and wave frame orientation */
891
892 sim_burst->ra = ra;
893 sim_burst->dec = dec;
894 sim_burst->psi = psi;
895
896 /* pick a waveform. assumes a random number generator spanning the
897 * full integer range is in use. at the time of writing, the
898 * MT19937 generator is being used, which yields integers spanning
899 * the full unsigned long int range. */
900
901 sim_burst->waveform_number = gsl_rng_get(rng);
902
903 /* centre frequency. three steps between minf and maxf */
904
905 sim_burst->frequency = ran_flat_log_discrete(rng, minf, maxf, pow(maxf / minf, 1.0 / 3.0));
906
907 /* duration and bandwidth. keep picking until a valid pair is
908 * obtained (i.e. their product is >= 2 / \pi) */
909 do {
910 sim_burst->duration = ran_flat_log(rng, mindur, maxdur);
911 sim_burst->bandwidth = ran_flat_log(rng, minband, maxband);
912 } while(sim_burst->bandwidth * sim_burst->duration < LAL_2_PI);
913
914 /* energy */
915
916 sim_burst->egw_over_rsquared = ran_flat_log(rng, minEoverr2, maxEoverr2) * pow(sim_burst->frequency / 100.0, 4.0);
917
918 /* not sure if this makes sense. these parameters are ignored by
919 * the injection code, but post-processing tools sometimes wish to
920 * know with what amplitude an injection should've been seen in an
921 * instrument, and they use these to project the + and x amplitudes
922 * onto the detector. setting the eccentricity to 0 and the angle
923 * to anything makes such tools believe the amplitude is equally
924 * partitioned between the two polarizations which is true for
925 * these injections. */
926
927 sim_burst->pol_ellipse_e = 0.0;
928 sim_burst->pol_ellipse_angle = 0.0;
929
930 /* populate the hrss column for convenience later */
931 /* FIXME: sample rate is hard-coded to 8192 Hz, which is what the
932 * excess power pipeline's .ini file is configured for in CVS, but
933 * because it can be easily changed this is not good */
934
935 XLALGenerateSimBurst(&hplus, &hcross, sim_burst, 1.0 / 8192);
936 if(!hplus || !hcross) {
939 XLALDestroySimBurst(sim_burst);
940 return NULL;
941 }
942 sim_burst->hrss = XLALMeasureHrss(hplus, hcross);
945
946 /* done */
947
948 return sim_burst;
949}
950
951
952static SimBurst *random_all_sky_btlwnb(double minf, double maxf, double minband, double maxband, double mindur, double maxdur, double minEoverr2, double maxEoverr2, gsl_rng *rng)
953{
954 double ra, dec, psi;
955
957
958 return random_directed_btlwnb(ra, dec, psi, minf, maxf, minband, maxband, mindur, maxdur, minEoverr2, maxEoverr2, rng);
959}
960
961
962/*
963 * ============================================================================
964 *
965 * All-Sky sine-Gaussians
966 *
967 * ============================================================================
968 */
969
970
971/*
972 * the duration of a sine-Gaussian from its Q and centre frequency
973 */
974
975
976static double duration_from_q_and_f(double Q, double f)
977{
978 /* compute duration from Q and frequency */
979 return Q / (sqrt(2.0) * LAL_PI * f);
980}
981
982
983/*
984 * pick a sine-Gaussian
985 */
986
987
988static SimBurst *random_all_sky_sineGaussian(double minf, double maxf, double q, double minhrsst, double maxhrsst, gsl_rng *rng)
989{
990 SimBurst *sim_burst = XLALCreateSimBurst();
991
992 if(!sim_burst)
993 return NULL;
994
995 strcpy(sim_burst->waveform, "SineGaussian");
996
997 /* sky location and wave frame orientation */
998
999 random_location_and_polarization(&sim_burst->ra, &sim_burst->dec, &sim_burst->psi, rng);
1000
1001 /* q and centre frequency. three steps between minf and maxf */
1002
1003 sim_burst->q = q;
1004 if( minf == maxf ){
1005 sim_burst->frequency = maxf;
1006 } else {
1007 sim_burst->frequency = ran_flat_log_discrete(rng, minf, maxf, pow(maxf / minf, 1.0 / 3.0));
1008 }
1009
1010 /* hrss */
1011
1012 sim_burst->hrss = ran_flat_log(rng, minhrsst, maxhrsst) / duration_from_q_and_f(sim_burst->q, sim_burst->frequency);
1013
1014 /* hard-code for linearly polarized waveforms in the x
1015 * polarization. induces LAL's sine-Gaussian generator to produce
1016 * linearly polarized sine-Gaussians (+ would be a cosine
1017 * Gaussian). */
1018
1019 sim_burst->pol_ellipse_e = 1.0;
1020 sim_burst->pol_ellipse_angle = LAL_PI_2;
1021
1022 /* done */
1023
1024 return sim_burst;
1025}
1026
1027
1028/*
1029 * ============================================================================
1030 *
1031 * Output
1032 *
1033 * ============================================================================
1034 */
1035
1036
1037static void write_xml(const char *filename, const ProcessTable *process_table_head, const ProcessParamsTable *process_params_table_head, const SearchSummaryTable *search_summary_table_head, const TimeSlide *time_slide_table_head, const SimBurst *sim_burst)
1038{
1039 LIGOLwXMLStream *xml;
1040
1042
1043 /* process table */
1044 if(XLALWriteLIGOLwXMLProcessTable(xml, process_table_head)) {
1045 /* error occured. ?? do anything else ?? */
1046 exit(1);
1047 }
1048
1049 /* process params table */
1050 if(XLALWriteLIGOLwXMLProcessParamsTable(xml, process_params_table_head)) {
1051 /* error occured. ?? do anything else ?? */
1052 exit(1);
1053 }
1054
1055 /* search summary table */
1056 if(XLALWriteLIGOLwXMLSearchSummaryTable(xml, search_summary_table_head)) {
1057 /* error occured. ?? do anything else ?? */
1058 exit(1);
1059 }
1060
1061 /* time slide table */
1062 if(XLALWriteLIGOLwXMLTimeSlideTable(xml, time_slide_table_head)) {
1063 /* error occured. ?? do anything else ?? */
1064 exit(1);
1065 }
1066
1067 /* sim burst table */
1068 if(XLALWriteLIGOLwXMLSimBurstTable(xml, sim_burst)) {
1069 /* error occured. ?? do anything else ?? */
1070 exit(1);
1071 }
1072
1074}
1075
1076
1077/*
1078 * ============================================================================
1079 *
1080 * Entry Point
1081 *
1082 * ============================================================================
1083 */
1084
1085
1086int main(int argc, char *argv[])
1087{
1088 struct options options;
1089 INT8 tinj, jitter;
1090 gsl_rng *rng;
1091 ProcessTable *process_table_head = NULL, *process;
1092 ProcessParamsTable *process_params_table_head = NULL;
1093 SearchSummaryTable *search_summary_table_head = NULL, *search_summary;
1094 TimeSlide *time_slide_table_head = NULL;
1095 SimBurst *sim_burst_table_head = NULL;
1096 SimBurst **sim_burst = &sim_burst_table_head;
1097
1098
1099 /*
1100 * Initialize debug handler
1101 */
1102
1103
1105
1106
1107 /*
1108 * Process table
1109 */
1110
1111
1112 process_table_head = process = XLALCreateProcessTableRow();
1114 exit(1);
1115 XLALGPSTimeNow(&process->start_time);
1116
1117
1118 /*
1119 * Command line and process params table.
1120 */
1121
1122
1123 options = parse_command_line(&argc, &argv, process, &process_params_table_head);
1124 if(options.user_tag)
1125 snprintf(process->comment, sizeof(process->comment), "%s", options.user_tag);
1126
1127
1128 /*
1129 * Search summary table
1130 */
1131
1132
1133 search_summary_table_head = search_summary = XLALCreateSearchSummaryTableRow(process);
1134 if(options.user_tag)
1135 snprintf(search_summary->comment, sizeof(search_summary->comment), "%s", options.user_tag);
1136 search_summary->nnodes = 1;
1137 search_summary->out_start_time = *XLALINT8NSToGPS(&search_summary->in_start_time, options.gps_start_time);
1138 search_summary->out_end_time = *XLALINT8NSToGPS(&search_summary->in_end_time, options.gps_end_time);
1139
1140
1141 /*
1142 * Initialize random number generator
1143 */
1144
1145
1146 rng = gsl_rng_alloc(gsl_rng_mt19937);
1147 if(options.seed)
1148 gsl_rng_set(rng, options.seed);
1149
1150
1151 /*
1152 * Main loop
1153 */
1154
1155
1156 for(tinj = options.gps_start_time; tinj <= options.gps_end_time; tinj += options.time_step * 1e9) {
1157 /*
1158 * Progress bar.
1159 */
1160
1161 XLALPrintInfo("%s: ", argv[0]);
1163 XLALPrintInfo(" complete\n");
1164
1165 /*
1166 * Create an injection
1167 */
1168
1169 switch(options.population) {
1172 break;
1173
1176 break;
1177
1180 break;
1181
1184 break;
1185
1186 default:
1187 /* shouldn't get here, command line parsing code
1188 * should prevent it */
1189 XLALPrintError("internal error\n");
1190 exit(1);
1191 }
1192
1193 if(!*sim_burst) {
1194 XLALPrintError("can't make injection\n");
1195 exit(1);
1196 }
1197
1198 /*
1199 * Peak time at geocentre in GPS seconds
1200 */
1201
1202 /* Add "jitter" to the injection if user requests it */
1203 if(options.jitter > 0) {
1204 jitter = gsl_ran_flat(rng, -options.jitter/2, options.jitter/2)*1e9;
1205 } else {
1206 jitter = 0;
1207 }
1208
1209 XLALINT8NSToGPS(&(*sim_burst)->time_geocent_gps, tinj + jitter);
1210
1211 /*
1212 * Peak time at geocentre in GMST radians
1213 */
1214
1215 (*sim_burst)->time_geocent_gmst = XLALGreenwichMeanSiderealTime(&(*sim_burst)->time_geocent_gps);
1216
1217 /*
1218 * Move to next injection
1219 */
1220
1221 sim_burst = &(*sim_burst)->next;
1222 }
1223
1224 XLALPrintInfo("%s: ", argv[0]);
1226 XLALPrintInfo(" complete\n");
1227
1228 /* load time slide document and merge our table rows with its */
1229
1230 if(load_tisl_file_and_merge(options.time_slide_file, &process_table_head, &process_params_table_head, &time_slide_table_head, &search_summary_table_head, &sim_burst_table_head))
1231 exit(1);
1232 if(set_instruments(process, time_slide_table_head))
1233 exit(1);
1234 snprintf(search_summary->ifos, sizeof(search_summary->ifos), "%s", process->ifos);
1235
1236 /* output */
1237
1238 XLALGPSTimeNow(&process->end_time);
1239 search_summary->nevents = XLALSimBurstAssignIDs(sim_burst_table_head, process->process_id, time_slide_table_head->time_slide_id, 0);
1240 write_xml(options.output, process_table_head, process_params_table_head, search_summary_table_head, time_slide_table_head, sim_burst_table_head);
1241
1242 /* done */
1243
1244 gsl_rng_free(rng);
1245 XLALDestroyProcessTable(process_table_head);
1246 XLALDestroyProcessParamsTable(process_params_table_head);
1247 XLALDestroyTimeSlideTable(time_slide_table_head);
1248 XLALDestroySearchSummaryTable(search_summary_table_head);
1249 XLALDestroySimBurstTable(sim_burst_table_head);
1250 exit(0);
1251}
int XLALStrToGPS(LIGOTimeGPS *t, const char *nptr, char **endptr)
const LALVCSInfo lalAppsVCSIdentInfo
Identable VCS and build information for LALApps.
lal_errhandler_t lal_errhandler
int LAL_ERR_EXIT(LALStatus *stat, const char *func, const char *file, const int line, volatile const char *id)
static double double delta
int LALgetopt_long(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 XLALWriteLIGOLwXMLProcessTable(LIGOLwXMLStream *, const ProcessTable *)
int XLALWriteLIGOLwXMLSimBurstTable(LIGOLwXMLStream *, const SimBurst *)
int XLALWriteLIGOLwXMLProcessParamsTable(LIGOLwXMLStream *, const ProcessParamsTable *)
int XLALWriteLIGOLwXMLSearchSummaryTable(LIGOLwXMLStream *, const SearchSummaryTable *)
int XLALWriteLIGOLwXMLTimeSlideTable(LIGOLwXMLStream *, const TimeSlide *)
int XLALLIGOLwHasTable(const char *filename, const char *table_name)
ProcessParamsTable * XLALProcessParamsTableFromLIGOLw(const char *filename)
ProcessTable * XLALProcessTableFromLIGOLw(const char *filename)
TimeSlide * XLALTimeSlideTableFromLIGOLw(const char *filename)
SearchSummaryTable * XLALSearchSummaryTableFromLIGOLw(const char *fileName)
SimBurst * XLALSimBurstTableFromLIGOLw(const char *filename)
void XLALDestroyProcessParamsTable(ProcessParamsTable *)
long XLALSimBurstAssignIDs(SimBurst *head, long process_id, long time_slide_id, long event_id)
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)
long XLALProcessTableGetNextID(ProcessTable *)
SimBurst * XLALCreateSimBurst(void)
ProcessParamsTable * XLALCreateProcessParamsTableRow(const ProcessTable *)
void XLALDestroySearchSummaryTable(SearchSummaryTable *)
SimBurst * XLALDestroySimBurst(SimBurst *row)
#define fprintf
double e
static double ran_flat_log(gsl_rng *rng, double a, double b)
Definition: binj.c:761
int main(int argc, char *argv[])
Definition: binj.c:1086
static void print_usage(void)
Definition: binj.c:145
static int load_tisl_file_and_merge(const char *filename, ProcessTable **process_table_head, ProcessParamsTable **process_params_table_head, TimeSlide **time_slide_table_head, SearchSummaryTable **search_summary_table_head, SimBurst **sim_burst_table_head)
Definition: binj.c:558
static double sequence_geometric_next(double low, double high, double ratio)
Definition: binj.c:706
static SimBurst * random_all_sky_sineGaussian(double minf, double maxf, double q, double minhrsst, double maxhrsst, gsl_rng *rng)
Definition: binj.c:988
static struct options parse_command_line(int *argc, char **argv[], const ProcessTable *process, ProcessParamsTable **paramaddpoint)
Definition: binj.c:254
#define ADD_PROCESS_PARAM(process, type)
Definition: binj.c:250
static int set_instruments(ProcessTable *process, TimeSlide *time_slide_table_head)
Definition: binj.c:633
#define PROGRAM_NAME
Definition: binj.c:64
static ProcessParamsTable ** add_process_param(ProcessParamsTable **proc_param, const ProcessTable *process, const char *type, const char *param, const char *value)
Definition: binj.c:238
static void random_location_and_polarization(double *ra, double *dec, double *psi, gsl_rng *rng)
Definition: binj.c:824
static double random_string_cusp_fhigh(double flow, double fhigh, gsl_rng *rng)
Definition: binj.c:809
static SimBurst * random_string_cusp(double flow, double fhigh, double Alow, double Ahigh, gsl_rng *rng)
Definition: binj.c:837
static SimBurst * random_directed_btlwnb(double ra, double dec, double psi, double minf, double maxf, double minband, double maxband, double mindur, double maxdur, double minEoverr2, double maxEoverr2, gsl_rng *rng)
Definition: binj.c:880
static SimBurst * random_all_sky_btlwnb(double minf, double maxf, double minband, double maxband, double mindur, double maxdur, double minEoverr2, double maxEoverr2, gsl_rng *rng)
Definition: binj.c:952
static void write_xml(const char *filename, const ProcessTable *process_table_head, const ProcessParamsTable *process_params_table_head, const SearchSummaryTable *search_summary_table_head, const TimeSlide *time_slide_table_head, const SimBurst *sim_burst)
Definition: binj.c:1037
static double ran_flat_log_discrete(gsl_rng *rng, double a, double b, double ratio)
Definition: binj.c:777
static struct options options_defaults(void)
Definition: binj.c:112
static double duration_from_q_and_f(double Q, double f)
Definition: binj.c:976
population
Definition: binj.c:76
@ POPULATION_ALL_SKY_SINEGAUSSIAN
Definition: binj.c:78
@ POPULATION_ALL_SKY_BTLWNB
Definition: binj.c:79
@ POPULATION_TARGETED
Definition: binj.c:77
@ POPULATION_STRING_CUSP
Definition: binj.c:80
static int qsort_strcmp(char **a, char **b)
Definition: binj.c:627
#define DEFINELIGOLWTABLEAPPEND(funcroot, rowtype)
Definition: binj.c:539
double flow
const double Q
LIGOTimeGPS * XLALGPSTimeNow(LIGOTimeGPS *gpstime)
#define LAL_PI_2
#define LAL_2_PI
#define LAL_PI
#define LAL_TWOPI
#define XLAL_NUM_ELEM(x)
#define LAL_INT8_C(c)
int64_t INT8
REAL8 XLALMeasureHrss(const REAL8TimeSeries *, const REAL8TimeSeries *)
static const INT4 q
static const INT4 a
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
#define xlalErrno
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_REAL8_FAIL_NAN
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int XLALClearErrno(void)
int XLALPrintProgressBar(double)
REAL8 XLALGreenwichMeanSiderealTime(const LIGOTimeGPS *gpstime)
LIGOTimeGPS * XLALINT8NSToGPS(LIGOTimeGPS *epoch, INT8 ns)
INT8 XLALGPSToINT8NS(const LIGOTimeGPS *epoch)
int XLALGenerateSimBurst(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const SimBurst *sim_burst, double delta_t)
char * ifos
Definition: inspinj.c:499
char name[LIGOMETA_SOURCE_MAX]
Definition: inspinj.c:561
REAL4 psi
Definition: inspinj.c:519
int i
Definition: inspinj.c:596
REAL8 dec
Definition: inspinj.c:563
REAL8 ra
Definition: inspinj.c:562
type
f
process_id
c
int
log
float atol
const char *const vcsDate
const char *const vcsStatus
const char *const vcsId
struct tagProcessParamsTable * next
struct tagProcessTable * next
struct tagSearchSummaryTable * next
char waveform[LIGOMETA_WAVEFORM_MAX]
struct tagSimBurst * next
REAL8 amplitude
REAL8 pol_ellipse_angle
unsigned long waveform_number
REAL8 frequency
REAL8 psi
REAL8 duration
REAL8 egw_over_rsquared
REAL8 ra
REAL8 bandwidth
long process_id
REAL8 pol_ellipse_e
REAL8 dec
REAL8 hrss
CHAR instrument[LIGOMETA_STRING_MAX]
long time_slide_id
struct tagTimeSlide * next
Definition: join.c:30
double jitter
Definition: binj.c:106
double minbandwidth
Definition: binj.c:93
double minf
Definition: binj.c:99
double minEoverr2
Definition: binj.c:97
double q
Definition: binj.c:103
double maxA
Definition: binj.c:90
double ra
Definition: binj.c:88
char * output
Definition: binj.c:102
double minduration
Definition: binj.c:95
char * user_tag
Definition: binj.c:108
double maxEoverr2
Definition: binj.c:96
char * time_slide_file
Definition: binj.c:107
enum population population
Definition: binj.c:87
double dec
Definition: binj.c:89
double maxhrss
Definition: binj.c:100
unsigned long seed
Definition: binj.c:104
double time_step
Definition: binj.c:105
INT8 gps_end_time
Definition: binj.c:86
double maxduration
Definition: binj.c:94
double minhrss
Definition: binj.c:101
double maxbandwidth
Definition: binj.c:92
INT8 gps_start_time
Definition: binj.c:85
double minA
Definition: binj.c:91
double maxf
Definition: binj.c:98