def get_volume_derivative(self, instruments):
        injfnames = self.inj_fnames
        FAR = self.far[instruments]
        zero_lag_segments = self.zero_lag_segments[instruments]
        gw = self.gw
        twoDMassBins = self.twoDMassBins

        #determine binning up front for infinite FAR
        found, missed = self.get_injections(instruments, FAR=float("inf"))
        dbin = rate.LogarithmicBins(min([l.distance for l in found]),
                                    max([l.distance for l in found]),
                                    int(self.opts.dist_bins))

        livetime = float(abs(zero_lag_segments))
        FARh = FAR * 100000
        FARl = FAR * 0.001
        nbins = 5
        FARS = rate.LogarithmicBins(FARl, FARh, nbins)
        vA = []
        vA2 = []
        for far in FARS.centres():
            print("computing volume at FAR " + str(far), file=sys.stderr)
            vAt, vA2t = self.twoD_SearchVolume(instruments,
                                               dbin=dbin,
                                               FAR=far,
                                               bootnum=1)
            # we need to compute derivitive of log according to ul paper
            vAt.array = scipy.log10(vAt.array + 0.001)
            vA.append(vAt)
        # the derivitive is calcuated with respect to FAR * t
        FARTS = rate.LogarithmicBins(FARl * livetime, FARh * livetime, nbins)
        return self._derivitave_fit(FARTS, FAR * livetime, vA, twoDMassBins)
Exemple #2
0
def get_volume_derivative(injfnames, twoDMassBins, dBin, FAR,
                          zero_lag_segments, gw):
    if (FAR == 0):
        print("\n\nFAR = 0\n \n")
        # FIXME lambda = ~inf if loudest event is above loudest timeslide?
        output = rate.BinnedArray(twoDMassBins)
        output.array = 10**6 * numpy.ones(output.array.shape)
        return output
    livetime = float(abs(zero_lag_segments))
    FARh = FAR * 100000
    FARl = FAR * 0.001
    nbins = 5
    FARS = rate.LogarithmicBins(FARl, FARh, nbins)
    vA = []
    vA2 = []
    for far in FARS.centres():
        m, f = get_injections(injfnames, far, zero_lag_segments)
        print("computing volume at FAR " + str(far), file=sys.stderr)
        vAt, vA2t = twoD_SearchVolume(f, m, twoDMassBins, dBin, gw, livetime,
                                      1)
        # we need to compute derivitive of log according to ul paper
        vAt.array = scipy.log10(vAt.array + 0.001)
        vA.append(vAt)
    # the derivitive is calcuated with respect to FAR * t
    FARS = rate.LogarithmicBins(FARl * livetime, FARh * livetime, nbins)
    return derivitave_fit(FARS, FAR * livetime, vA, twoDMassBins)
Exemple #3
0
 def __init__(self, x_instrument, y_instrument, magnitude, desc,
              min_magnitude, max_magnitude):
     self.fig, self.axes = SnglBurstUtils.make_burst_plot(
         "%s %s" % (x_instrument, desc), "%s %s" % (y_instrument, desc))
     self.fig.set_size_inches(6, 6)
     self.axes.loglog()
     self.x_instrument = x_instrument
     self.y_instrument = y_instrument
     self.magnitude = magnitude
     self.foreground_x = []
     self.foreground_y = []
     self.n_foreground = 0
     self.n_background = 0
     self.n_injections = 0
     self.foreground_bins = rate.BinnedArray(
         rate.NDBins(
             (rate.LogarithmicBins(min_magnitude, max_magnitude, 1024),
              rate.LogarithmicBins(min_magnitude, max_magnitude, 1024))))
     self.background_bins = rate.BinnedArray(
         rate.NDBins(
             (rate.LogarithmicBins(min_magnitude, max_magnitude, 1024),
              rate.LogarithmicBins(min_magnitude, max_magnitude, 1024))))
     self.coinc_injection_bins = rate.BinnedArray(
         rate.NDBins(
             (rate.LogarithmicBins(min_magnitude, max_magnitude, 1024),
              rate.LogarithmicBins(min_magnitude, max_magnitude, 1024))))
     self.incomplete_coinc_injection_bins = rate.BinnedArray(
         rate.NDBins(
             (rate.LogarithmicBins(min_magnitude, max_magnitude, 1024),
              rate.LogarithmicBins(min_magnitude, max_magnitude, 1024))))
