diff --git a/gstlal-burst/bin/gstlal_cherenkov_burst b/gstlal-burst/bin/gstlal_cherenkov_burst
index bbae89996a054ee4fbabe6516537611cbee1e599..993404d23bf193d7afdbc1aefd1cfb92461eb2b3 100755
--- a/gstlal-burst/bin/gstlal_cherenkov_burst
+++ b/gstlal-burst/bin/gstlal_cherenkov_burst
@@ -116,7 +116,7 @@ def parse_command_line():
 	parser.add_option("--reference-psd", metavar = "filename", help = "Use fixed PSDs from this file (one for each detector) instead of measuring them from the data.  Optional.")
 	parser.add_option("--output", metavar = "filename", help = "Name of output xml file.")
 	parser.add_option("--rankingstat-output", metavar = "filename", help = "Name of output xml file to record rankingstat object.")
-	parser.add_option("--threshold", metavar = "snr_threshold", type = "float", default = 4.0, help = "SNR threshold (default = 4.0).")
+	parser.add_option("--threshold", metavar = "snr_threshold", type = "float", default = 3.0, help = "SNR threshold (default = 3.0).")
 	parser.add_option("--cluster-events", metavar = "cluster_events", type = "float", default = 0.1, help = "Cluster events with input timescale in seconds (default = 0.1).")
 	parser.add_option("--min-instruments", metavar = "min_instruments", type = "int", default = 2, help = "Minimum number of instruments (default is 2).")
 	parser.add_option("--snr-dump", metavar = "start,stop", help = "Turn on SNR time series dumping to a text file within the GPS time range [start, stop).")
@@ -133,7 +133,7 @@ def parse_command_line():
 	required_options = set(("template_bank", "time_slide_file", "output", "rankingstat_output"))
 	missing_options = set(option for option in required_options if getattr(options, option) is None)
 	if missing_options:
-		raise ValueError("missing required option(s) %s" % ", ".join("--%s" % option.subst("_", "-") for option in (required_options - missing_options)))
+		raise ValueError("missing required option(s) %s" % ", ".join("--%s" % option.replace("_", "-") for option in (required_options - missing_options)))
 
 	options.gps_start_time = lal.LIGOTimeGPS(options.gps_start_time)
 	options.gps_end_time = lal.LIGOTimeGPS(options.gps_end_time)
@@ -145,6 +145,7 @@ def parse_command_line():
 
 	if options.hoft_dump is not None:
 		options.hoft_dump = segments.segment(*map(lal.LIGOTimeGPS, options.hoft_dump.split(",")))
+
 	return options, process_params, datasourceinfo, filenames
 
 
@@ -258,7 +259,7 @@ class PipelineHandler(simplehandler.Handler):
 		# make templates, whiten, put into firbank
 		for i, row in enumerate(self.template_bank):
 			# obtain cherenkov radiation-like waveform. Since this wave form is linealy polarized, only the plus mode will be considered.
-			template_t[i], _ = lalsimulation.SimBurstCherenkovRadiation(row.central_freq, row.bandwidth, row.amplitude, 1.0 / sample_rate)
+			template_t[i], _ = lalsimulation.SimBurstCherenkovRadiation(row.bandwidth, 1.0, 1.0 / sample_rate)
 
 			# Resize the template as its deltaF matches to the PSD.
 			assert template_t[i].data.length <= fir_length, "data length is too huge comparted to the zero pad."
@@ -504,7 +505,7 @@ for instrument in all_inst:
 
 
 	with tempfile.NamedTemporaryFile(suffix = ".xml.gz") as fp:
-		template_bank.getColumnByName("ifo")[:] = [instrument for i in range(len(template_bank))]
+		template_bank.getColumnByName("ifo")[:] = [instrument] * len(template_bank)
 		xmldoc = ligolw.Document()
 		xmldoc.appendChild(ligolw.LIGO_LW())
 		xmldoc.childNodes[-1].appendChild(template_bank)
diff --git a/gstlal-burst/bin/gstlal_cherenkov_inj b/gstlal-burst/bin/gstlal_cherenkov_inj
index 3fe8a7a3ba3661e4dc4cea9074b2ca1c410143d7..bccd52db442d4a70c44c6aaf1c5874691ec901d2 100755
--- a/gstlal-burst/bin/gstlal_cherenkov_inj
+++ b/gstlal-burst/bin/gstlal_cherenkov_inj
@@ -66,9 +66,12 @@ def parse_command_line():
 		description = "GstLAL-based cherenkov burst injection pipeline."
 	)
 	parser.add_option("--dEoverdA", type = "float", help = "Set dEoverdA. Non input of this generates uniform random amplitude.")
