コード例 #1
0
    def test_get_limit(self):
        """ Test main limit setting code
        """
        numpy.random.seed()
        mu = 5.0
        sigma = 1.0
        for energy, radius, time in zip(
                numpy.random.normal(mu, sigma, self._n_events),
                numpy.random.uniform(self._signal._radial_low,
                                     self._signal._radial_high,
                                     self._n_events),
                numpy.random.uniform(self._signal._time_low,
                                     self._signal._time_high, self._n_events)):
            self._signal.fill(energy, radius, time)
            for background in self._backgrounds:
                background.fill(energy, radius, time)

        # Configure signal
        signal_counts = numpy.arange(1.0, 55.0, 1.0, dtype=float)
        signal_prior = 18.0
        signal_config = limit_config.LimitConfig(signal_prior, signal_counts)

        # Configure bkg_1
        # No penalty term to start with so just an array containing one value
        bkg_1_counts = numpy.arange(100.0, 101.0, 1.0, dtype=float)
        bkg_1_prior = 100.0
        bkg_1_config = limit_config.LimitConfig(bkg_1_prior, bkg_1_counts)

        # set chi squared calculator
        calculator = chi_squared.ChiSquared()

        # Test 1: test Exceptions
        limit_setter_1 = limit_setting.LimitSetting(
            self._signal, floating_backgrounds=self._backgrounds[:1])
        self.assertRaises(TypeError, limit_setter_1.get_limit)
        limit_setter_1.configure_signal(signal_config)
        self.assertRaises(KeyError, limit_setter_1.get_limit)
        limit_setter_1.configure_background("bkg_1", bkg_1_config)
        self.assertRaises(TypeError, limit_setter_1.get_limit)
        limit_setter_1.set_calculator(calculator)

        # Test 2: different limits with and without penalty term
        # Define ROI
        roi = (mu - sigma, mu + sigma)

        limit_setter_2 = limit_setting.LimitSetting(
            self._signal,
            floating_backgrounds=self._backgrounds[:1],
            roi=roi,
            pre_shrink=True)
        limit_setter_2.configure_signal(signal_config)
        limit_setter_2.configure_background("bkg_1", bkg_1_config)
        limit_setter_2.set_calculator(calculator)
        limit_2 = limit_setter_2.get_limit()

        # Now try with a penalty term
        # set new config this time with more background counts to cycle through
        bkg_1_penalty_counts = numpy.arange(75.0, 125.0, 0.5, dtype=float)
        bkg_1_sigma = 25.0  # To use in penalty term
        bkg_1_penalty_config = limit_config.LimitConfig(
            bkg_1_prior, bkg_1_penalty_counts, bkg_1_sigma)

        limit_setter_2.configure_background("bkg_1", bkg_1_penalty_config)
        limit_2_penalty = limit_setter_2.get_limit()
        self.assertNotEqual(limit_2, limit_2_penalty)

        # Test 3: Try with a second background
        # Configure bkg_2
        # No penalty term so just an array containing one value
        bkg_2_counts = numpy.arange(10.0, 11.0, 1.0, dtype=float)
        bkg_2_prior = 10.0
        bkg_2_config = limit_config.LimitConfig(bkg_2_prior, bkg_2_counts)

        limit_setter_3 = limit_setting.LimitSetting(
            self._signal,
            floating_backgrounds=self._backgrounds,
            roi=roi,
            pre_shrink=True)
        limit_setter_3.configure_signal(signal_config)
        limit_setter_3.configure_background("bkg_1", bkg_1_config)
        limit_setter_3.configure_background("bkg_2", bkg_2_config)
        limit_setter_3.set_calculator(calculator)
        limit_3 = limit_setter_3.get_limit()
        self.assertNotEqual(limit_2, limit_3)

        # Check chi squareds have been recorded for each background
        for config in limit_setter_3._background_configs.values():
            chi_squareds = config._chi_squareds
            self.assertTrue(chi_squareds.shape[1] > 0)
