Ejemplo n.º 1
0
	def add_contents(self, contents):
		offsetvectors = contents.time_slide_table.as_dict()
		for values in contents.connection.cursor().execute("""
SELECT
	*,
	EXISTS (
		SELECT
			*
		FROM
			sim_burst_map
			JOIN sngl_burst ON (
				sngl_burst.event_id == sim_burst_map.event_id
			)
		WHERE
			sim_burst_map.simulation_id == sim_burst.simulation_id
			AND sngl_burst.ifo == ?
	)
FROM
	sim_burst
		""", (self.instrument,)):
			sim = contents.sim_burst_table.row_from_cols(values)
			found = values[-1]
			if SimBurstUtils.injection_was_made(sim, contents.seglists, (self.instrument,)):
				self.num_injections += 1
				amplitude = self.amplitude_func(sim, self.instrument, offsetvectors[sim.time_slide_id])
				self.injected_x.append(sim.frequency)
				self.injected_y.append(amplitude)
				if not found:
					self.missed_x.append(sim.frequency)
					self.missed_y.append(amplitude)
    def add_contents(self, contents):
        offsetvectors = contents.time_slide_table.as_dict()
        for values in contents.connection.cursor().execute(
                """
SELECT
	*,
	EXISTS (
		SELECT
			*
		FROM
			sim_burst_map
			JOIN sngl_burst ON (
				sngl_burst.event_id == sim_burst_map.event_id
			)
		WHERE
			sim_burst_map.simulation_id == sim_burst.simulation_id
			AND sngl_burst.ifo == ?
	)
FROM
	sim_burst
		""", (self.instrument, )):
            sim = contents.sim_burst_table.row_from_cols(values)
            found = values[-1]
            if SimBurstUtils.injection_was_made(sim, contents.seglists,
                                                (self.instrument, )):
                self.num_injections += 1
                amplitude = self.amplitude_func(
                    sim, self.instrument, offsetvectors[sim.time_slide_id])
                self.injected_x.append(sim.frequency)
                self.injected_y.append(amplitude)
                if not found:
                    self.missed_x.append(sim.frequency)
                    self.missed_y.append(amplitude)
Ejemplo n.º 3
0
	def add_contents(self, contents):
		self.seglist |= contents.seglists[self.instrument]
		for values in contents.connection.cursor().execute("""
SELECT
	*,
	EXISTS (
		SELECT
			*
		FROM
			sim_burst_map
			JOIN sngl_burst ON (
				sngl_burst.event_id == sim_burst_map.event_id
			)
		WHERE
			sim_burst_map.simulation_id == sim_burst.simulation_id
			AND sngl_burst.ifo == ?
	)
FROM
	sim_burst
		""", (self.instrument,)):
			sim = contents.sim_burst_table.row_from_cols(values)
			found = values[-1]
			if SimBurstUtils.injection_was_made(sim, contents.seglists, (self.instrument,)):
				self.num_injections += 1
				peak = float(sim.time_at_instrument(self.instrument))
				self.injected_x.append(peak)
				self.injected_y.append(sim.frequency)
				if not found:
					self.missed_x.append(peak)
					self.missed_y.append(sim.frequency)
    def add_contents(self, contents):
        self.seglist |= contents.seglists[self.instrument]
        for values in contents.connection.cursor().execute(
                """
SELECT
	*,
	EXISTS (
		SELECT
			*
		FROM
			sim_burst_map
			JOIN sngl_burst ON (
				sngl_burst.event_id == sim_burst_map.event_id
			)
		WHERE
			sim_burst_map.simulation_id == sim_burst.simulation_id
			AND sngl_burst.ifo == ?
	)
FROM
	sim_burst
		""", (self.instrument, )):
            sim = contents.sim_burst_table.row_from_cols(values)
            found = values[-1]
            if SimBurstUtils.injection_was_made(sim, contents.seglists,
                                                (self.instrument, )):
                self.num_injections += 1
                peak = float(sim.time_at_instrument(self.instrument))
                self.injected_x.append(peak)
                self.injected_y.append(sim.frequency)
                if not found:
                    self.missed_x.append(peak)
                    self.missed_y.append(sim.frequency)
