def __init__(self, rankingstat, nsamples = 2**24, verbose = False): # # bailout used by .from_xml() class method to get an # uninitialized instance # if rankingstat is None: return # # initialize binnings # self.noise_lr_lnpdf = rate.BinnedLnPDF(rate.NDBins((rate.ATanBins(-10., 30., 3000),))) self.signal_lr_lnpdf = rate.BinnedLnPDF(rate.NDBins((rate.ATanBins(-10., 30., 3000),))) self.candidates_lr_lnpdf = rate.BinnedLnPDF(rate.NDBins((rate.ATanBins(-10., 30., 3000),))) # # obtain analyzed segments that will be used to obtain livetime # self.segments = segmentsUtils.vote(rankingstat.denominator.triggerrates.segmentlistdict().values(),rankingstat.min_instruments) # # run importance-weighted random sampling to populate binnings. # self.signal_lr_lnpdf.array, self.noise_lr_lnpdf.array = binned_log_likelihood_ratio_rates_from_samples( self.signal_lr_lnpdf, self.noise_lr_lnpdf, rankingstat.ln_lr_samples(rankingstat.denominator.random_params(), rankingstat), nsamples = nsamples) if verbose: print("done computing ranking statistic PDFs", file=sys.stderr) # # apply density estimation kernels to counts # self.density_estimate(self.noise_lr_lnpdf, "noise model") self.density_estimate(self.signal_lr_lnpdf, "signal model") # # set the total sample count in the noise and signal # ranking statistic histogram equal to the total expected # count of the respective events from the experiment. This # information is required so that when adding ranking # statistic PDFs in our .__iadd__() method they are # combined with the correct relative weights, so that # .__iadd__() has the effect of marginalizing the # distribution over the experients being combined. # self.noise_lr_lnpdf.array /= self.noise_lr_lnpdf.array.sum() self.noise_lr_lnpdf.normalize() self.signal_lr_lnpdf.array /= self.signal_lr_lnpdf.array.sum() self.signal_lr_lnpdf.normalize()
def __init__(self, instruments): self.densities = {} for instrument in instruments: self.densities["%s_snr2_chi2" % instrument] = rate.BinnedLnPDF(rate.NDBins((rate.ATanLogarithmicBins(10, 1e7, 801), rate.ATanLogarithmicBins(.1, 1e4, 801)))) for pair in itertools.combinations(sorted(instruments), 2): dt = 0.005 + snglcoinc.light_travel_time(*pair) # seconds self.densities["%s_%s_dt" % pair] = rate.BinnedLnPDF(rate.NDBins((rate.ATanBins(-dt, +dt, 801),))) self.densities["%s_%s_dA" % pair] = rate.BinnedLnPDF(rate.NDBins((rate.ATanBins(-0.5, +0.5, 801),))) self.densities["%s_%s_df" % pair] = rate.BinnedLnPDF(rate.NDBins((rate.ATanBins(-0.2, +0.2, 501),))) # only non-negative rss timing residual bins will be used # but we want a binning that's linear at the origin so # instead of inventing a new one we just use atan bins that # are symmetric about 0 self.densities["instrumentgroup,rss_timing_residual"] = rate.BinnedLnPDF(rate.NDBins((InstrumentBins(names = instruments), rate.ATanBins(-0.02, +0.02, 1001))))
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 __init__(self, rankingstat, signal_noise_pdfs=None, nsamples=2**24, nthreads=8, verbose=False): # # bailout out used by .from_xml() class method to get an # uninitialized instance # if rankingstat is None: return # # initialize binnings # self.noise_lr_lnpdf = rate.BinnedLnPDF( rate.NDBins((rate.ATanBins(0., 110., 6000), ))) self.signal_lr_lnpdf = rate.BinnedLnPDF( rate.NDBins((rate.ATanBins(0., 110., 6000), ))) self.zero_lag_lr_lnpdf = rate.BinnedLnPDF( rate.NDBins((rate.ATanBins(0., 110., 6000), ))) self.segments = segmentsUtils.vote(rankingstat.segmentlists.values(), rankingstat.min_instruments) if rankingstat.template_ids is None: raise ValueError( "cannot be initialized from a RankingStat that is not for a specific set of templates" ) self.template_ids = rankingstat.template_ids # # bailout used by codes that want all-zeros histograms # if not nsamples: return # # run importance-weighted random sampling to populate # binnings. # if signal_noise_pdfs is None: signal_noise_pdfs = rankingstat nthreads = int(nthreads) assert nthreads >= 1 threads = [] for i in range(nthreads): assert nsamples // nthreads >= 1 q = multiprocessing.SimpleQueue() p = multiprocessing.Process( target=lambda: self. binned_log_likelihood_ratio_rates_from_samples_wrapper( q, self.signal_lr_lnpdf, self.noise_lr_lnpdf, rankingstat.ln_lr_samples( rankingstat.denominator.random_params(), signal_noise_pdfs), nsamples=nsamples // nthreads)) p.start() threads.append((p, q)) nsamples -= nsamples // nthreads nthreads -= 1 # sleep a bit to help random number seeds change time.sleep(1.5) while threads: p, q = threads.pop(0) signal_counts, noise_counts = q.get() self.signal_lr_lnpdf.array += signal_counts self.noise_lr_lnpdf.array += noise_counts p.join() if p.exitcode: raise Exception("sampling thread failed") if verbose: print("done computing ranking statistic PDFs", file=sys.stderr) # # apply density estimation kernels to counts # self.density_estimate(self.noise_lr_lnpdf, "noise model") self.density_estimate(self.signal_lr_lnpdf, "signal model") # # set the total sample count in the noise and signal # ranking statistic histogram equal to the total expected # count of the respective events from the experiment. this # information is required so that when adding ranking # statistic PDFs in our .__iadd__() method they are # combined with the correct relative weights, so that # .__iadd__() has the effect of marginalizing the # distribution over the experiments being combined. # self.noise_lr_lnpdf.array *= sum( rankingstat.denominator.candidate_count_model().values( )) / self.noise_lr_lnpdf.array.sum() self.noise_lr_lnpdf.normalize() self.signal_lr_lnpdf.array *= rankingstat.numerator.candidate_count_model( ) / self.signal_lr_lnpdf.array.sum() self.signal_lr_lnpdf.normalize()