def make_binning(plots):
    plots = [
        plot for instrument in plots.keys() for plot in plots[instrument]
        if isinstance(plot, SimBurstUtils.Efficiency_hrss_vs_freq)
    ]
    if not plots:
        return None
    minx = min([min(plot.injected_x) for plot in plots])
    maxx = max([max(plot.injected_x) for plot in plots])
    miny = min([min(plot.injected_y) for plot in plots])
    maxy = max([max(plot.injected_y) for plot in plots])
    return rate.NDBins(
        (rate.LogarithmicBins(minx, maxx,
                              512), rate.LogarithmicBins(miny, maxy, 512)))
    def _bin_events(self, binning=None):
        # called internally by finish()
        if binning is None:
            minx, maxx = min(self.injected_x), max(self.injected_x)
            miny, maxy = min(self.injected_y), max(self.injected_y)
            binning = rate.NDBins((rate.LogarithmicBins(minx, maxx, 256),
                                   rate.LogarithmicBins(miny, maxy, 256)))

        self.efficiency = rate.BinnedRatios(binning)

        for xy in zip(self.injected_x, self.injected_y):
            self.efficiency.incdenominator(xy)
        for xy in zip(self.found_x, self.found_y):
            self.efficiency.incnumerator(xy)

        # 1 / error^2 is the number of injections that need to be
        # within the window in order for the fractional uncertainty
        # in that number to be = error.  multiplying by
        # bins_per_inj tells us how many bins the window needs to
        # cover, and taking the square root translates that into
        # the window's length on a side in bins.  because the
        # contours tend to run parallel to the x axis, the window
        # is dilated in that direction to improve resolution.

        bins_per_inj = self.efficiency.used() / float(len(self.injected_x))
        self.window_size_x = self.window_size_y = math.sqrt(bins_per_inj /
                                                            self.error**2)
        self.window_size_x *= math.sqrt(2)
        self.window_size_y /= math.sqrt(2)
        if self.window_size_x > 100 or self.window_size_y > 100:
            # program will take too long to run
            raise ValueError(
                "smoothing filter too large (not enough injections)")

        print("The smoothing window for %s is %g x %g bins" % ("+".join(
            self.instruments), self.window_size_x, self.window_size_y),
              end=' ',
              file=sys.stderr)
        print("which is %g%% x %g%% of the binning" %
              (100.0 * self.window_size_x / binning[0].n,
               100.0 * self.window_size_y / binning[1].n),
              file=sys.stderr)
 def get_distance_bins(self, instruments, found=None, missed=None):
   if not found and not missed: found, missed = self.get_injections(instruments)
   if not found:  
     print("Found no injections cannot compute distance bins ABORTING", file=sys.stderr)
     sys.exit(1)
   #Give the bins some padding based on the errors
   maxdist = max([s.distance for s in found])
   mindist = min([s.distance for s in found])
   if (maxdist < 0) or (mindist < 0) or (mindist > maxdist):
     print("minimum and maximum distances are screwy, maybe the distance errors given in the options don't make sense? ABORTING", file=sys.stderr)
     sys.exit(1)
   self.dBin[instruments] = rate.LogarithmicBins(mindist,maxdist,self.opts.dist_bins)
Exemple #7
0
def create_efficiency_plot(axes, all_injections, found_injections, detection_threshold, cal_uncertainty):
	filter_width = 16.7
	# formats
	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 all_injections), max(sim.amplitude for sim in all_injections), 400),))
	efficiency_num = rate.BinnedArray(bins)
	efficiency_den = rate.BinnedArray(bins)
	for sim in found_injections:
		efficiency_num[sim.amplitude,] += 1
	for sim in all_injections:
		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(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, cal_uncertainty, filter_width, colour = "k", linestyle = "-", erroralpha = 0.2)

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

	# adjust limits
	axes.set_xlim([3e-22, 3e-19])
	axes.set_ylim([0.0, 1.0])