コード例 #2
0
    # Shrink spectra to 5 years - livetime used by Andy
    # And make 3.5m fiducial volume cut
    Te130_0n2b.shrink(0.0, 10.0, 0.0, 3500.0, 0.0, 5.0)
    Te130_2n2b.shrink(0.0, 10.0, 0.0, 3500.0, 0.0, 5.0)
    B8_Solar.shrink(0.0, 10.0, 0.0, 3500.0, 0.0, 5.0)

    # Create list of backgrounds
    backgrounds = []
    backgrounds.append(Te130_2n2b)
    backgrounds.append(B8_Solar)

    # Initialise limit setting class
    roi = (2.46, 2.68)  # Define ROI - as used by Andy
    set_limit = limit_setting.LimitSetting(Te130_0n2b,
                                           backgrounds,
                                           roi=roi,
                                           pre_shrink=True,
                                           verbose=args.verbose)

    # Configure Te130_0n2b
    Te130_0n2b_counts = numpy.arange(5.0, 500.0, 5.0, dtype=float)
    Te130_0n2b_prior = 262.0143  # Based on T_1/2 = 9.94e25 y @ 90% CL
    # (SNO+-doc-2593-v8) for 5 year livetime
    # Note extrapolating here to 10 years
    Te130_0n2b_config = limit_config.LimitConfig(Te130_0n2b_prior,
                                                 Te130_0n2b_counts)
    set_limit.configure_signal(Te130_0n2b_config)

    # Configure Te130_2n2b
    Te130_2n2b_counts = numpy.arange(11.323579e6,
                                     11.323580e6,
コード例 #3
0
def main(args):
    """ Script to set 90% CL on all four Majoron-emitting modes.
    """
    # Load signal spectra
    signals = []
    for signal_hdf5 in args.signals:
        spectrum = store.load(signal_hdf5)
        print spectrum._name
        print "Num decays:", spectrum._num_decays
        print "events:", spectrum.sum()
        signals.append(spectrum)

    # Load background spectra
    floating_backgrounds = []
    Te130_2n2b = store.load(args.two_nu)
    print Te130_2n2b._name
    Te130_2n2b._num_decays = Te130_2n2b.sum()  # Sum not raw events
    print "Num decays:", Te130_2n2b._num_decays
    print "events:", Te130_2n2b.sum()
    floating_backgrounds.append(Te130_2n2b)
    B8_Solar = store.load(args.b8_solar)
    print B8_Solar._name
    B8_Solar._num_decays = B8_Solar.sum()  # Sum not raw events
    print "Num decays:", B8_Solar._num_decays
    print "events:", B8_Solar.sum()
    floating_backgrounds.append(B8_Solar)

    # Apply FV and livetime cuts
    fv_radius = constants._fv_radius
    livetime = 1.0
    for spectrum in signals:
        spectrum.cut(time_low=0.0, time_high=livetime)  # cut to livetime
        spectrum.shrink(radial_low=0.0, radial_high=fv_radius)  # shrink to FV
        spectrum.shrink_to_roi(0.5, 3.0, 0)  # shrink to ROI
    for spectrum in floating_backgrounds:
        spectrum.cut(time_low=0.0, time_high=livetime)  # cut to livelime
        spectrum.shrink(radial_low=0.0, radial_high=fv_radius)  # shrink to FV
        spectrum.shrink_to_roi(0.5, 3.0, 0)  # shrink to ROI

    # Signal configuration
    signal_configs_np = []  # no penalty term
    signal_configs = []
    prior = 0.0

    Te130_0n2b_n1_counts = numpy.linspace(signals[0]._num_decays, 0.0, 100,
                                          False)
    # endpoint=False in linspace arrays
    Te130_0n2b_n1_config_np = limit_config.LimitConfig(prior,
                                                       Te130_0n2b_n1_counts)
    Te130_0n2b_n1_config = limit_config.LimitConfig(prior,
                                                    Te130_0n2b_n1_counts)
    signal_configs_np.append(Te130_0n2b_n1_config_np)
    signal_configs.append(Te130_0n2b_n1_config)

    Te130_0n2b_n2_counts = numpy.linspace(signals[1]._num_decays, 0.0, 100,
                                          False)
    Te130_0n2b_n2_config_np = limit_config.LimitConfig(prior,
                                                       Te130_0n2b_n2_counts)
    Te130_0n2b_n2_config = limit_config.LimitConfig(prior,
                                                    Te130_0n2b_n2_counts)
    signal_configs_np.append(Te130_0n2b_n2_config_np)
    signal_configs.append(Te130_0n2b_n2_config)

    Te130_0n2b_n3_counts = numpy.linspace(signals[2]._num_decays, 0.0, 100,
                                          False)
    Te130_0n2b_n3_config_np = limit_config.LimitConfig(prior,
                                                       Te130_0n2b_n3_counts)
    Te130_0n2b_n3_config = limit_config.LimitConfig(prior,
                                                    Te130_0n2b_n3_counts)
    signal_configs_np.append(Te130_0n2b_n3_config_np)
    signal_configs.append(Te130_0n2b_n3_config)

    Te130_0n2b_n7_counts = numpy.linspace(signals[3]._num_decays, 0.0, 100,
                                          False)
    Te130_0n2b_n7_config_np = limit_config.LimitConfig(prior,
                                                       Te130_0n2b_n7_counts)
    Te130_0n2b_n7_config = limit_config.LimitConfig(prior,
                                                    Te130_0n2b_n7_counts)
    signal_configs_np.append(Te130_0n2b_n7_config_np)
    signal_configs.append(Te130_0n2b_n7_config)

    # Background configuration
    # Te130_2n2b
    Te130_2n2b_prior = 3.7396e6  # Based on NEMO-3 T_1/2, for 1 year livetime
    # Since we used cut method to cut to livetime
    # No penalty term
    Te130_2n2b_counts_np = numpy.array([Te130_2n2b_prior])
    Te130_2n2b_config_np = limit_config.LimitConfig(Te130_2n2b_prior,
                                                    Te130_2n2b_counts_np)
    # With penalty term
    Te130_2n2b_counts = numpy.linspace(0.8 * Te130_2n2b_prior,
                                       1.2 * Te130_2n2b_prior, 51)
    # 51 bins to make sure midpoint (no variation from prior) is included
    # to use in penalty term (20%, Andy's document on systematics)
    sigma = 0.2 * Te130_2n2b_prior
    Te130_2n2b_config = limit_config.LimitConfig(Te130_2n2b_prior,
                                                 Te130_2n2b_counts, sigma)

    # B8_Solar
    # from integrating whole spectrum scaled to Valentina's number
    B8_Solar_prior = 1252.99691
    # No penalty term
    B8_Solar_counts_np = numpy.array([B8_Solar_prior])
    B8_Solar_config_np = limit_config.LimitConfig(B8_Solar_prior,
                                                  B8_Solar_counts_np)
    # With penalty term
    B8_Solar_counts = numpy.linspace(0.96 * B8_Solar_prior,
                                     1.04 * B8_Solar_prior, 11)
    # 11 bins to make sure midpoint (no variation from prior) is included
    sigma = 0.04 * B8_Solar_prior  # 4% To use in penalty term
    B8_Solar_config = limit_config.LimitConfig(B8_Solar_prior, B8_Solar_counts,
                                               sigma)

    # DBIsotope converter information - constant across modes
    isotope_name = "Te130"
    atm_weight_iso = 129.906229
    atm_weight_nat = 127.6
    abundance = 0.3408

    # Make a list of associated nuclear physics info
    nuclear_params = []
    # n=1:
    phase_space = 5.94e-16
    matrix_element = 3.97  # Averaged
    nuclear_params.append((phase_space, matrix_element))
    # n=2:
    phase_space = None
    matrix_element = None
    nuclear_params.append((phase_space, matrix_element))
    # n=1:
    phase_space = 1.06e-17  # Assuming two Majorons emitted
    matrix_element = 1.e-3
    nuclear_params.append((phase_space, matrix_element))
    # n=1:
    phase_space = 4.83e-17
    matrix_element = 1.e-3
    nuclear_params.append((phase_space, matrix_element))

    # chi squared calculator
    calculator = chi_squared.ChiSquared()

    # Set output location
    output_dir = echidna.__echidna_base__ + "/results/snoplus/"

    for signal, signal_config_np, nuclear_param in zip(signals,
                                                       signal_configs_np,
                                                       nuclear_params):
        print signal._name
        # Create no penalty limit setter
        set_limit_np = limit_setting.LimitSetting(
            signal, floating_backgrounds=floating_backgrounds)
        # Configure signal
        set_limit_np.configure_signal(signal_config_np)
        # Configure 2n2b
        set_limit_np.configure_background(Te130_2n2b._name,
                                          Te130_2n2b_config_np)
        # Configure B8
        set_limit_np.configure_background(B8_Solar._name, B8_Solar_config_np)

        # Set converter
        phase_space, matrix_element = nuclear_param
        roi_efficiency = signal.get_roi(0).get("efficiency")
        converter = decay.DBIsotope(isotope_name,
                                    atm_weight_iso,
                                    atm_weight_nat,
                                    abundance,
                                    phase_space,
                                    matrix_element,
                                    roi_efficiency=roi_efficiency)

        # Set chi squared calculator
        set_limit_np.set_calculator(calculator)

        # Get limit
        try:
            limit = set_limit_np.get_limit()
            print "-----------------------------------"
            print "90% CL at " + str(limit) + " counts"
            half_life = converter.counts_to_half_life(limit, livetime=livetime)
            print "90% CL at " + str(half_life) + " yr"
            print "-----------------------------------"
        except IndexError as detail:
            print "-----------------------------------"
            print detail
            print "-----------------------------------"

    for i, signal_config_np in enumerate(signal_configs_np):
        store.dump_ndarray(output_dir + signals[i]._name + "_np.hdf5",
                           signal_config_np)
    raw_input("RETURN to continue")

    signal_num = 0
    for signal, signal_config, nuclear_param in zip(signals, signal_configs,
                                                    nuclear_params):
        print signal._name
        # Create limit setter
        set_limit = limit_setting.LimitSetting(
            signal, floating_backgrounds=floating_backgrounds)
        # Configure signal
        set_limit.configure_signal(signal_config)
        # Configure 2n2b
        set_limit.configure_background(Te130_2n2b._name,
                                       Te130_2n2b_config,
                                       plot_systematic=True)
        # Configure B8
        set_limit.configure_background(B8_Solar._name,
                                       B8_Solar_config,
                                       plot_systematic=True)

        # Set converter
        phase_space, matrix_element = nuclear_param
        roi_efficiency = signal.get_roi(0).get("efficiency")
        converter = decay.DBIsotope(isotope_name,
                                    atm_weight_iso,
                                    atm_weight_nat,
                                    abundance,
                                    phase_space,
                                    matrix_element,
                                    roi_efficiency=roi_efficiency)

        # Set chi squared calculator
        set_limit.set_calculator(calculator)

        # Get limit
        try:
            limit = set_limit.get_limit()
            print "-----------------------------------"
            print "90% CL at " + str(limit) + " counts"
            half_life = converter.counts_to_half_life(limit, livetime=livetime)
            print "90% CL at " + str(half_life) + " yr"
            print "-----------------------------------"
        except IndexError as detail:
            print "-----------------------------------"
            print detail
            print "-----------------------------------"

        # Dump SystAnalysers to hdf5
        for syst_analyser in set_limit._syst_analysers.values():
            store.dump_ndarray(
                output_dir + syst_analyser._name + str(signal_num) + ".hdf5",
                syst_analyser)
        signal_num += 1

    # Dump configs to hdf5
    for i, signal_config in enumerate(signal_configs):
        store.dump_ndarray(output_dir + signals[i]._name + ".hdf5",
                           signal_config)
    store.dump_ndarray(output_dir + "Te130_2n2b_config.hdf5",
                       Te130_2n2b_config)
    store.dump_ndarray(output_dir + "B8_Solar_config.hdf5", B8_Solar_config)
コード例 #4
0
    # from integrating whole spectrum scaled to Valentina's number
    B8_Solar_prior = 12529.9691
    fixed_backgrounds = {
        Te130_2n2b._name: [Te130_2n2b, Te130_2n2b_prior],
        B8_Solar._name: [B8_Solar, B8_Solar_prior]
    }
    # Create fixed spectrum. Pre-shrink here if pre-shrinking in LimitSetting
    roi = (2.46, 2.68)  # Define ROI - as used by Andy
    fixed = limit_setting.make_fixed_background(fixed_backgrounds,
                                                pre_shrink=True,
                                                roi=roi)

    # Initialise limit setting class
    set_limit = limit_setting.LimitSetting(Te130_0n2b,
                                           fixed_background=fixed,
                                           roi=roi,
                                           pre_shrink=True,
                                           verbose=args.verbose)

    # Configure Te130_0n2b
    Te130_0n2b_counts = numpy.arange(5.0, 1000.0, 5.0, dtype=float)
    Te130_0n2b_prior = 0.  # Setting a 90% CL so no signal in observed
    Te130_0n2b_config = limit_config.LimitConfig(Te130_0n2b_prior,
                                                 Te130_0n2b_counts)
    set_limit.configure_signal(Te130_0n2b_config)

    # Set chi squared calculator
    calculator = chi_squared.ChiSquared()
    set_limit.set_calculator(calculator)

    # Calculate confidence limit