Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALBurst 2.0.7.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Macros Modules Pages
lalburst_coinc.py
Go to the documentation of this file.
1##python
2#
3# Copyright (C) 2006--2017 Kipp Cannon
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 General
13# Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along
16# with this program; if not, write to the Free Software Foundation, Inc.,
17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19
20#
21# =============================================================================
22#
23# Preamble
24#
25# =============================================================================
26#
27
28
29from optparse import OptionParser
30import sys
31
32
33from igwn_ligolw import lsctables
34from igwn_ligolw import utils as ligolw_utils
35from igwn_ligolw.utils import process as ligolw_process
36from lalburst import git_version
37from lalburst import burca
38from igwn_segments import utils as segmentsUtils
39
40
41process_program_name = "lalburst_coinc"
42
43
44__author__ = "Kipp Cannon <kipp.cannon@ligo.org>"
45__version__ = "git id %s" % git_version.id
46__date__ = git_version.date
47
48
49#
50# =============================================================================
51#
52# Command Line
53#
54# =============================================================================
55#
56
57
59 parser = OptionParser(
60 version = "Name: %%prog\n%s" % git_version.verbose_msg,
61 usage = "%prog [options] [file ...]",
62 description = "%prog implements the excess power and string cusp coincidence algorithms for use in performing trigger-based multi-instrument searches for gravitational wave events. The LIGO Light Weight XML files listed on the command line are processed one by one in order, and over-written with the results. If no files are named, then input is read from stdin and output written to stdout. Gzipped files will be autodetected on input, if a file's name ends in \".gz\" it will be gzip-compressed on output."
63 )
64 parser.add_option("-c", "--comment", metavar = "text", help = "Set comment string in process table (default = None).")
65 parser.add_option("-f", "--force", action = "store_true", help = "Process document even if it has already been processed.")
66 parser.add_option("-a", "--coincidence-algorithm", metavar = "[excesspower|stringcusp]", default = None, help = "Select the coincidence test algorithm to use (required).")
67 parser.add_option("-s", "--coincidence-segments", metavar = "start:end[,start:end,...]", help = "Set the GPS segments in which to retain coincidences. Multiple segments can be specified by separating them with commas. If either start or end is absent from a segment then the interval is unbounded on that side, for example \"874000000:\" causes all coincidences starting at 874000000 to be retained. The \"time\" of a coincidence is ambiguous, and is different for different search algorithms, but a deterministic algorithm is used in all cases so the same coincidence of events will always be assigned the same time. This feature is intended to allow large input files to be analyzed; the procedure is to make n copies of the file and run n instances of burca specifying disjoint --coincidence-segments for each.")
68 parser.add_option("-m", "--min-instruments", metavar = "N", type = "int", default = 2, help = "Set the minimum number of instruments required to form a coincidence (default = 2).")
69 parser.add_option("-t", "--threshold", metavar = "threshold", type = "float", help = "Set the coincidence algorithm's threshold. For excesspower this parameter is not used and must not be set. For stringcusp, this parameter sets the maximum peak time difference in seconds not including light travel time (which will be added internally).")
70 parser.add_option("-v", "--verbose", action = "store_true", help = "Be verbose.")
71 options, filenames = parser.parse_args()
72
73 paramdict = options.__dict__.copy()
74
75 #
76 # check and convert and bunch of arguments
77 #
78
79 if options.coincidence_algorithm is None:
80 raise ValueError("missing required argument --coincidence-algorithm")
81 if options.coincidence_algorithm not in ("excesspower", "stringcusp"):
82 raise ValueError("unrecognized --coincidence-algorithm %s" % options.coincidence_algorithm)
83 if options.coincidence_segments is not None:
84 options.coincidence_segments = segmentsUtils.from_range_strings(options.coincidence_segments.split(","), boundtype = lsctables.LIGOTimeGPS).coalesce()
85 if filenames is not None and len(filenames) > 1:
86 raise ValueError("refusing to allow use of --coincidence-segments with more than one input file")
87 if options.min_instruments < 1:
88 raise ValueError("--min-instruments must be >= 1")
89
90 if options.coincidence_algorithm == "stringcusp" and options.threshold is None:
91 raise ValueError("--threshold is required for --coincidence-algorithm stringcusp")
92 elif options.coincidence_algorithm == "excesspower" and options.threshold is not None:
93 raise ValueError("--threshold is meaningless for --coincidence-algorithm excesspower")
94
95 #
96 # done
97 #
98
99 return options, (filenames or [None]), paramdict
100
101
102#
103# =============================================================================
104#
105# Main
106#
107# =============================================================================
108#
109
110
111#
112# Command line
113#
114
115
116options, filenames, paramdict = parse_command_line()
117
118
119#
120# For excesspower and stringcusp methods, select the appropriate
121# event comparison and book-keeping functions.
122#
123
124
125if options.coincidence_segments is not None:
126 def coinc_segs_ntuple_comparefunc(events, offset_vector, min_instruments = options.min_instruments, coinc_segs = options.coincidence_segments):
127 # for the purposes of the coinc segs feature, the coinc
128 # time is minimum of event peak times. this is a fast, and
129 # guaranteed reproducible definition
130 return min(event.peak + offset_vector[event.ifo] for event in events) not in coinc_segs
131else:
133 return False
134
135
136if options.coincidence_algorithm == "excesspower":
137 coincgen_doubles = burca.ep_coincgen_doubles
138 ntuple_comparefunc = coinc_segs_ntuple_comparefunc
139 CoincTables = burca.ExcessPowerCoincTables
140 CoincDef = burca.ExcessPowerBBCoincDef
141elif options.coincidence_algorithm == "stringcusp":
142 coincgen_doubles = burca.string_coincgen_doubles
143 ntuple_comparefunc = lambda *args: coinc_segs_ntuple_comparefunc(*args) or burca.StringCuspCoincTables.ntuple_comparefunc(*args)
144 CoincTables = burca.StringCuspCoincTables
145 CoincDef = burca.StringCuspBBCoincDef
146else:
147 raise Exception("should never get here")
148
149
150#
151# Iterate over files.
152#
153
154
155for n, filename in enumerate(filenames):
156 #
157 # Load the file.
158 #
159
160 if options.verbose:
161 print("%d/%d:" % (n + 1, len(filenames)), end=' ', file=sys.stderr)
162 xmldoc = ligolw_utils.load_filename(filename, verbose = options.verbose)
163
164 #
165 # Have we already processed it?
166 #
167
168 if ligolw_process.doc_includes_process(xmldoc, process_program_name):
169 if options.verbose:
170 print("warning: %s already processed," % (filename or "stdin"), end=' ', file=sys.stderr)
171 if not options.force:
172 if options.verbose:
173 print("skipping", file=sys.stderr)
174 continue
175 if options.verbose:
176 print("continuing by --force", file=sys.stderr)
177
178 #
179 # Add an entry to the process table.
180 #
181
182 process = ligolw_process.register_to_xmldoc(xmldoc, process_program_name, paramdict,
183 comment = options.comment,
184 version = __version__,
185 cvs_repository = "lscsoft",
186 cvs_entry_time = __date__
187 )
188
189 #
190 # Run coincidence algorithm.
191 #
192
193
194 if options.coincidence_algorithm == "excesspower":
195 delta_t = 2. * bruca.ep_coincgen_doubles.get_coincs.max_edge_peak_delta(lsctables.SnglBurstTable.get_table(xmldoc))
196 elif options.coincidence_algorithm == "stringcusp":
197 delta_t = options.threshold
198 else:
199 raise Exception("should never get here")
200 burca.burca(
201 xmldoc = xmldoc,
202 process_id = process.process_id,
203 coincgen_doubles = coincgen_doubles,
204 CoincTables = CoincTables,
205 coinc_definer_row = CoincDef,
206 delta_t = delta_t,
207 ntuple_comparefunc = ntuple_comparefunc,
208 min_instruments = options.min_instruments,
209 verbose = options.verbose
210 )
211
212 #
213 # Close out the process table.
214 #
215
216 process.set_end_time_now()
217
218 #
219 # Write back to disk, and clean up.
220 #
221
222 ligolw_utils.write_filename(xmldoc, filename, verbose = options.verbose)
223 xmldoc.unlink()
224 lsctables.reset_next_ids(lsctables.TableByName.values())
static double min(double a, double b)
Definition: EPFilters.c:42
def parse_command_line()
def coinc_segs_ntuple_comparefunc(events, offset_vector, min_instruments=options.min_instruments, coinc_segs=options.coincidence_segments)