def rate_posterior_from_samples(samples):
    """
	Construct and return a BinnedArray containing a histogram of a
	sequence of samples.  If limits is None (default) then the limits
	of the binning will be determined automatically from the sequence,
	otherwise limits is expected to be a tuple or other two-element
	sequence providing the (low, high) limits, and in that case the
	sequence can be a generator.
	"""
    nbins = int(math.sqrt(len(samples)) / 40.)
    assert nbins >= 1, "too few samples to construct histogram"
    lo = samples.min() * (1. - nbins / len(samples))
    hi = samples.max() * (1. + nbins / len(samples))
    ln_pdf = rate.BinnedLnPDF(
        rate.NDBins((rate.LogarithmicBins(lo, hi, nbins), )))
    count = ln_pdf.count  # avoid attribute look-up in loop
    for sample in samples:
        count[sample, ] += 1.
    rate.filter_array(ln_pdf.array, rate.gaussian_window(5), use_fft=False)
    ln_pdf.normalize()
    return ln_pdf
    def twoD_SearchVolume(self,
                          instruments,
                          dbin=None,
                          FAR=None,
                          bootnum=None,
                          derr=0.197,
                          dsys=0.074):
        """ 
    Compute the search volume in the mass/mass plane, bootstrap
    and measure the first and second moment (assumes the underlying 
    distribution can be characterized by those two parameters) 
    This is gonna be brutally slow
    derr = (0.134**2+.103**2+.102**2)**.5 = 0.197 which is the 3 detector 
    calibration uncertainty in quadrature.  This is conservative since some injections
     will be H1L1 and have a lower error of .17
    the dsys is the DC offset which is the max offset of .074. 
    """

        if not FAR: FAR = self.far[instruments]
        found, missed = self.get_injections(instruments, FAR)
        twodbin = self.twoDMassBins
        wnfunc = self.gw
        livetime = self.livetime[instruments]
        if not bootnum: bootnum = self.bootnum

        if wnfunc:
            wnfunc /= wnfunc[(wnfunc.shape[0] - 1) / 2,
                             (wnfunc.shape[1] - 1) / 2]

        x = twodbin.shape[0]
        y = twodbin.shape[1]
        z = int(self.opts.dist_bins)

        rArrays = []
        volArray = rate.BinnedArray(twodbin)
        volArray2 = rate.BinnedArray(twodbin)
        #set up ratio arrays for each distance bin
        for k in range(z):
            rArrays.append(rate.BinnedRatios(twodbin))

        # Bootstrap to account for errors
        for n in range(bootnum):
            #initialize by setting these to zero
            for k in range(z):
                rArrays[k].numerator.array = numpy.zeros(
                    rArrays[k].numerator.bins.shape)
                rArrays[k].denominator.array = numpy.zeros(
                    rArrays[k].numerator.bins.shape)
            #Scramble the inj population and distances
            if bootnum > 1:
                sm, sf = self._scramble_pop(missed, found)
                # I make a separate array of distances to speed up this calculation
                f_dist = self._scramble_dist(sf, derr, dsys)
            else:
                sm, sf = missed, found
                f_dist = numpy.array([l.distance for l in found])

            # compute the distance bins
            if not dbin:
                dbin = rate.LogarithmicBins(min(f_dist), max(f_dist), z)
            #else: print dbin.centres()

            # get rid of all missed injections outside the distance bins
            # to prevent binning errors
            sm, m_dist = self.cut_distance(sm, dbin)
            sf, f_dist = self.cut_distance(sf, dbin)

            for i, l in enumerate(sf):  #found:
                tbin = rArrays[dbin[f_dist[i]]]
                tbin.incnumerator((l.mass1, l.mass2))
            for i, l in enumerate(sm):  #missed:
                tbin = rArrays[dbin[m_dist[i]]]
                tbin.incdenominator((l.mass1, l.mass2))

            tmpArray2 = rate.BinnedArray(
                twodbin)  #start with a zero array to compute the mean square
            for k in range(z):
                tbins = rArrays[k]
                tbins.denominator.array += tbins.numerator.array
                if wnfunc: rate.filter_array(tbins.denominator.array, wnfunc)
                if wnfunc: rate.filter_array(tbins.numerator.array, wnfunc)
                tbins.regularize()
                # logarithmic(d)
                integrand = 4.0 * pi * tbins.ratio() * dbin.centres(
                )[k]**3 * dbin.delta
                volArray.array += integrand
                tmpArray2.array += integrand  #4.0 * pi * tbins.ratio() * dbin.centres()[k]**3 * dbin.delta
                print(
                    "bootstrapping:\t%.1f%% and Calculating smoothed volume:\t%.1f%%\r"
                    % ((100.0 * n / bootnum), (100.0 * k / z)),
                    end=' ',
                    file=sys.stderr)
            tmpArray2.array *= tmpArray2.array
            volArray2.array += tmpArray2.array

        print("", file=sys.stderr)
        #Mean and variance
        volArray.array /= bootnum
        volArray2.array /= bootnum
        volArray2.array -= volArray.array**2  # Variance
        volArray.array *= livetime
        volArray2.array *= livetime * livetime  # this gets two powers of live time
        return volArray, volArray2
Exemple #10
0
                                   zero_lag_segments,
                                   verbose=opts.verbose)

else:
    Found = get_burst_injections(opts.burst_found)
    Missed = get_burst_injections(opts.burst_missed)

# restrict the sims to a distance range
Found = cut_distance(Found, 1, max_dist)
Missed = cut_distance(Missed, 1, max_dist)

# get a 2D mass binning
twoDMassBins = get_2d_mass_bins(min_mass, max_mass, mass_bins)

# get log distance bins
dBin = rate.LogarithmicBins(0.1, max_dist * 1.25, dist_bins)

# Someday we could try a Gaussian smoothing function
#gw = rate.gaussian_window2d(2,2,8)
gw = None

#Get derivative of volume with respect to FAR
#dvA = get_volume_derivative(opts.injfnames, twoDMassBins, dBin, FAR, zero_lag_segments, gw)

vA, vA2 = twoD_SearchVolume(Found,
                            Missed,
                            twoDMassBins,
                            dBin,
                            gw,
                            1.0,
                            bootnum=int(opts.bootstrap_iterations))