Ejemplo n.º 5
0
	def add_contents(self, contents, verbose = False):
		#
		# update segment information
		#

		self.seglists |= contents.seglists
		self.vetoseglists |= contents.vetoseglists
		seglists = contents.seglists - contents.vetoseglists
		if set(("H1", "H2")).issubset(set(seglists)):
			# we have segments for both H1 and H2, remove time
			# when exactly that pair are on
			seglists -= segments.segmentlistdict.fromkeys(seglists, seglists.intersection(("H1", "H2")) - seglists.union(set(seglists) - set(("H1", "H2"))))

		# for each injection, retrieve the highest likelihood ratio
		# of the burst coincs that were found to match the
		# injection or null if no burst coincs matched the
		# injection
		offsetvectors = contents.time_slide_table.as_dict()
		stringutils.create_recovered_ln_likelihood_ratio_table(contents.connection, contents.bb_definer_id)
		for values in contents.connection.cursor().execute("""
SELECT
	sim_burst.*,
	recovered_ln_likelihood_ratio.ln_likelihood_ratio
FROM
	sim_burst
	LEFT JOIN recovered_ln_likelihood_ratio ON (
		recovered_ln_likelihood_ratio.simulation_id == sim_burst.simulation_id
	)
		"""):
			sim = contents.sim_burst_table.row_from_cols(values[:-1])
			ln_likelihood_ratio = values[-1]
			found = ln_likelihood_ratio is not None
			# were at least 2 instruments on when the injection
			# was made?
			if len(SimBurstUtils.on_instruments(sim, seglists, offsetvectors[sim.time_slide_id])) >= 2:
				# yes
				self.all.append(sim)
				if found and ln_likelihood_ratio > self.detection_threshold:
					self.found.append(sim)
					# 1/amplitude needs to be first so
					# that it acts as the sort key
					record = (1.0 / sim.amplitude, sim, offsetvectors[sim.time_slide_id], contents.filename, ln_likelihood_ratio)
					if len(self.quietest_found) < self.n_diagnostics:
						heapq.heappush(self.quietest_found, record)
					else:
						heapq.heappushpop(self.quietest_found, record)
				else:
					# amplitude needs to be first so
					# that it acts as the sort key
					record = (sim.amplitude, sim, offsetvectors[sim.time_slide_id], contents.filename, ln_likelihood_ratio)
					if len(self.loudest_missed) < self.n_diagnostics:
						heapq.heappush(self.loudest_missed, record)
					else:
						heapq.heappushpop(self.loudest_missed, record)
			elif found:
				# no, but it was found anyway
				print("%s: odd, injection %s was found but not injected ..." % (contents.filename, sim.simulation_id), file=sys.stderr)