-	parser.add_option("--gps-geocent-time", metavar = "s", help = "Set the start time of the tiling in GPS seconds (required).")
 	parser.add_option("--deltaT", metavar = "s", default = 0, type = "float", help = "Set the time interval of injections. Default value is 0 for injecting only one.")
-	parser.add_option("--num", type = "int", default = 1, help = "Set the number of injections. Default value is 1.")
+	parser.add_option("--start", type = "float", help = "start gps time of the injection. Non input will generate the injection in whole segements.")
+	parser.add_option("--stop", type = "float", help = "end gps time of the injection. Non input will generate the injection in whole segements.")
+	parser.add_option("--min-instruments", metavar = "num", default = 1, type = "int", help = "When constructing the segment list, require at least this many instruments to be on (default = 1).  See also --segments-file and --segments-name.")
+	parser.add_option("--segments-file", metavar = "filename", help = "Load the segment list for the injections from this file (required).  See also --segments-name and --min-instruments.")
+	parser.add_option("--segments-name", metavar = "name", default = "datasegments", help = "Use the segments with this name in the segments file (default = \"datasegments\")).  See also --segments-file and --min-instruments")
 	parser.add_option("--time-slide-file", metavar = "filename", help = "Associate injections with the first time slide ID in this XML file (required).")
 	parser.add_option("--output", metavar = "filename", help = "Set the name of the output file (default = stdout).")
 	parser.add_option("--verbose", action = "store_true", help = "Be verbose.")
@@ -78,14 +81,11 @@ def parse_command_line():
 	process_params = dict(options.__dict__)
 
 	# check for params
-	required_options = set(("output", "time_slide_file", "gps_geocent_time"))
+	required_options = set(("min_instruments", "segments_file", "segments_name", "output", "time_slide_file"))
 	missing_options = set(option for option in required_options if getattr(options, option) is None)
 	if missing_options:
 		raise ValueError("missing required option(s) %s" % ", ".join("--%s" % option.replace("_", "-") for option in missing_options))
 
-	# type-cast
-	options.gps_geocent_time = lal.LIGOTimeGPS(options.gps_geocent_time)
-
 	return options, process_params, filenames
 
 
