diff --git a/gstlal-ugly/bin/Makefile.am b/gstlal-ugly/bin/Makefile.am
index 8196848701427b7d81682565965efe2647330be4..32e34e0bd033dcbbcb283ae45091ae02c1d9ae75 100644
--- a/gstlal-ugly/bin/Makefile.am
+++ b/gstlal-ugly/bin/Makefile.am
@@ -11,6 +11,7 @@ dist_bin_SCRIPTS = \
 	gstlal_harmonic_mean_psd \
 	gstlal_mock_data_server \
 	gstlal_ilwdify \
+	gstlal_inspiral_best_coinc_file \
 	gstlal_inspiral_treebank \
 	gstlal_inspiral_treebank_dag \
 	gstlal_inspiral_bankviz \
@@ -26,6 +27,7 @@ dist_bin_SCRIPTS = \
 	gstlal_recolor_frames_pipe \
 	gstlal_inj_frames \
 	gstlal_cache_to_segments \
+	gstlal_ligolw_add_without_reassign \
 	gstlal_ll_inspiral_aggregator \
 	gstlal_ll_dq \
 	gstlal_condor_top \
diff --git a/gstlal-ugly/bin/gstlal_inspiral_best_coinc_file b/gstlal-ugly/bin/gstlal_inspiral_best_coinc_file
new file mode 100755
index 0000000000000000000000000000000000000000..51f15e31cac6752ef6db08298e32356d0b4d66b6
--- /dev/null
+++ b/gstlal-ugly/bin/gstlal_inspiral_best_coinc_file
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+import sys
+from ligo.lw import ligolw
+from ligo.lw import array as ligolw_array
+from ligo.lw import lsctables
+from ligo.lw import utils as ligolw_utils
+#from glue.ligolw import ligolw
+#from glue.ligolw import array as ligolw_array
+#from glue.ligolw import lsctables
+#from glue.ligolw import utils as ligolw_utils
+
+@ligolw_array.use_in
+@lsctables.use_in
+class ContentHandler(ligolw.LIGOLWContentHandler):
+	pass
+
+def get_snr(fname):
+	xmldoc = ligolw_utils.load_filename(fname, verbose = False, contenthandler = ContentHandler)
+	coinc_inspiral_table = lsctables.CoincInspiralTable.get_table(xmldoc)
+	assert len(coinc_inspiral_table) == 1
+	return coinc_inspiral_table[0].snr
+
+
+best = sys.argv[1]
+bestsnr = get_snr(sys.argv[1])
+for fname in sys.argv[2:]:
+	snr = get_snr(fname)
+	if snr > bestsnr:
+		bestsnr = snr
+		best = fname
+
+print best
+		
diff --git a/gstlal-ugly/bin/gstlal_ligolw_add_without_reassign b/gstlal-ugly/bin/gstlal_ligolw_add_without_reassign
new file mode 100755
index 0000000000000000000000000000000000000000..5fc63fddd112db6ba810bf400427d940ba25cc8f
--- /dev/null
+++ b/gstlal-ugly/bin/gstlal_ligolw_add_without_reassign
@@ -0,0 +1,167 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2005--2009,2012,2014,2015,2017  Kipp Cannon
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+
+#
+# =============================================================================
+#
+#                                   Preamble
+#
+# =============================================================================
+#
+
+
+"""
+Add (merge) LIGO LW XML files containing LSC tables.
+"""
+
+
+from optparse import OptionParser
+
+
+from lal.utils.cache import CacheEntry
+from ligo.lw import __version__, __date__
+from ligo.lw import ligolw
+from ligo.lw import array as ligolw_array
+from ligo.lw import lsctables
+from ligo.lw import utils as ligolw_utils
+from ligo.lw.utils import ligolw_add
+
+
+__author__ = "Kipp Cannon <kipp.cannon@ligo.org>"
+
+
+#
+# =============================================================================
+#
+#                                 Command Line
+#
+# =============================================================================
+#
+
+
+def parse_command_line():
+	"""
+	Parse the command line, return an options object and a list of URLs.
+	"""
+	parser = OptionParser(
+		version = "Name: %%prog\n%s" % __version__,
+		usage = "%prog [options] [url ...]",
+		description = "Combines one or more LIGO Light Weight XML files into a single output file.  The output is written to stdout or to the filename specified by --output.  In addition to regular files, many common URL types can be read such as http:// and ftp://.  Input documents that are gzip-compressed are automatically detected and decompressed.  If the output file's name ends in \".gz\", the output document will be gzip-compressed.  Table elements contained in the document will be merged so that there is not more than one table of any given name in the output.  To accomplish this, any tables in the input documents that share the same name must have compatible columns, meaning the same column names with matching types (but not necessarily in the same order)."
+	)
+	parser.add_option("-i", "--input-cache", metavar = "filename", action = "append", default = [], help = "Get input files from the LAL cache named filename.")
+	parser.add_option("--non-lsc-tables-ok", action = "store_true", help = "OK to merge documents containing non-LSC tables.")
+	parser.add_option("-o", "--output", metavar = "filename", help = "Write output to filename (default = stdout).")
+	parser.add_option("-v", "--verbose", action = "store_true", help = "Be verbose.")
+	parser.add_option("--remove-input", action = "store_true", help = "Remove input files after writing output (an attempt is made to not delete the output file in the event that it overwrote one of the input files).")
+	parser.add_option("--remove-input-except", metavar = "filename", action = "append", default = [], help = "When deleting input files, do not delete this file.")
+	options, urls = parser.parse_args()
+
+	urls += [CacheEntry(line).url for cache in options.input_cache for line in open(cache)]
+
+	if len(urls) < 1:
+		raise ValueError("no input files!")
+
+	return options, urls
+
+
+#
+# =============================================================================
+#
+#                                     Main
+#
+# =============================================================================
+#
+
+
+#
+# Command line
+#
+
+
+options, urls = parse_command_line()
+
+
+#
+# Input
+#
+
+
+@ligolw_array.use_in
+@lsctables.use_in
+class ContentHandler(ligolw.LIGOLWContentHandler):
+	pass
+
+def _ligolw_add(xmldoc, urls, non_lsc_tables_ok = False, verbose = False, contenthandler = ContentHandler, reassign_ids = True):
+	"""
+	An implementation of the LIGO LW add algorithm.  urls is a list of
+	URLs (or filenames) to load, xmldoc is the XML document tree to
+	which they should be added.
+	"""
+	# Input
+	for n, url in enumerate(urls, 1):
+		if verbose:
+			sys.stderr.write("%d/%d:" % (n, len(urls)))
+		ligolw_utils.load_url(url, verbose = verbose, xmldoc = xmldoc, contenthandler = contenthandler)
+
+	# ID reassignment
+	if not non_lsc_tables_ok and lsctables.HasNonLSCTables(xmldoc):
+		raise ValueError("non-LSC tables found.  Use --non-lsc-tables-ok to force")
+	if reassign_ids:
+		ligolw_add.reassign_ids(xmldoc, verbose = verbose)
+
+	# Document merge
+	if verbose:
+		sys.stderr.write("merging elements ...\n")
+	ligolw_add.merge_ligolws(xmldoc)
+	ligolw_add.merge_compatible_tables(xmldoc)
+
+	return xmldoc
+
+
+xmldoc = _ligolw_add(
+	ligolw.Document(),
+	urls,
+	non_lsc_tables_ok = options.non_lsc_tables_ok,
+	verbose = options.verbose,
+	contenthandler = ContentHandler,
+	reassign_ids = False
+)
+
+
+
+#
+# Output
+#
+
+
+ligolw_utils.write_filename(
+	xmldoc,
+	options.output,
+	verbose = options.verbose,
+	gz = (options.output or "stdout").endswith(".gz")
+)
+
+
+#
+# Remove input
+#
+
+
+if options.remove_input:
+	ligolw_add.remove_input(urls, [options.output] + options.remove_input_except, options.verbose)