Ejemplo n.º 6
0
	def add_contents(self, contents, verbose = False):
		#
		# update segment information
		#

		self.seglists |= contents.seglists
		self.vetoseglists |= contents.vetoseglists
		seglists = contents.seglists - contents.vetoseglists
		if set(("H1", "H2")).issubset(set(seglists)):
			# we have segments for both H1 and H2, remove time
			# when exactly that pair are on
			seglists -= segments.segmentlistdict.fromkeys(seglists, seglists.intersection(("H1", "H2")) - seglists.union(set(seglists) - set(("H1", "H2"))))

		# for each injection, retrieve the highest likelihood ratio
		# of the burst coincs that were found to match the
		# injection or null if no burst coincs matched the
		# injection
		offsetvectors = contents.time_slide_table.as_dict()
		stringutils.create_recovered_likelihood_table(contents.connection, contents.bb_definer_id)
		for values in contents.connection.cursor().execute("""
SELECT
	sim_burst.*,
	recovered_likelihood.likelihood
FROM
	sim_burst
	LEFT JOIN recovered_likelihood ON (
		recovered_likelihood.simulation_id == sim_burst.simulation_id
	)
		"""):
			sim = contents.sim_burst_table.row_from_cols(values[:-1])
			likelihood_ratio = values[-1]
			found = likelihood_ratio is not None
			# were at least 2 instruments on when the injection
			# was made?
			if len(SimBurstUtils.on_instruments(sim, seglists, offsetvectors[sim.time_slide_id])) >= 2:
				# yes
				self.all.append(sim)
				if found and likelihood_ratio > self.detection_threshold:
					self.found.append(sim)
					# 1/amplitude needs to be first so
					# that it acts as the sort key
					record = (1.0 / sim.amplitude, sim, offsetvectors[sim.time_slide_id], contents.filename, likelihood_ratio)
					if len(self.quietest_found) < self.n_diagnostics:
						heapq.heappush(self.quietest_found, record)
					else:
						heapq.heappushpop(self.quietest_found, record)
				else:
					# amplitude needs to be first so
					# that it acts as the sort key
					record = (sim.amplitude, sim, offsetvectors[sim.time_slide_id], contents.filename, likelihood_ratio)
					if len(self.loudest_missed) < self.n_diagnostics:
						heapq.heappush(self.loudest_missed, record)
					else:
						heapq.heappushpop(self.loudest_missed, record)
			elif found:
				# no, but it was found anyway
				print >>sys.stderr, "%s: odd, injection %s was found but not injected ..." % (contents.filename, sim.simulation_id)
Ejemplo n.º 7
0
def new_plots(instrument, amplitude_func, amplitude_lbl, plots):
	l = (
		FreqVsTime(instrument),
		HrssVsFreqScatter(instrument, amplitude_func, amplitude_lbl),
		SimBurstUtils.Efficiency_hrss_vs_freq((instrument,), amplitude_func, amplitude_lbl, 0.1),
		TriggerCountHistogram(instrument),
		RecoveredVsInjectedhrss(instrument, amplitude_func, amplitude_lbl),
		RecoveredPerInjectedhrssVsFreq(instrument, amplitude_func, amplitude_lbl),
		RecoveredPerInjectedhrssVsBandwidth(instrument, amplitude_func, amplitude_lbl),
		RecoveredTimeOffset(instrument, segments.segment(-0.03, +0.03), 0.00015),
		RecoveredFrequencyOffset(instrument, segments.segment(-1.0, +1.0), .002),
		RecoveredVsInjectedFreq(instrument, amplitude_func)
	)
	return [l[i] for i in plots]
Ejemplo n.º 8
0
def plot_efficiency_data(efficiency_data):
	print("plotting efficiency curves ...", file=sys.stderr)

	# use the stock plotting routing in SimBurstUtils for the
	# efficiency contour plot

	fig = SimBurstUtils.plot_Efficiency_hrss_vs_freq(efficiency_data)
	#fig.gca().set_ylim((3e-17, 3e-10))

	# done

	#print >>sys.stderr, "writing lalapps_excesspowerfinal_efficiency.pdf ..."
	#fig.savefig("lalapps_excesspowerfinal_efficiency.pdf")
	print("writing lalapps_excesspowerfinal_efficiency.png ...", file=sys.stderr)
	fig.savefig("lalapps_excesspowerfinal_efficiency.png")
Ejemplo n.º 9
0
def plot_efficiency_data(efficiency_data):
	print >>sys.stderr, "plotting efficiency curves ..."

	# use the stock plotting routing in SimBurstUtils for the
	# efficiency contour plot

	fig = SimBurstUtils.plot_Efficiency_hrss_vs_freq(efficiency_data)
	#fig.gca().set_ylim((3e-17, 3e-10))

	# done

	#print >>sys.stderr, "writing lalapps_excesspowerfinal_efficiency.pdf ..."
	#fig.savefig("lalapps_excesspowerfinal_efficiency.pdf")
	print >>sys.stderr, "writing lalapps_excesspowerfinal_efficiency.png ..."
	fig.savefig("lalapps_excesspowerfinal_efficiency.png")
