def get_2d_mass_bins(self, low, high, bins): """ Given the component mass range low, high of the search it will return 2D bins with size bins in each direction """ mass1Bin = rate.LinearBins(low, high, bins) mass2Bin = rate.LinearBins(low, high, bins) twoDMB = rate.NDBins((mass1Bin, mass2Bin)) return twoDMB
def add_contents(self, contents): if self.tisi_rows is None: # get a list of time slide dictionaries self.tisi_rows = contents.time_slide_table.as_dict().values() # find the largest and smallest offsets min_offset = min(offset for vector in self.tisi_rows for offset in vector.values()) max_offset = max(offset for vector in self.tisi_rows for offset in vector.values()) # a guess at the time slide spacing: works if the # time slides are distributed as a square grid over # the plot area. (max - min)^2 gives the area of # the time slide square in square seconds; dividing # by the length of the time slide list gives the # average area per time slide; taking the square # root of that gives the average distance between # adjacent time slides in seconds time_slide_spacing = ((max_offset - min_offset)**2 / len(self.tisi_rows))**0.5 # use an average of 3 bins per time slide in each # direction, but round to an odd integer nbins = int( math.ceil((max_offset - min_offset) / time_slide_spacing * 3)) # construct the binning self.counts = rate.BinnedArray( rate.NDBins((rate.LinearBins(min_offset, max_offset, nbins), rate.LinearBins(min_offset, max_offset, nbins)))) self.seglists |= contents.seglists for offsets in contents.connection.cursor().execute( """ SELECT tx.offset, ty.offset FROM coinc_event JOIN time_slide AS tx ON ( tx.time_slide_id == coinc_event.time_slide_id ) JOIN time_slide AS ty ON ( ty.time_slide_id == coinc_event.time_slide_id ) WHERE coinc_event.coinc_def_id == ? AND tx.instrument == ? AND ty.instrument == ? """, (contents.bb_definer_id, self.x_instrument, self.y_instrument)): try: self.counts[offsets] += 1 except IndexError: # beyond plot boundaries pass
def guess_distance_chirp_mass_bins_from_sims(sims, mbins = 11, distbins = 200): """ Given a list of the injections, guess at the chirp mass and distance bins. """ dist_mchirp_vals = map(sim_to_distance_chirp_mass_bins_function, sims) distances = [tup[0] for tup in dist_mchirp_vals] mchirps = [tup[1] for tup in dist_mchirp_vals] return rate.NDBins([rate.LinearBins(min(distances), max(distances), distbins), rate.LinearBins(min(mchirps), max(mchirps), mbins)])
def guess_distance_effective_spin_parameter_bins_from_sims(sims, chibins = 11, distbins = 200): """ Given a list of the injections, guess at the chi = (m1*s1z + m2*s2z)/(m1+m2) and distance bins. """ dist_chi_vals = map(sim_to_distance_effective_spin_parameter_bins_function, sims) distances = [tup[0] for tup in dist_chi_vals] chis = [tup[1] for tup in dist_chi_vals] return rate.NDBins([rate.LinearBins(min(distances), max(distances), distbins), rate.LinearBins(min(chis), max(chis), chibins)])
def __init__(self, instruments): self.densities = {} for pair in intertools.combinations(sorted(instruments), 2): # FIXME: hard-coded for directional search #dt = 0.02 + snglcoinc.light_travel_time(*pair) dt = 0.02 self.densities["%s_%s_dt" % pair] = rate.BinnedLnDPF(rate.NDBins((rate.ATanBins(-dt, +dt, 12001), rate.LinearBins(0.0, 2 * math.pi, 61)))) self.densities["%s_%s_dband" % pair] = rate.BinnedLnDPF(rate.NDBins((rate.LinearBins(-2.0, +2.0, 12001), rate.LinearBins(0.0, 2 * math.pi, 61)))) self.densities["%s_%s_ddur" % pair] = rate.BinnedLnDPF(rate.NDBins((rate.LinearBins(-2.0, +2.0, 12001), rate.LinearBins(0.0, 2 * math.pi, 61)))) self.densities["%s_%s_df" % pair] = rate.BinnedLnDPF(rate.NDBins((rate.LinearBins(-2.0, +2.0, 12001), rate.LinearBins(0.0, 2 * math.pi, 61)))) self.densities["%s_%s_dh" % pair] = rate.BinnedLnDPF(rate.NDBins((rate.LinearBins(-2.0, +2.0, 12001), rate.LinearBins(0.0, 2 * math.pi, 61))))
def guess_distance_total_mass_bins_from_sims(sims, nbins = 11, distbins = 200): """ Given a list of the injections, guess at the mass1, mass2 and distance bins. Floor and ceil will be used to round down to the nearest integers. """ total_lo = numpy.floor(min([sim.mass1 + sim.mass2 for sim in sims])) total_hi = numpy.ceil(max([sim.mass1 + sim.mass2 for sim in sims])) mindist = numpy.floor(min([sim.distance for sim in sims])) maxdist = numpy.ceil(max([sim.distance for sim in sims])) return rate.NDBins((rate.LinearBins(mindist, maxdist, distbins), rate.LinearBins(total_lo, total_hi, nbins)))
def __init__(self, x, y, magnitude, max_magnitude): self.fig, self.axes = SnglBurstUtils.make_burst_plot("X", "Y") self.fig.set_size_inches(6, 6) self.x = x self.y = y self.magnitude = magnitude self.n_foreground = 0 self.n_background = 0 self.n_injections = 0 max_magnitude = math.log10(max_magnitude) self.foreground_bins = rate.BinnedArray( rate.NDBins((rate.LinearBins(-max_magnitude, max_magnitude, 1024), rate.LinearBins(-max_magnitude, max_magnitude, 1024)))) self.background_bins = rate.BinnedArray( rate.NDBins((rate.LinearBins(-max_magnitude, max_magnitude, 1024), rate.LinearBins(-max_magnitude, max_magnitude, 1024)))) self.coinc_injection_bins = rate.BinnedArray( rate.NDBins((rate.LinearBins(-max_magnitude, max_magnitude, 1024), rate.LinearBins(-max_magnitude, max_magnitude, 1024)))) self.incomplete_coinc_injection_bins = rate.BinnedArray( rate.NDBins((rate.LinearBins(-max_magnitude, max_magnitude, 1024), rate.LinearBins(-max_magnitude, max_magnitude, 1024))))
class test_MovingHistogramFixedN(unittest.TestCase): bins = rate.LinearBins(0, 1, 10) max_hist_size = 100 def setUp(self): self.hist = mh.MovingHistogramFixedN(self.bins, self.max_hist_size) def test_monotonicity_check(self): for i in range(num_tests): self.setUp() a, b = np.random.randint(100, size=2) self.hist.update(a, 0.5) if b < a: self.assertRaises(ValueError, lambda: self.hist.update(b, 0.5)) else: self.hist.update(b, 0.5) def test_pdf_normalization(self): for i in range(num_tests): self.setUp() for t, s in enumerate(np.random.random(size=100)): self.hist.update(t, s) x = np.linspace(0, 1, 100) y = np.array([self.hist.get_pdf(a) for a in x]) integral = integrate.simps(y, x) self.assertTrue(abs(integral - 1.0) < 0.01) def test_cdf_normalization(self): for i in range(num_tests): self.setUp() for t, s in enumerate(np.random.random(size=100)): self.hist.update(t, s) self.assertAlmostEqual(self.hist.get_cdf(self.bins.max), 1) def test_sf_normalization(self): for i in range(num_tests): self.setUp() for t, s in enumerate(np.random.random(size=100)): self.hist.update(t, s) self.assertAlmostEqual(self.hist.get_sf(self.bins.min), 1) def test_hist_size_limit(self): for t, s in enumerate(np.random.random(size=self.max_hist_size + num_tests)): self.hist.update(t, s) self.assertTrue(len(self.hist) <= self.max_hist_size) def test_hist_discards_oldest(self): for t, s in enumerate(np.random.random(size=self.max_hist_size + num_tests)): self.hist.update(t, s) self.assertEqual(self.hist.get_oldest_timestamp(), max(0, t - self.max_hist_size + 1)) def test_matches_naive_hist(self): rand_nums = np.random.random(size=self.max_hist_size + num_tests) for t, s in enumerate(rand_nums): self.hist.update(t, s) naive_hist = np.zeros(len(self.bins), dtype=int) for n in rand_nums[max(0, t - self.max_hist_size + 1):t + 1]: naive_hist[self.bins[n]] += 1 self.assertTrue((naive_hist == self.hist.counts).all())
def __init__(self, ifo, width, max): self.fig, self.axes = SnglBurstUtils.make_burst_plot("Delay (s)", "Count / Delay") self.ifo = ifo self.nevents = 0 # 21 bins per filter width interval = segments.segment(0, max + 2) self.bins = rate.BinnedDensity(rate.NDBins((rate.LinearBins(interval[0], interval[1], int(float(abs(interval)) / width) * 21),))) self.axes.semilogy()
def __init__(self, ifo, interval, width): self.fig, self.axes = SnglBurstUtils.make_burst_plot("Peak Frequency (Hz)", "Trigger Rate Spectral Density (triggers / s / Hz)") self.ifo = ifo self.nevents = 0 # 21 bins per filter width bins = int(float(abs(interval)) / width) * 21 binning = rate.NDBins((rate.LinearBins(interval[0], interval[1], bins),)) self.rate = rate.BinnedDensity(binning)
def __init__(self, instrument, interval, width): self.fig, self.axes = SnglBurstUtils.make_burst_plot( r"$f_{\mathrm{recovered}} / f_{\mathrm{injected}}$", "Event Number Density") self.axes.loglog() self.instrument = instrument self.found = 0 # 21 bins per filter width bins = int(float(abs(interval)) / width) * 21 binning = rate.NDBins((rate.LinearBins(interval[0], interval[1], bins), )) self.offsets = rate.BinnedDensity(binning) self.coinc_offsets = rate.BinnedDensity(binning)
def __init__(self, instrument, interval, width): self.fig, self.axes = SnglBurstUtils.make_burst_plot( r"$t_{\mathrm{recovered}} - t_{\mathrm{injected}}$ (s)", "Triggers per Unit Offset") self.axes.semilogy() self.instrument = instrument self.found = 0 # 21 bins per filter width bins = int(float(abs(interval)) / width) * 21 binning = rate.NDBins((rate.LinearBins(interval[0], interval[1], bins), )) self.offsets = rate.BinnedDensity(binning) self.coinc_offsets = rate.BinnedDensity(binning)
def check_off_distribution(self, pop_min, pop_max, far=False): data_list_by_grb = self.lik_by_grb if far: data_list_by_grb = self.ifar_by_grb # prepare the plot if far: tag = 'log(IFAR)' sname = 'far' else: tag = 'Likelihood' sname = 'lik' plot = plotutils.SimplePlot(tag, r"cumulative sum",\ r"Cumulative distribution offsource") # create the hist data in a consistent binning nbins = 20 bins = rate.LinearBins(pop_min, pop_max, nbins) px = bins.lower() for data_list in data_list_by_grb: grb_name = data_list.grb_name tmp_pop = data_list.off_by_trial tmp_arr = np.array(tmp_pop, dtype=float) off_pop = tmp_arr[~np.isinf(tmp_arr)] off_pop.sort() py = range(len(off_pop), 0, -1) if far: off_pop = np.log10(off_pop) ifos = self.grb_data[grb_name]['ifos'] if ifos == 'H1L1': linestyle = '-' elif ifos == 'H1H2': linestyle = '-.' else: linestyle = ':' # add content to the plot plot.add_content(off_pop, py, color = self.colors.next(),\ linestyle = linestyle, label=grb_name) plot.finalize() plot.ax.set_yscale("log") return plot
def get_exttrig_trials(on_segs, off_segs, veto_files): """ Return a tuple of (off-source time bins, off-source veto mask, index of trial that is on source). The off-source veto mask is a one-dimensional boolean array where True means vetoed. @param on_segs: On-source segments @param off_segs: Off-source segments @param veto_files: List of filenames containing vetoes """ # Check that offsource length is a multiple of the onsource segment length trial_len = int(abs(on_segs)) if abs(off_segs) % trial_len != 0: raise ValueError, "The provided file's analysis segment is not "\ "divisible by the fold time." extent = (off_segs | on_segs).extent() # generate bins for trials num_trials = int(abs(extent)) // trial_len trial_bins = rate.LinearBins(extent[0], extent[1], num_trials) # incorporate veto file; in trial_veto_mask, True means vetoed. trial_veto_mask = numpy.zeros(num_trials, dtype=numpy.bool8) for veto_file in veto_files: new_veto_segs = segmentsUtils.fromsegwizard(open(veto_file), coltype=int) if new_veto_segs.intersects(on_segs): print >>sys.stderr, "warning: %s overlaps on-source segment" \ % veto_file trial_veto_mask |= rate.bins_spanned(trial_bins, new_veto_segs).astype(bool) # identify onsource trial index onsource_mask = rate.bins_spanned(trial_bins, on_segs).astype(bool) if sum(onsource_mask) != 1: raise ValueError, "on-source segment spans more or less than one trial" onsource_ind = numpy.arange(len(onsource_mask))[onsource_mask] return trial_bins, trial_veto_mask, onsource_ind
def plot_range(found_inj, missed_inj, seg_bins, tlohi, dlohi, horizon_history, colors = {'H1': numpy.array((1.0, 0.0, 0.0)), 'L1': numpy.array((0.0, 0.8, 0.0)), 'V1': numpy.array((1.0, 0.0, 1.0))}, fig = None, axes = None): tlo, thi = tlohi dlo, dhi = dlohi if fig is None: fig = plt.figure() if axes is None: axes = fig.add_subplot(111) # FIXME Add number of distance bins as option ndbins = rate.NDBins((rate.LinearBins(dlo, dhi, int(dhi - dlo + 1)), rate.IrregularBins(seg_bins))) vol, err = imr_utils.compute_search_volume_in_bins([f[1] for f in found_inj], missed_inj + [f[1] for f in found_inj], ndbins, lambda sim: (sim.distance, sim.geocent_end_time)) x = vol.bins[0].lower() dx = vol.bins[0].upper() - vol.bins[0].lower() y = (vol.array * 3./ (4. * math.pi))**(1./3.) yerr = (1./3.) * (3./(4.*math.pi))**(1./3.)*vol.array**(-2./3.) * err.array yerr[~numpy.isfinite(yerr)] = 0. err_lo = y - 2.0 * yerr err_lo[err_lo<=0] = 0. err_hi = y + 2.0 * yerr axes.bar(x, err_hi-err_lo, bottom=err_lo, color='c', alpha=0.6, label='95\% confidence interval\non range estimated \nfrom injections', width=dx, linewidth=0) for ifo in horizon_history.keys(): horizon_times = numpy.array(horizon_history[ifo].keys()).clip(tlo,thi) sensemon_range = numpy.array([horizon_history[ifo][seg]/2.26 for seg in horizon_times]) axes.scatter(horizon_times.compress(horizon_times <= horizon_history[ifo].maxkey()), sensemon_range, s = 1, color = colors[ifo], label='%s SenseMon Range' % ifo, alpha=1.0) xticks = numpy.linspace(tlo,thi,9) x_format = tkr.FuncFormatter(lambda x, pos: datetime.datetime(*GPSToUTC(int(x))[:7]).strftime("%Y-%m-%d, %H:%M:%S UTC")) axes.set_ylabel('Range (Mpc)') axes.set_xlim(tlo,thi) axes.set_ylim(0,5*(int(max(err_hi)/5.)+1)) axes.xaxis.set_major_formatter(x_format) axes.xaxis.set_ticks(xticks) axes.grid(color=(0.1,0.4,0.5), linewidth=2) return fig, axes
def create_hist_plot(self, n_bin, range=None): def create_area(x, dx, y, dy): px = [x - dx / 2, x + dx / 2, x + dx / 2, x - dx / 2, x - dx / 2] py = [y - dy / 2, y - dy / 2, y + dy / 2, y + dy / 2, y - dy / 2] return px, py def draw_error_boxes(plot, x, dx, y, dy, col): bx, by = create_area(x, dx, y, dy) plot.ax.fill(bx, by, ec='w', fc=col, alpha=0.2) bx, by = create_area(x, dx, y, 2 * dy) plot.ax.fill(bx, by, ec='w', fc=col, alpha=0.2) bx, by = create_area(x, dx, y, 3 * dy) plot.ax.fill(bx, by, ec='k', fc=col, alpha=0.2) return plot # set the surroundings of the parameter space if range is None: data_on = np.asarray(self.on_list) inf_ind = np.isinf(data_on) val_min = data_on[~inf_ind].min() val_max = data_on.max() else: val_min = range[0] val_max = range[1] # create the hists hist_on = np.zeros(n_bin) hist_off = np.zeros(n_bin) # create the rate bins lik_bins = rate.LinearBins(val_min, val_max, n_bin) # and fill the histograms for x in self.off_list: if x >= val_min and x <= val_max: hist_off[lik_bins[x]] += 1 for x in self.on_list: if x >= val_min and x <= val_max: hist_on[lik_bins[x]] += 1 # get the centres px = lik_bins.centres() dx = px[1] - px[0] # norm the histograms norm = self.n_grb / self.n_off hist_on_norm = hist_on hist_off_norm = norm * hist_off # create the plot plot = plotutils.SimplePlot(r"Likelihood", r"counts",\ r"Histogramm of on/offsource with %d bins"%\ (n_bin)) # the norm of the normed histograms: 1.0 plot.add_content(px, hist_on, color = 'r', marker = 'o',\ markersize = 10.0, label = 'on-source') plot.add_content(px, hist_off_norm, color = 'b',marker = 's', \ markersize = 10, label = 'off-source') # add the error shading for x, n in zip(px, hist_on): # calculate the error (just the statistic error) dn = np.sqrt(n) plot = draw_error_boxes(plot, x, dx, n, dn, 'r') plot.finalize() plot.ax.axis([val_min, val_max, 0.0, 20.0]) #return plot # insert the lines of the data itself for x in self.on_list: if x >= val_min and x <= val_max: plot.ax.plot([x, x], [0.0, 1.0], 'k') plot.ax.axis([val_min, val_max, 0.0, 20.0]) return plot
def finish(self, threshold): # bin the injections self._bin_events() # use the same binning for the found injection density as # was constructed for the efficiency self.found_density = rate.BinnedArray(self.efficiency.denominator.bins) # construct the amplitude weighting function amplitude_weight = rate.BinnedArray(rate.NDBins((rate.LinearBins(threshold - 100, threshold + 100, 10001),))) # gaussian window's width is the number of bins # corresponding to 10 units of amplitude, which is computed # by dividing 10 by the "volume" of the bin corresponding # to threshold. index is the index of the element in # amplitude_weight corresponding to the threshold. index, = amplitude_weight.bins[threshold,] window = rate.gaussian_window(10.0 / amplitude_weight.bins.volumes()[index]) window /= 10 * window[(len(window) - 1) / 2] # set the window data into the BinnedArray object. the # Gaussian peaks on the middle element of the window, which # we want to place at index in the amplitude_weight array. lo = index - (len(window) - 1) / 2 hi = lo + len(window) if lo < 0 or hi > len(amplitude_weight.array): raise ValueError("amplitude weighting window too large") amplitude_weight.array[lo:hi] = window # store the recovered injections in the found density bins # weighted by amplitude for x, y, z in self.recovered_xyz: try: weight = amplitude_weight[z,] except IndexError: # beyond the edge of the window weight = 0.0 self.found_density[x, y] += weight # the efficiency is only valid up to the highest energy # that has been injected. this creates problems later on # so, instead, for each frequency, identify the highest # energy that has been measured and copy the values for # that bin's numerator and denominator into the bins for # all higher energies. do the same for the counts in the # found injection density bins. # # numpy.indices() returns two arrays array, the first of # which has each element set equal to its x index, the # second has each element set equal to its y index, we keep # the latter. meanwhile numpy.roll() cyclically permutes # the efficiency bins down one along the y (energy) axis. # from this, the conditional finds bins where the # efficiency is greater than 0.9 but <= 0.9 in the bin # immediately above it in energy. we select the elements # from the y index array where the conditional is true, and # then use numpy.max() along the y direction to return the # highest such y index for each x index, which is a 1-D # array. finally, enumerate() is used to iterate over x # index and corresponding y index, and if the y index is # not negative (was found) the value from that x-y bin is # copied to all higher bins. n = self.efficiency.numerator.array d = self.efficiency.denominator.array f = self.found_density.array bady = -1 for x, y in enumerate(numpy.max(numpy.where((d > 0) & (numpy.roll(d, -1, axis = 1) <= 0), numpy.indices(d.shape)[1], bady), axis = 1)): if y != bady: n[x, y + 1:] = n[x, y] d[x, y + 1:] = d[x, y] f[x, y + 1:] = f[x, y] # now do the same for the bins at energies below those that # have been measured. bady = d.shape[1] for x, y in enumerate(numpy.min(numpy.where((d > 0) & (numpy.roll(d, 1, axis = 1) <= 0), numpy.indices(d.shape)[1], bady), axis = 1)): if y != bady: n[x, 0:y] = n[x, y] d[x, 0:y] = d[x, y] f[x, 0:y] = f[x, y] diagnostic_plot(self.efficiency.numerator.array, self.efficiency.denominator.bins, r"Efficiency Numerator (Before Averaging)", self.amplitude_lbl, "lalapps_excesspowerfinal_efficiency_numerator_before.png") diagnostic_plot(self.efficiency.denominator.array, self.efficiency.denominator.bins, r"Efficiency Denominator (Before Averaging)", self.amplitude_lbl, "lalapps_excesspowerfinal_efficiency_denominator_before.png") diagnostic_plot(self.found_density.array, self.efficiency.denominator.bins, r"Injections Lost / Unit of Threshold (Before Averaging)", self.amplitude_lbl, "lalapps_excesspowerfinal_found_density_before.png") # smooth the efficiency bins and the found injection # density bins using the same 2D window. window = rate.gaussian_window(self.window_size_x, self.window_size_y) window /= window[tuple((numpy.array(window.shape, dtype = "double") - 1) / 2)] rate.filter_binned_ratios(self.efficiency, window) rate.filter_array(self.found_density.array, window) diagnostic_plot(self.efficiency.numerator.array, self.efficiency.denominator.bins, r"Efficiency Numerator (After Averaging)", self.amplitude_lbl, "lalapps_excesspowerfinal_efficiency_numerator_after.png") diagnostic_plot(self.efficiency.denominator.array, self.efficiency.denominator.bins, r"Efficiency Denominator (After Averaging)", self.amplitude_lbl, "lalapps_excesspowerfinal_efficiency_denominator_after.png") diagnostic_plot(self.found_density.array, self.efficiency.denominator.bins, r"Injections Lost / Unit of Threshold (After Averaging)", self.amplitude_lbl, "lalapps_excesspowerfinal_found_density_after.png") # compute the uncertainties in the efficiency and its # derivative by assuming these to be the binomial counting # fluctuations in the numerators. p = self.efficiency.ratio() self.defficiency = numpy.sqrt(p * (1 - p) / self.efficiency.denominator.array) p = self.found_density.array / self.efficiency.denominator.array self.dfound_density = numpy.sqrt(p * (1 - p) / self.efficiency.denominator.array)
def __init__(self, interval, width): # 21 bins per filter width bins = int(float(abs(interval)) / width) * 21 self.binning = rate.NDBins((rate.LinearBins(interval[0], interval[1], bins), )) self.data = {}
] options, filenames = parse_command_line() # # ============================================================================= # # Custom SnglBurstTable append() method to put triggers directly into bins # # ============================================================================= # nbins = int( float(abs(options.read_segment)) / options.window) * bins_per_filterwidth binning = rate.NDBins((rate.LinearBins(options.read_segment[0], options.read_segment[1], nbins), )) trigger_rate = rate.BinnedDensity(binning) num_triggers = 0 def snglburst_append(self, row, verbose=options.verbose): global num_triggers, rate t = row.peak if t in options.read_segment: trigger_rate.count[t, ] += 1.0 num_triggers += 1 if verbose and not (num_triggers % 125): print >> sys.stderr, "sngl_burst rows read: %d\r" % num_triggers,