LALInspiral 5.0.3.1-eeff03c
lalinspiral_injfind.py
Go to the documentation of this file.
1##python
2#
3# Copyright (C) 2006--2009,2013,2014,2016,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
29"""
30Command-line interface to CBC injection identification code.
31"""
32
33
34from optparse import OptionParser
35import sys
36
37
38from igwn_ligolw import lsctables
39from igwn_ligolw import utils as ligolw_utils
40from igwn_ligolw.utils import process as ligolw_process
41from lalinspiral import inspinjfind
42
43
44__author__ = "Kipp Cannon <kipp.cannon@ligo.org>"
45from lalinspiral.git_version import date as __date__
46from lalinspiral.git_version import version as __version__
47
48
49process_program_name = "lalapps_inspinjfind"
50
51
52#
53# Must use injection finder's custom sngl_inspiral table row type.
54#
55
56
57lsctables.SnglInspiralTable.RowType = lsctables.SnglInspiral = inspinjfind.SnglInspiral
58
59
60#
61# =============================================================================
62#
63# Command Line
64#
65# =============================================================================
66#
67
68
70 parser = OptionParser(
71 version = "Name: %%prog\n%s" % __version__,
72 usage = "%prog [options] [file ...]",
73 description = "Accepts as input one or more LIGO Light Weight XML files, each containing CBC candidates and a list of injections, and adds entries to the coincidence tables indicating which events match which injections."
74 )
75 parser.add_option("-f", "--force", action = "store_true", help = "Process even if file has already been processed.")
76 parser.add_option("--comment", metavar = "text", help = "Set the comment string to be written to the process table (default = None).")
77 parser.add_option("-c", "--match-algorithm", metavar = "[inspiral]", default = "inspiral", help = "Set the algorithm used to match event candidates with injections (default = \"inspiral\").")
78 parser.add_option("-r", "--revert", action = "store_true", help = "Revert a previously-processed XML file to its pre-lalapps_inspinjfind state, allowing it to be re-processed. This is achieved by removing lalapps_inspinjfind's entries from the process metadata tables, removing injection-related entries from the coinc_definer table, and removing all coincs created by lalapps_inspinjfind. NOTE: generally this is only possible if lalapps_inspinjfind was the last transformation applied to the file, otherwise data that has been added subsequently might be broken due to dangling cross-references to deleted data. It is left as an exercise to the user to ensure that reverting the file is sensible.")
79 parser.add_option("-w", "--time-window", metavar = "seconds", type = 'float', default = 9., help = "Set the time window used by the \"inspiral\" match algorithm (default = 9.0).")
80 parser.add_option("-v", "--verbose", action = "store_true", help = "Be verbose.")
81 options, filenames = parser.parse_args()
82
83 paramdict = options.__dict__.copy()
84
85 if options.match_algorithm is None:
86 raise ValueError("missing required --match-algorithm option")
87 if options.match_algorithm not in ("inspiral",):
88 raise ValueError("unrecognized --match-algorithm \"%s\"" % options.match_algorithm)
89
90 if options.time_window < 0.:
91 raise ValueError("--time-window must be non-negative")
92
93 return options, paramdict, (filenames or [None])
94
95
96#
97# =============================================================================
98#
99# Main
100#
101# =============================================================================
102#
103
104
105#
106# command line
107#
108
109
110options, paramdict, filenames = parse_command_line()
111
112# must match columns in sngl_inspiral table
113search = {
114 "inspiral": "inspiral"
115}[options.match_algorithm]
116
117
118#
119# set compare functions
120#
121
122
123def InspiralSnglCompare(sim, sngl, twindow = lsctables.LIGOTimeGPS(options.time_window)):
124 """
125 Returns 0 if sim and sngl are less than twindow apart.
126 """
127 dt = sim.time_geocent - sngl.end
128 return 0 if abs(dt) < twindow else dt
129
130
131NearCoincCompare = InspiralSnglCompare
132
133
134snglcomparefunc, nearcoinccomparefunc = {
135 "inspiral": (InspiralSnglCompare, NearCoincCompare)
136}[options.match_algorithm]
137
138
139#
140# loop over files
141#
142
143
144for n, filename in enumerate(filenames, start = 1):
145 #
146 # load the document
147 #
148
149 if options.verbose:
150 print("%d/%d:" % (n, len(filenames)), end=' ', file=sys.stderr)
151 xmldoc = ligolw_utils.load_filename(filename, verbose = options.verbose)
152
153 #
154 # process
155 #
156
157 if options.revert:
158 inspinjfind.revert(xmldoc, process_program_name, verbose = options.verbose)
159 else:
160 #
161 # have we already processed it?
162 #
163
164 if ligolw_process.doc_includes_process(xmldoc, process_program_name):
165 if options.verbose:
166 print("warning: %s already processed," % (filename or "stdin"), end=' ', file=sys.stderr)
167 if not options.force:
168 if options.verbose:
169 print("skipping (use --force to force)", file=sys.stderr)
170 continue
171 if options.verbose:
172 print("continuing by --force", file=sys.stderr)
173
174 #
175 # add process metadata to document
176 #
177
178 process = ligolw_process.register_to_xmldoc(xmldoc, process_program_name, paramdict, version = __version__, cvs_repository = u"lscsoft", cvs_entry_time = __date__, comment = options.comment)
179
180 #
181 # run inspinjfind algorithm
182 #
183
184 inspinjfind.ligolw_inspinjfind(
185 xmldoc,
186 process,
187 search,
188 snglcomparefunc,
189 nearcoinccomparefunc,
190 end_time_bisect_window = 1.5 * options.time_window,
191 verbose = options.verbose
192 )
193
194 #
195 # close out the process metadata
196 #
197
198 process.set_end_time_now()
199
200 #
201 # done
202 #
203
204 ligolw_utils.write_filename(xmldoc, filename, verbose = options.verbose)
205 xmldoc.unlink()
206 lsctables.reset_next_ids(lsctables.TableByName.values())
def InspiralSnglCompare(sim, sngl, twindow=lsctables.LIGOTimeGPS(options.time_window))
Returns 0 if sim and sngl are less than twindow apart.