Ejemplo n.º 10
0
	def add_contents(self, contents, threshold):
		if self.instruments != contents.instruments:
			raise ValueError("this document contains instruments %s, but we want %s" % ("+".join(contents.instruments), "+".join(self.instruments)))

		# iterate over all sims

		offsetvectors = contents.time_slide_table.as_dict()
		create_sim_coinc_map_view(contents.connection)
		for values in contents.connection.cursor().execute("""
SELECT
	sim_burst.*,
	(
		SELECT
			MAX(sim_coinc_map.burst_coinc_amplitude)
		FROM
			sim_coinc_map
		WHERE
			sim_coinc_map.simulation_id == sim_burst.simulation_id
			AND sim_coinc_map.sim_coinc_def_id == ?
	)
FROM
	sim_burst
		""", (contents.scn_definer_id,)):
			sim = contents.sim_burst_table.row_from_cols(values)
			detection_statistic = values[-1]
			amplitude = self.amplitude_func(sim, None)
			if SimBurstUtils.on_instruments(sim, contents.seglists, offsetvectors[sim.time_slide_id]) == self.instruments:
				# injection was made
				self.injected_x.append(sim.frequency)
				self.injected_y.append(amplitude)
				if detection_statistic is not None:
					# injection was recovered (found at
					# all)
					self.recovered_xyz.append((sim.frequency, amplitude, detection_statistic))
					if detection_statistic > threshold:
						# injection was found above
						# threshold
						self.found_x.append(sim.frequency)
						self.found_y.append(amplitude)
			elif (detection_statistic is not None) and (detection_statistic > threshold):
				# injection was found, and found above
				# threshold, but not "injected" because it
				# lies outside of the output segments.
				# this is not unusual, in particular
				# because we are only looking for coincs
				# that are "nearby" an injection which can
				# mean several seconds.
				print("odd, injection %s was found but not injected ..." % sim.simulation_id, file=sys.stderr)
Ejemplo n.º 11
0
	def add_contents(self, contents, threshold):
		if self.instruments != contents.instruments:
			raise ValueError("this document contains instruments %s, but we want %s" % ("+".join(contents.instruments), "+".join(self.instruments)))

		# iterate over all sims

		offsetvectors = contents.time_slide_table.as_dict()
		create_sim_coinc_map_view(contents.connection)
		for values in contents.connection.cursor().execute("""
SELECT
	sim_burst.*,
	(
		SELECT
			MAX(sim_coinc_map.burst_coinc_amplitude)
		FROM
			sim_coinc_map
		WHERE
			sim_coinc_map.simulation_id == sim_burst.simulation_id
			AND sim_coinc_map.sim_coinc_def_id == ?
	)
FROM
	sim_burst
		""", (contents.scn_definer_id,)):
			sim = contents.sim_burst_table.row_from_cols(values)
			detection_statistic = values[-1]
			amplitude = self.amplitude_func(sim, None)
			if SimBurstUtils.on_instruments(sim, contents.seglists, offsetvectors[sim.time_slide_id]) == self.instruments:
				# injection was made
				self.injected_x.append(sim.frequency)
				self.injected_y.append(amplitude)
				if detection_statistic is not None:
					# injection was recovered (found at
					# all)
					self.recovered_xyz.append((sim.frequency, amplitude, detection_statistic))
					if detection_statistic > threshold:
						# injection was found above
						# threshold
						self.found_x.append(sim.frequency)
						self.found_y.append(amplitude)
			elif (detection_statistic is not None) and (detection_statistic > threshold):
				# injection was found, and found above
				# threshold, but not "injected" because it
				# lies outside of the output segments.
				# this is not unusual, in particular
				# because we are only looking for coincs
				# that are "nearby" an injection which can
				# mean several seconds.
				print >>sys.stderr, "odd, injection %s was found but not injected ..." % sim.simulation_id
Ejemplo n.º 12
0