@@ -124,8 +124,34 @@ process = ligolw_process.register_to_xmldoc(xmldoc, "cherenkov_burst_inj", proce
 
 time_slide_table = lsctables.TimeSlideTable.get_table(xmldoc)
 time_slide_id = time_slide_table[0].time_slide_id
+offset_vector = time_slide_table.as_dict()[time_slide_id]
 if options.verbose:
-	print("associating injections with time slide (%d) %s" % (time_slide_id, time_slide_table.as_dict()[time_slide_id]), file = sys.stderr)
+	print("associating injections with time slide (%d) %s" % (time_slide_id, offset_vector), file = sys.stderr)
+
+#
+# construct the segment list for injection times
+#
+
+
+segmentlists = ligolw_segments.segmenttable_get_by_name(ligolw_utils.load_filename(options.segments_file, contenthandler = LIGOLWContentHandler, verbose = options.verbose), options.segments_name)
+segmentlists.coalesce()
+
+if set(segmentlists) != set(offset_vector):
+	raise ValueError("time slide had instruments %s but segment list has instruments %$.  must be the same." % (", ".join(sorted(offset_vector)), ", ".join(sorted(segmentlists))))
+
+# injections are done so that they are coincident when the data has the
+# given offset vector applied.  so we apply the offset vector to the
+# segment lists, determine when the number of on instruments meets the
+# --min-instruments criterion, and then *without restoring the offsets* use
+# that segment list for the injections.  when, later, the injection code
+# performs these injections the injection times will have the opposite time
+# shift applied which will place them back into the available segments in
+# the respective detectors.
+
+segmentlists.offsets.update(offset_vector)
+segmentlist = segments_utils.vote(segmentlists.values(), options.min_instruments)
+if not abs(segmentlist):
+	raise ValueError("the --min-instruments criterion cannot be satisfied")
 
 
 #
@@ -148,7 +174,19 @@ sim_burst_tbl = xmldoc.childNodes[-1].appendChild(lsctables.New(lsctables.SimBur
 # populate the sim_burst table with injections
 #
 
-for i in range(options.num):
+if options.start is None and options.stop is None:
+	start, stop = segmentlist.extent()
+else:
+	start = options.start
+	stop = options.stop
+for i in range(math.ceil(float(start) / options.deltaT), math.ceil(float(stop) / options.deltaT)):
+	# we use floating point arithmetic to compute the times because we
+	# don't really care when they occur, not to the nanosecond.
+	time_geocent = lal.LIGOTimeGPS(i * options.deltaT)
+	# skip injections outside the desired segments
+	if time_geocent not in segmentlist:
+		continue
+	# add an injection at the desired time
 	sim_burst_tbl.append(sim_burst_tbl.RowType(
 		# metadata
 		process_id = process.process_id,
@@ -157,10 +195,10 @@ for i in range(options.num):
 		waveform = "Cherenkov",
 
 		# waveform parameters
-		time_geocent = options.gps_geocent_time + i * options.deltaT,
+		time_geocent = time_geocent,
 		frequency = math.nan,
 		# bandwidth parameter is actually not used. Hence, the length of Enterprise in StarTrek.is inputted as a fixed parameter.
-		bandwidth = 642.,
+		bandwidth = 641.,
 		egw_over_rsquared = math.nan,
 
 		# sky location and polarization axis orientation
@@ -171,7 +209,7 @@ for i in range(options.num):
 		# unnecessary columns
 		waveform_number = 0.,
 		# Create the uniform and random amplitude in log10.
-		amplitude = pow(10, random.uniform(-1, 4.5)) if options.dEoverdA is None else options.dEoverdA,
+		amplitude = pow(10, random.uniform(-1., 5.)) if options.dEoverdA is None else options.dEoverdA,
 		duration = math.nan,
 		q = math.nan,
 		hrss = math.nan,
diff --git a/gstlal-burst/bin/gstlal_cherenkov_plot_rankingstat b/gstlal-burst/bin/gstlal_cherenkov_plot_rankingstat
index 93aab8013a4e63491819b2825ca966b4ba6191bf..e66ab82acaad9783c27e0fac49e8977d3a0cf15d 100755
--- a/gstlal-burst/bin/gstlal_cherenkov_plot_rankingstat
+++ b/gstlal-burst/bin/gstlal_cherenkov_plot_rankingstat
@@ -70,12 +70,24 @@ def parse_command_line():
 		description = "GstLAL-based cherenkov burst ranking statistic plotting tool."
 	)
 	parser.add_option("--ranking-stat-cache", metavar = "filename", help = "Also load the ranking statistic likelihood ratio data files listed in this LAL cache.  See lalapps_path2cache for information on how to produce a LAL cache file.")
+	parser.add_option("--instrument", type = "string", help = "choose the instrument for the pdf calculation.")
+	parser.add_option("--width", type = "float", help = "width of the gaussian distribution in rankingstat in log scale.")
+	parser.add_option("--slope", type = "float", help = "slope of the pdf in the region where gaussian noise is dominant.")
+	parser.add_option("--threshold", type = "float", help = "threshold of the SNR where the dominance changes.")
+	parser.add_option("--matching", type = "float", help = "The chi^2 / rho value when the unmatch between template and injections become dominant.")
 	parser.add_option("--output", metavar = "string", help = "Name of output png.")
 	parser.add_option("-v", "--verbose", action = "store_true", help = "Be verbose.")
+	parser.add_option("--is-calculate", action = "store_true", help = "Whether plot calculated PDF for adjustment.")
 	options, urls = parser.parse_args()
 
 	if options.ranking_stat_cache is not None:
 		urls += [CacheEntry(line).url for line in open(options.ranking_stat_cache)]
+	# check for input parameters
+	required_options = set(("instrument", "width", "slope", "threshold", "matching"))
+	if options.is_calculate:
+		missing_options = set(option for option in required_options if getattr(options, option) is None)
+		if missing_options:
+			raise ValueError("missing required option(s) %s" % ", ".join("--%s" % option.replace("_", "-") for option in missing_options))
 
 	# save for the process_params table
 	options.options_dict = dict(options.__dict__)
@@ -101,6 +113,26 @@ options, urls = parse_command_line()
 
 rankingstat = cherenkov_rankingstat.marginalize_rankingstat_urls(urls, verbose = options.verbose)
 
+#
+# create artficial PDF
+#
+
+def gaussian(x, mu, sig):
+	return numpy.exp(-(x - mu)**2. / (2. * sig**2.))
+
+def calculated_pdf(x, y, width, slope, snr, matching):
+	pdf = numpy.zeros((len(x), len(y)))
+
+	for i in range(len(x)):
+		if x[i] >= snr:
+			# Gaussian in log scale
+			pdf[i][:] = gaussian(numpy.log10(y), matching, width) + (-4. * math.log10(x[i]))
+
+		else:
+			# Gaussian with decreasing width
+			pdf[i][:] = gaussian(numpy.log10(y), matching + slope * math.log10(x[i] / snr), 0.05 + (width - 0.05) * math.log10(x[i]) / math.log10(snr)) + (-4. * math.log10(x[i]))
+	return pdf
+
 
 #
 # plot denominator snr, chisq PDFs
@@ -110,18 +142,22 @@ rankingstat = cherenkov_rankingstat.marginalize_rankingstat_urls(urls, verbose =
 for instrument, pdf in rankingstat.denominator.lnpdfs.items():
 	x,y = pdf.bins.centres()
 	lnpdf = pdf.at_centres()
+	if options.is_calculate:
+		calpdf = calculated_pdf(x, y, options.width, options.slope, options.threshold, options.matching)
 
 	fig = figure.Figure()
 	FigureCanvas(fig)
 	axes = fig.gca()
 
 	norm = matplotlib.colors.Normalize(vmin = -30., vmax = lnpdf.max())
-	mesh = axes.pcolormesh(x, y, lnpdf.T, norm = None, cmap = "afmhot", shading = "gouraud")
+	mesh = axes.pcolormesh(x, y, lnpdf.T, norm = norm, cmap = "afmhot", shading = "gouraud")
+	if options.is_calculate:
+		axes.pcolormesh(x, y, calpdf.T, norm = norm, cmap = "winter", shading = "gouraud")
 	axes.contour(x, y, lnpdf.T, colors = "k", linestyles = "-", linewidths = .5, alpha = .3)
 	axes.loglog()
 	axes.grid(which = "both")
-	axes.set_xlim((4, 500))
-	axes.set_ylim((.00001, 5))
+	axes.set_xlim((3., 500.))
+	axes.set_ylim((.000001, 5.))
 	fig.colorbar(mesh, ax = axes)
 	axes.set_xlabel("$\mathrm{SNR}$")
 	axes.set_ylabel("$\chi^{2}/ \mathrm{SNR}^{2}$")
@@ -144,8 +180,8 @@ for instrument, pdf in rankingstat.denominator.lnpdfs.items():
 	axes.contour(x, y, lnpdf.T, norm = norm, colors = "k", linestyles = "-", linewidths = .5, alpha = .3)
 	axes.loglog()
 	axes.grid(which = "both")
-	axes.set_xlim((4, 500))
-	axes.set_ylim((.00001, 5))
+	axes.set_xlim((3., 500.))
+	axes.set_ylim((.000001, 5))
 	colorbar = fig.colorbar(mesh, ax = axes)
 	colorbar.set_clim(-30, lnpdf.max())
 	axes.set_xlabel("$\mathrm{SNR}$")
diff --git a/gstlal-burst/bin/gstlal_cherenkov_plot_summary b/gstlal-burst/bin/gstlal_cherenkov_plot_summary
index 2b877d6b86380c0ced36e17526480e2da43b082f..1868e7f13300146a1fea465206abf521f68d9739 100755
--- a/gstlal-burst/bin/gstlal_cherenkov_plot_summary
+++ b/gstlal-burst/bin/gstlal_cherenkov_plot_summary
@@ -47,12 +47,14 @@ matplotlib.rcParams.update({
 from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
 import numpy
 from scipy import interpolate
+from scipy import optimize
 import sys
 
 from optparse import OptionParser
 
 from lal import rate
 from lalburst import binjfind
+import lalsimulation
 from lal.utils import CacheEntry
 from gstlal import cherenkov
 from gstlal import stats as gstlalstats
@@ -75,8 +77,9 @@ from ligo.lw import lsctables
 
 def parse_command_line():
 	parser = OptionParser()
-	parser.add_option("--ranking-stat-pdf", metavar = "filename", help = "Set the name of the xml file rankingstatpdf.")
 	parser.add_option("--candidates-cache", metavar = "filename", help = "Also load the candidates from files listed in this LAL cache.  See lalapps_path2cache for information on how to produce a LAL cache file.")
+	parser.add_option("--power", type = "float", help = "Power of the source. It is used for making the contour graph of true rate.")
+	parser.add_option("--ranking-stat-pdf", metavar = "filename", help = "Set the name of the xml file rankingstatpdf.")
 	parser.add_option("--verbose", "-v", action = "store_true", help = "Be verbose.")
 
 	options, urls = parser.parse_args()
@@ -147,7 +150,7 @@ class FAPFAR(object):
 		# the zero-lag LR distribution
 		rate_normalization_lr_threshold, = rankingstatpdf.zl_lr_lnpdf.argmax()
 		# FIXME:  override with a manual cut until an automatic algorithm can be found
-		rate_normalization_lr_threshold = -28.
+		rate_normalization_lr_threshold = -19.
 
 		# record trials factor, with safety checks
 		counts = rankingstatpdf.zl_lr_lnpdf.count
@@ -224,7 +227,7 @@ def rankingstat_pdfs_plot(rankingstatpdf):
 	line1, = axes.semilogy(rankingstatpdf.noise_lr_lnpdf.bins[0].centres(), numpy.exp(rankingstatpdf.noise_lr_lnpdf.at_centres()), linewidth = 1)
 	rankingstatpdf.zl_lr_lnpdf.normalize()
 	axes.semilogy(rankingstatpdf.zl_lr_lnpdf.bins[0].centres(), numpy.exp(rankingstatpdf.zl_lr_lnpdf.at_centres()), color = 'red')
-	axes.set_xlim(-35., -15)
+	axes.set_xlim(-27., 5)
 	axes.set_ylim(1e-4, 1e1) 
 	axes.set_xlabel("$\ln\mathcal{L}$")
 	axes.set_ylabel("$P$")
@@ -297,20 +300,19 @@ def create_rate_vs_lnL_plot(axes, stats, stats_label, fapfar):
 
 
 def RateVsThreshold(fapfar, zerolag_stats, background_stats):
-	zerolag_fig, axes = create_plot("$\ln \mathcal{L}$ Threshold", "Number of Events $\geq \ln \mathcal{L}$")
+	zerolag_fig, axes = create_plot(r"$\ln \mathcal{L}$ Threshold", "Number of Events $\geq \ln \mathcal{L}$")
 	zerolag_stats = numpy.array(sorted(zerolag_stats, reverse = True))
 	create_rate_vs_lnL_plot(axes, zerolag_stats, r"Observed", fapfar)
-	axes.set_title("Event Count vs.\ Ranking Statistic Threshold")
+	axes.set_title(r"Event Count vs.\ Ranking Statistic Threshold")
 
-	background_fig, axes = create_plot("$\ln \mathcal{L}$ Threshold", "Number of Events $\geq \ln \mathcal{L}$")
+	background_fig, axes = create_plot(r"$\ln \mathcal{L}$ Threshold", "Number of Events $\geq \ln \mathcal{L}$")
 	background_stats = numpy.array(sorted(background_stats, reverse = True))
 	create_rate_vs_lnL_plot(axes, background_stats, r"Observed (time shifted)", fapfar)
-	axes.set_title("Event Count vs.\ Ranking Statistic Threshold (Closed Box)")
+	axes.set_title(r"Event Count vs.\ Ranking Statistic Threshold (Closed Box)")
 	detection_threshold = zerolag_stats[0]
 	return zerolag_fig, background_fig, detection_threshold
 
 
-
 #
 # =============================================================================
 #
@@ -320,6 +322,81 @@ def RateVsThreshold(fapfar, zerolag_stats, background_stats):
 #
 
 
+def slope(x, y):
+	"""
+	From the x and y arrays, compute the slope at the x co-ordinates
+	using a first-order finite difference approximation.
+	"""
+	slope = numpy.zeros((len(x),), dtype = "double")
+	slope[0] = (y[1] - y[0]) / (x[1] - x[0])
+	for i in range(1, len(x) - 1):
+		slope[i] = (y[i + 1] - y[i - 1]) / (x[i + 1] - x[i - 1])
+	slope[-1] = (y[-1] - y[-2]) / (x[-1] - x[-2])
+	return slope
+
+
+def upper_err(y, yerr, deltax):
+	z = y + yerr
+	deltax = int(deltax)
+	upper = numpy.zeros((len(yerr),), dtype = "double")
+	for i in range(len(yerr)):
+		upper[i] = max(z[max(i - deltax, 0) : min(i + deltax, len(z))])
+	return upper - y
+
+
+def lower_err(y, yerr, deltax):
+	z = y - yerr
+	deltax = int(deltax)
+	lower = numpy.zeros((len(yerr),), dtype = "double")
+	for i in range(len(yerr)):
+		lower[i] = min(z[max(i - deltax, 0) : min(i + deltax, len(z))])
+	return y - lower
+
+
+def render_from_bins(axes, efficiency_numerator, efficiency_denominator, cal_uncertainty, filter_width, colour = "k", erroralpha = 0.3, linestyle = "-"):
+	# extract array of x co-ordinates, and the factor by which x
+	# increases from one sample to the next.
+	(x,) = efficiency_denominator.centres()
+	x_factor_per_sample = efficiency_denominator.bins[0].delta
+
+	# compute the efficiency, the slope (units = efficiency per
+	# sample), the y uncertainty (units = efficiency) due to binomial
+	# counting fluctuations, and the x uncertainty (units = samples)
+	# due to the width of the smoothing filter.
+	eff = efficiency_numerator.array / efficiency_denominator.array
+	dydx = slope(numpy.arange(len(x), dtype = "double"), eff)
+	yerr = numpy.sqrt(eff * (1. - eff) / efficiency_denominator.array)
+	xerr = numpy.array([filter_width / 2.] * len(yerr))
+
+	# compute the net y err (units = efficiency) by (i) multiplying the
+	# x err by the slope, (ii) dividing the calibration uncertainty
+	# (units = percent) by the fractional change in x per sample and
+	# multiplying by the slope, (iii) adding the two in quadradure with
+	# the y err.
+	net_yerr = numpy.sqrt((xerr * dydx)**2. + yerr**2. + (cal_uncertainty / x_factor_per_sample * dydx)**2.)
+
+	# compute net xerr (units = percent) by dividing yerr by slope and
+	# then multiplying by the fractional change in x per sample.
+	net_xerr = net_yerr / dydx * x_factor_per_sample
+
+	# plot the efficiency curve and uncertainty region
+	#patch = patches.Polygon(zip(numpy.concatenate((x, x[::-1])), numpy.concatenate((eff + upper_err(eff, yerr, filter_width / 2.), (eff - lower_err(eff, yerr, filter_width / 2.))[::-1]))), edgecolor = colour, facecolor = colour, alpha = erroralpha)
+	#axes.add_patch(patch)
+	line, = axes.plot(x, eff, colour + linestyle)
+
+	# compute 50% point and its uncertainty
+	A50 = None #optimize.bisect(interpolate.interp1d(x, eff - 0.5), x[0], x[-1], xtol = 1e-40)
+	A50_err = None #interpolate.interp1d(x, net_xerr)(A50)
+
+	# print some analysis FIXME:  this calculation needs attention
+	num_injections = efficiency_denominator.array.sum()
+	num_samples = len(efficiency_denominator.array)
+	#print("Bins were %g samples wide, ideal would have been %g" % (filter_width, (num_samples / num_injections / interpolate.interp1d(x, dydx)(A50)**2.0)**(1.0/3.0)), file=sys.stderr)
+	#print("Average number of injections in each bin = %g" % efficiency_denominator.array.mean(), file=sys.stderr)
+
+	return line, A50, A50_err
+
+
 def create_efficiency_plot(axes, all_injections, found_injections, detection_threshold):
 	# formats
 	axes.semilogx()
@@ -327,43 +404,53 @@ def create_efficiency_plot(axes, all_injections, found_injections, detection_thr
 	
 	# 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(("\(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")
 
 	# the denominator and numerator binning for the plot
-	efficiency_numerator = rate.BinnedArray(rate.NDBins((rate.LogarithmicBins(min(sim.egw_over_rsquared for sim in all_injections), max(sim.egw_over_rsquared for sim in all_injections), 400),)))
-	efficiency_denominator = rate.BinnedArray(rate.NDBins((rate.LogarithmicBins(min(sim.egw_over_rsquared for sim in all_injections), max(sim.egw_over_rsquared for sim in all_injections), 400),)))
+	efficiency_numerator = rate.BinnedArray(rate.NDBins((rate.LogarithmicBins(min(sim.amplitude for sim in all_injections), max(sim.amplitude for sim in all_injections), 400),)))
+	efficiency_denominator = rate.BinnedArray(efficiency_numerator.bins)
 
 	# add into the vins
 	for sim in found_injections:
-		efficiency_numerator[sim.egw_over_rsquared,] += 1
+		efficiency_numerator[sim.amplitude,] += 1
 	for sim in all_injections:
-		efficiency_denominator[sim.egw_over_rsquared,] += 1
+		efficiency_denominator[sim.amplitude,] += 1
 
 	# adjust window function normalization
-	#filter_width = 16.7
-	#windowfunc = rate.gaussian_window(filter_width)
-	#windowfunc /= windowfunc[len(windowfunc) / 2 + 1]
-	#rate.filter_array(efficiency_numerator.array, windowfunc)
-	#rate.filter_array(efficiency_denominator.array, windowfunc)
+	filter_width = 10
+	windowfunc = rate.gaussian_window(filter_width)
+	windowfunc /= windowfunc[int((len(windowfunc) + 1) / 2)]
+	rate.filter_array(efficiency_numerator.array, windowfunc)
+	rate.filter_array(efficiency_denominator.array, windowfunc)
 
 	# regularize: adjust unused bins so that the efficiency is 0 avoid Nan
 	assert(efficiency_numerator.array <= efficiency_denominator.array).all()
 	efficiency_denominator.array[(efficiency_numerator.array == 0) & (efficiency_denominator.array == 0)] = 1
 	
-	(x,) = efficiency_denominator.centres()
-	eff = efficiency_numerator.array / efficiency_denominator.array
-	print(eff, file = sys.stderr)
-	line, = axes.plot(x, eff)
+	# FIXME: for output checking only
+	eff = rate.BinnedArray(efficiency_numerator.bins, array = efficiency_numerator.array / efficiency_denominator.array)
+	#print(eff, file = sys.stderr)
 
-def Efficiency(all_injections, found_injections, detection_threshold):
-	fig, axes = create_plot("Injection Amplitude (\(\mathrm{J/s^2}\))", "Detection Efficiency")
-	create_efficiency_plot(axes, all_injections, found_injections, detection_threshold)
-	axes.set_title("Detection Efficiency vs.\ Amplitude")
-	return fig
+	line1, A50, A50_error = render_from_bins(axes, efficiency_numerator, efficiency_denominator, 0.2, filter_width)
+
+	# add a legend to the axis
+	axes.legend((line1,), (r"\noindent Injections with $\log \Lambda > %.2f$" % detection_threshold,), loc = "lower right")
 
+	# adjust limits
+	axes.set_ylim([0.0, 1.0])
+
+	# return eff for true rate contour
+	return eff
+
+
+def Efficiency(all_injections, found_injections, detection_threshold):
+	fig, axes = create_plot(r"Injection Amplitude ($\mathrm{J/m^2}$)", "Detection Efficiency")
+	eff = create_efficiency_plot(axes, all_injections, found_injections, detection_threshold)
+	axes.set_title(r"Detection Efficiency vs.\ Amplitude")
+	return fig, eff
 
 
 #
@@ -374,6 +461,39 @@ def Efficiency(all_injections, found_injections, detection_threshold):
 # =============================================================================
 #
 
+
+def create_truerate_contour(axes, power, eff):
+	# set beta and impact parameter axis
+	rate = numpy.zeros((300,300))
+	beta = 10.**numpy.linspace(0.01, 2., 300)
+	r = 10.**numpy.linspace(5., 9., 300)
+
+	print(eff, file = sys.stderr)
+	# calculate
+	for i in range(len(beta)):
+		for j in range(len(r)):
+			dE_dA = lalsimulation.SimBurstCherenkov_dE_dA(power, beta[i], r[j])
+			dE_dA = max(dE_dA, eff.bins[0].min)
+			dE_dA = min(dE_dA, eff.bins[0].max)
+			rate[i][j] = 3.890 / eff[dE_dA,]
+
+	# set color maps
+	norm = matplotlib.colors.LogNorm(vmin = 1., vmax = 10000.)
+	cmap = matplotlib.cm.viridis
+	cmap.set_bad("k")
+	mesh = axes.pcolormesh(beta, r, rate.T, norm = norm, cmap = cmap, shading = "gouraud")
+	contour = axes.contour(beta, r, rate.T, norm = norm, colors = "black", linestyle = "-", linewidth = .5, alpha = 1., levels = numpy.logspace(0., 3., 7, base = 10.))
+	fmt = matplotlib.ticker.LogFormatterMathtext()
+	axes.clabel(contour, contour.levels, colors = "black", fmt = fmt)
+	axes.loglog()
+	axes.grid(which = "both")
+
+def Truerate(power, eff):
+	fig, axes = create_plot(r"$\beta$", "Impact parameter(metres)")
+	create_truerate_contour(axes, power, eff)
+	axes.set_title(r"90\%% Confidence Rate Upper Limit for NCC-1701-D Enterprise ($P=%s$ W)" % gstlalplotutil.latexnumber("%.4g" % power))
+	return fig
+
 #
 # =============================================================================
 #
@@ -463,6 +583,7 @@ for filename, fig in [("rate_vs_threshold_open", rate_vs_thresh_zl), ("rate_vs_t
 
 all_injections = []
 found_injections = []
+is_injection = False
 
 for n, url in enumerate(urls, 1):
 	if options.verbose:
@@ -471,6 +592,7 @@ for n, url in enumerate(urls, 1):
 
 	if not is_injection_document(xmldoc):
 		continue
+	is_injection = True
 	coinc_def_id = lsctables.CoincDefTable.get_table(xmldoc).get_coinc_def_id(search = cherenkov.CherenkovBBCoincDef.search, search_coinc_type = cherenkov.CherenkovBBCoincDef.search_coinc_type, create_new = False)
 	lnL_index = dict((coinc.coinc_event_id, coinc.likelihood) for coinc in lsctables.CoincTable.get_table(xmldoc) if coinc.coinc_def_id == coinc_def_id)
 
@@ -492,9 +614,18 @@ for n, url in enumerate(urls, 1):
 		if sim_lnL_index.get(sim.simulation_id, float("-inf")) >= threshold:
 			found_injections.append(sim)
 
-efficiency = Efficiency(all_injections, found_injections, threshold)
+if is_injection:
+	efficiencyfig, eff = Efficiency(all_injections, found_injections, threshold)
 
-for ext in (".png", ".pdf"):
-	if options.verbose:
-		print("writing Efficiency%s with threshold of %s", (ext,threshold), file = sys.stderr)
-	efficiency.savefig("Efficiency%s" % ext)
+	for ext in (".png", ".pdf"):
+		if options.verbose:
+			print("writing Efficiency%s with threshold of %s" % (ext,threshold), file = sys.stderr)
+		efficiencyfig.savefig("Efficiency%s" % ext)
+
+	if options.power is not None:
+		rate = Truerate(options.power, eff)
+
+		for ext in (".png", ".pdf"):
+			if options.verbose:
+				print("writing True rate contour graph", file = sys.stderr)
+			rate.savefig("Truerate%s" % ext)
diff --git a/gstlal-burst/bin/gstlal_cherenkov_zl_rank_pdfs b/gstlal-burst/bin/gstlal_cherenkov_zl_rank_pdfs
index 42621ca34ab27d65a7224321279550533829d279..d259f82e6de469469a3907d0598cd5a5a9670331 100755
--- a/gstlal-burst/bin/gstlal_cherenkov_zl_rank_pdfs
+++ b/gstlal-burst/bin/gstlal_cherenkov_zl_rank_pdfs
@@ -60,6 +60,7 @@ def parse_command_line():
 	parser.add_option("--candidates-cache", metavar = "filename", help = "Also load the candidates from files listed in this LAL cache.  See lalapps_path2cache for information on how to produce a LAL cache file.")
 	parser.add_option("-v", "--verbose", action = "store_true", help = "Be verbose.")
 	parser.add_option("--ranking-stat-pdf", metavar = "filename", help = "Write zero-lag ranking statistic PDF to this file.  Must contain exactly one Cherenkov burst ranking statistic PDF object.")
+	parser.add_option("--is-timeshifted", action = "store_true", help = "Whether the open(zerolag) or closed(time shifted) box.")
 	options, urls = parser.parse_args()
 
 	paramdict = options.__dict__.copy()
@@ -119,7 +120,10 @@ for n, url in enumerate(urls, 1):
 		print("%d/%d: " % (n, len(urls)), end = "", file = sys.stderr)
 	xmldoc = ligolw_utils.load_url(url, contenthandler = cherenkov_rankingstat.LIGOLWContentHandler, verbose = options.verbose)
 	coinc_def_id = lsctables.CoincDefTable.get_table(xmldoc).get_coinc_def_id(search = cherenkov.CherenkovBBCoincDef.search, search_coinc_type = cherenkov.CherenkovBBCoincDef.search_coinc_type, create_new = False)
-	zl_time_slide_ids = frozenset(time_slide_id for time_slide_id, offsetvector in lsctables.TimeSlideTable.get_table(xmldoc).as_dict().items() if not any(offsetvector.values()))
+	if options.is_timeshifted:
+		zl_time_slide_ids = frozenset(time_slide_id for time_slide_id, offsetvector in lsctables.TimeSlideTable.get_table(xmldoc).as_dict().items() if any(offsetvector.values()))
+	else:
+		zl_time_slide_ids = frozenset(time_slide_id for time_slide_id, offsetvector in lsctables.TimeSlideTable.get_table(xmldoc).as_dict().items() if not any(offsetvector.values()))
 
 	for coinc in lsctables.CoincTable.get_table(xmldoc):
 		if coinc.coinc_def_id == coinc_def_id and coinc.time_slide_id in zl_time_slide_ids:
diff --git a/gstlal-burst/python/cherenkov/rankingstat.py b/gstlal-burst/python/cherenkov/rankingstat.py
index 7f762232d969b19a76f811f5440213a444281e36..893b16c9ac1709a2ea4d3f73f1fbe922d4f26ab6 100644
--- a/gstlal-burst/python/cherenkov/rankingstat.py
+++ b/gstlal-burst/python/cherenkov/rankingstat.py
@@ -53,15 +53,17 @@ from gstlal.stats import trigger_rate
 # ============================================================================
 #
 
+
 #
 # Numerator
 #
 
 class LnSignalDensity(snglcoinc.LnLRDensity):
-	ln_chisq_const = {"H1": -1.5, "L1": -1.}
-	threshold = {"H1": 80., "L1": 50.}
-	width = {"H1": 2.3, "L1": 2.3}
-	ln_matching = {"H1": -7.26443022292087, "L1": -5.80914299031403}
+	ln_chisq_const = {"H1": -1.9, "L1": -2.0}
+	threshold = {"H1": 120., "L1": 100.}
+	width = {"H1": 1.0, "L1": 1.5}
+	ln_matching = {"H1": -9.5, "L1": -9.5}
+
 
 	def __init__(self, instruments, delta_t, min_instruments):
 		self.instruments = instruments