efficiencies = []
for instrument in plots:
	n = 0
	format = "%%s%s_%%0%dd.%%s" % (instrument, int(math.log10(max(options.plot) or 1)) + 1)
	while len(plots[instrument]):
		plot = plots[instrument].pop(0)
		filename = format % (options.base, options.plot[n], options.format)
		if options.verbose:
			print("finishing %s plot %d ..." % (instrument, options.plot[n]), file=sys.stderr)
		try:
			if isinstance(plot, SimBurstUtils.Efficiency_hrss_vs_freq):
				plot.finish(binning = binning)
				efficiencies.append(plot)
				fig = SimBurstUtils.plot_Efficiency_hrss_vs_freq(plot)
			else:
				plot.finish()
				fig = plot.fig
		except ValueError as e:
			print("can't finish %s plot %d: %s" % (instrument, options.plot[n], str(e)), file=sys.stderr)
		else:
			if options.verbose:
				print("writing %s ..." % filename, file=sys.stderr)
			fig.savefig(filename)
		n += 1


#
# finish and write coinc plots, deleting them as we go to save memory
#
def new_coinc_plots(instruments, amplitude_func, amplitude_lbl, plots):
    l = (SimBurstUtils.Efficiency_hrss_vs_freq(instruments, amplitude_func,
                                               amplitude_lbl, 0.1),
         CoincRecoveredVsInjectedFreq(instruments))
    return [l[i] for i in plots]
efficiencies = []
for instrument in plots:
    n = 0
    format = "%%s%s_%%0%dd.%%s" % (instrument,
                                   int(math.log10(max(options.plot) or 1)) + 1)
    while len(plots[instrument]):
        plot = plots[instrument].pop(0)
        filename = format % (options.base, options.plot[n], options.format)
        if options.verbose:
            print("finishing %s plot %d ..." % (instrument, options.plot[n]),
                  file=sys.stderr)
        try:
            if isinstance(plot, SimBurstUtils.Efficiency_hrss_vs_freq):
                plot.finish(binning=binning)
                efficiencies.append(plot)
                fig = SimBurstUtils.plot_Efficiency_hrss_vs_freq(plot)
            else:
                plot.finish()
                fig = plot.fig
        except ValueError as e:
            print("can't finish %s plot %d: %s" %
                  (instrument, options.plot[n], str(e)),
                  file=sys.stderr)
        else:
            if options.verbose:
                print("writing %s ..." % filename, file=sys.stderr)
            fig.savefig(filename)
        n += 1

#
# finish and write coinc plots, deleting them as we go to save memory
Ejemplo n.º 15
0
	def finish(self):
		fig, axes = SnglBurstUtils.make_burst_plot(r"Injection Amplitude (\(\mathrm{s}^{-\frac{1}{3}}\))", "Detection Efficiency", width = 108.0)
		axes.set_title(r"Detection Efficiency vs.\ Amplitude")
		axes.semilogx()
		axes.set_position([0.10, 0.150, 0.86, 0.77])

		# set desired yticks
		axes.set_yticks((0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0))
		axes.set_yticklabels((r"\(0\)", r"\(0.1\)", r"\(0.2\)", r"\(0.3\)", r"\(0.4\)", r"\(0.5\)", r"\(0.6\)", r"\(0.7\)", r"\(0.8\)", r"\(0.9\)", r"\(1.0\)"))
		axes.xaxis.grid(True, which = "major,minor")
		axes.yaxis.grid(True, which = "major,minor")

		# put made and found injections in the denominators and
		# numerators of the efficiency bins
		bins = rate.NDBins((rate.LogarithmicBins(min(sim.amplitude for sim in self.all), max(sim.amplitude for sim in self.all), 400),))
		efficiency_num = rate.BinnedArray(bins)
		efficiency_den = rate.BinnedArray(bins)
		for sim in self.found:
			efficiency_num[sim.amplitude,] += 1
		for sim in self.all:
			efficiency_den[sim.amplitude,] += 1

		# generate and plot trend curves.  adjust window function
		# normalization so that denominator array correctly
		# represents the number of injections contributing to each
		# bin:  make w(0) = 1.0.  note that this factor has no
		# effect on the efficiency because it is common to the
		# numerator and denominator arrays.  we do this for the
		# purpose of computing the Poisson error bars, which
		# requires us to know the counts for the bins
		windowfunc = rate.gaussian_window(self.filter_width)
		windowfunc /= windowfunc[len(windowfunc) / 2 + 1]
		rate.filter_array(efficiency_num.array, windowfunc)
		rate.filter_array(efficiency_den.array, windowfunc)

		# regularize:  adjust unused bins so that the efficiency is
		# 0, not NaN
		assert (efficiency_num.array <= efficiency_den.array).all()
		efficiency_den.array[(efficiency_num.array == 0) & (efficiency_den.array == 0)] = 1

		line1, A50, A50_err = render_data_from_bins(file("string_efficiency.dat", "w"), axes, efficiency_num, efficiency_den, self.cal_uncertainty, self.filter_width, colour = "k", linestyle = "-", erroralpha = 0.2)
		print("Pipeline's 50%% efficiency point for all detections = %g +/- %g%%\n" % (A50, A50_err * 100), file=sys.stderr)

		# add a legend to the axes
		axes.legend((line1,), (r"\noindent Injections recovered with $\log \Lambda > %.2f$" % self.detection_threshold,), loc = "lower right")

		# adjust limits
		axes.set_xlim([3e-22, 3e-19])
		axes.set_ylim([0.0, 1.0])

		#
		# dump some information about the highest-amplitude missed
		# and quietest-amplitude found injections
		#

		self.loudest_missed.sort(reverse = True)
		self.quietest_found.sort(reverse = True)

		f = file("string_loud_missed_injections.txt", "w")
		print("Highest Amplitude Missed Injections", file=f)
		print("===================================", file=f)
		for amplitude, sim, offsetvector, filename, ln_likelihood_ratio in self.loudest_missed:
			print(file=f)
			print("%s in %s:" % (str(sim.simulation_id), filename), file=f)
			if ln_likelihood_ratio is None:
				print("Not recovered", file=f)
			else:
				print("Recovered with \\log \\Lambda = %.16g, detection threshold was %.16g" % (ln_likelihood_ratio, self.detection_threshold), file=f)
			for instrument in self.seglists:
				print("In %s:" % instrument, file=f)
				print("\tInjected amplitude:\t%.16g" % SimBurstUtils.string_amplitude_in_instrument(sim, instrument, offsetvector), file=f)
				print("\tTime of injection:\t%s s" % sim.time_at_instrument(instrument, offsetvector), file=f)
			print("Amplitude in waveframe:\t%.16g" % sim.amplitude, file=f)
			t = sim.get_time_geocent()
			print("Time at geocentre:\t%s s" % t, file=f)
			print("Segments within 60 seconds:\t%s" % segmentsUtils.segmentlistdict_to_short_string(self.seglists & segments.segmentlistdict((instrument, segments.segmentlist([segments.segment(t-offsetvector[instrument]-60, t-offsetvector[instrument]+60)])) for instrument in self.seglists)), file=f)
			print("Vetoes within 60 seconds:\t%s" % segmentsUtils.segmentlistdict_to_short_string(self.vetoseglists & segments.segmentlistdict((instrument, segments.segmentlist([segments.segment(t-offsetvector[instrument]-60, t-offsetvector[instrument]+60)])) for instrument in self.vetoseglists)), file=f)

		f = file("string_quiet_found_injections.txt", "w")
		print("Lowest Amplitude Found Injections", file=f)
		print("=================================", file=f)
		for inv_amplitude, sim, offsetvector, filename, ln_likelihood_ratio in self.quietest_found:
			print(file=f)
			print("%s in %s:" % (str(sim.simulation_id), filename), file=f)
			if ln_likelihood_ratio is None:
				print("Not recovered", file=f)
			else:
				print("Recovered with \\log \\Lambda = %.16g, detection threshold was %.16g" % (ln_likelihood_ratio, self.detection_threshold), file=f)
			for instrument in self.seglists:
				print("In %s:" % instrument, file=f)
				print("\tInjected amplitude:\t%.16g" % SimBurstUtils.string_amplitude_in_instrument(sim, instrument, offsetvector), file=f)
				print("\tTime of injection:\t%s s" % sim.time_at_instrument(instrument, offsetvector), file=f)
			print("Amplitude in waveframe:\t%.16g" % sim.amplitude, file=f)
			t = sim.get_time_geocent()
			print("Time at geocentre:\t%s s" % t, file=f)
			print("Segments within 60 seconds:\t%s" % segmentsUtils.segmentlistdict_to_short_string(self.seglists & segments.segmentlistdict((instrument, segments.segmentlist([segments.segment(t-offsetvector[instrument]-60, t-offsetvector[instrument]+60)])) for instrument in self.seglists)), file=f)
			print("Vetoes within 60 seconds:\t%s" % segmentsUtils.segmentlistdict_to_short_string(self.vetoseglists & segments.segmentlistdict((instrument, segments.segmentlist([segments.segment(t-offsetvector[instrument]-60, t-offsetvector[instrument]+60)])) for instrument in self.vetoseglists)), file=f)

		#
		# done
		#

		return fig,
Ejemplo n.º 16
0
	def finish(self):
		fig, axes = SnglBurstUtils.make_burst_plot(r"Injection Amplitude (\(\mathrm{s}^{-\frac{1}{3}}\))", "Detection Efficiency", width = 108.0)
		axes.set_title(r"Detection Efficiency vs.\ Amplitude")
		axes.semilogx()
		axes.set_position([0.10, 0.150, 0.86, 0.77])

		# set desired yticks
		axes.set_yticks((0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0))
		axes.set_yticklabels((r"\(0\)", r"\(0.1\)", r"\(0.2\)", r"\(0.3\)", r"\(0.4\)", r"\(0.5\)", r"\(0.6\)", r"\(0.7\)", r"\(0.8\)", r"\(0.9\)", r"\(1.0\)"))
		axes.xaxis.grid(True, which = "major,minor")
		axes.yaxis.grid(True, which = "major,minor")

		# put made and found injections in the denominators and
		# numerators of the efficiency bins
		bins = rate.NDBins((rate.LogarithmicBins(min(sim.amplitude for sim in self.all), max(sim.amplitude for sim in self.all), 400),))
		efficiency_num = rate.BinnedArray(bins)
		efficiency_den = rate.BinnedArray(bins)
		for sim in self.found:
			efficiency_num[sim.amplitude,] += 1
		for sim in self.all:
			efficiency_den[sim.amplitude,] += 1

		# generate and plot trend curves.  adjust window function
		# normalization so that denominator array correctly
		# represents the number of injections contributing to each
		# bin:  make w(0) = 1.0.  note that this factor has no
		# effect on the efficiency because it is common to the
		# numerator and denominator arrays.  we do this for the
		# purpose of computing the Poisson error bars, which
		# requires us to know the counts for the bins
		windowfunc = rate.gaussian_window(self.filter_width)
		windowfunc /= windowfunc[len(windowfunc) / 2 + 1]
		rate.filter_binned_array(efficiency_num, windowfunc)
		rate.filter_binned_array(efficiency_den, windowfunc)

		# regularize:  adjust unused bins so that the efficiency is
		# 0, not NaN
		assert (efficiency_num <= efficiency_den).all()
		efficiency_den[efficiency_num == 0 & efficiency_den == 0] = 1

		line1, A50, A50_err = render_data_from_bins(file("string_efficiency.dat", "w"), axes, efficiency_num, efficiency_den, self.cal_uncertainty, self.filter_width, colour = "k", linestyle = "-", erroralpha = 0.2)
		print >>sys.stderr, "Pipeline's 50%% efficiency point for all detections = %g +/- %g%%\n" % (A50, A50_err * 100)

		# add a legend to the axes
		axes.legend((line1,), (r"\noindent Injections recovered with $\Lambda > %s$" % SnglBurstUtils.latexnumber("%.2e" % self.detection_threshold),), loc = "lower right")

		# adjust limits
		axes.set_xlim([1e-21, 2e-18])
		axes.set_ylim([0.0, 1.0])

		#
		# dump some information about the highest-amplitude missed
		# and quietest-amplitude found injections
		#

		self.loudest_missed.sort(reverse = True)
		self.quietest_found.sort(reverse = True)

		f = file("string_loud_missed_injections.txt", "w")
		print >>f, "Highest Amplitude Missed Injections"
		print >>f, "==================================="
		for amplitude, sim, offsetvector, filename, likelihood_ratio in self.loudest_missed:
			print >>f
			print >>f, "%s in %s:" % (str(sim.simulation_id), filename)
			if likelihood_ratio is None:
				print >>f, "Not recovered"
			else:
				print >>f, "Recovered with \\Lambda = %.16g, detection threshold was %.16g" % (likelihood_ratio, self.detection_threshold)
			for instrument in self.seglists:
				print >>f, "In %s:" % instrument
				print >>f, "\tInjected amplitude:\t%.16g" % SimBurstUtils.string_amplitude_in_instrument(sim, instrument, offsetvector)
				print >>f, "\tTime of injection:\t%s s" % sim.time_at_instrument(instrument, offsetvector)
			print >>f, "Amplitude in waveframe:\t%.16g" % sim.amplitude
			t = sim.get_time_geocent()
			print >>f, "Time at geocentre:\t%s s" % t
			print >>f, "Segments within 60 seconds:\t%s" % segmentsUtils.segmentlistdict_to_short_string(self.seglists & segments.segmentlistdict((instrument, segments.segmentlist([segments.segment(t-offsetvector[instrument]-60, t-offsetvector[instrument]+60)])) for instrument in self.seglists))
			print >>f, "Vetoes within 60 seconds:\t%s" % segmentsUtils.segmentlistdict_to_short_string(self.vetoseglists & segments.segmentlistdict((instrument, segments.segmentlist([segments.segment(t-offsetvector[instrument]-60, t-offsetvector[instrument]+60)])) for instrument in self.vetoseglists))

		f = file("string_quiet_found_injections.txt", "w")
		print >>f, "Lowest Amplitude Found Injections"
		print >>f, "================================="
		for inv_amplitude, sim, offsetvector, filename, likelihood_ratio in self.quietest_found:
			print >>f
			print >>f, "%s in %s:" % (str(sim.simulation_id), filename)
			if likelihood_ratio is None:
				print >>f, "Not recovered"
			else:
				print >>f, "Recovered with \\Lambda = %.16g, detection threshold was %.16g" % (likelihood_ratio, self.detection_threshold)
			for instrument in self.seglists:
				print >>f, "In %s:" % instrument
				print >>f, "\tInjected amplitude:\t%.16g" % SimBurstUtils.string_amplitude_in_instrument(sim, instrument, offsetvector)
				print >>f, "\tTime of injection:\t%s s" % sim.time_at_instrument(instrument, offsetvector)
			print >>f, "Amplitude in waveframe:\t%.16g" % sim.amplitude
			t = sim.get_time_geocent()
			print >>f, "Time at geocentre:\t%s s" % t
			print >>f, "Segments within 60 seconds:\t%s" % segmentsUtils.segmentlistdict_to_short_string(self.seglists & segments.segmentlistdict((instrument, segments.segmentlist([segments.segment(t-offsetvector[instrument]-60, t-offsetvector[instrument]+60)])) for instrument in self.seglists))
			print >>f, "Vetoes within 60 seconds:\t%s" % segmentsUtils.segmentlistdict_to_short_string(self.vetoseglists & segments.segmentlistdict((instrument, segments.segmentlist([segments.segment(t-offsetvector[instrument]-60, t-offsetvector[instrument]+60)])) for instrument in self.vetoseglists))

		#
		# done
		#

		return fig,