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)
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)
# (SNO+-doc-2593-v8) for 5 year livetime # Note extrapolating here to 10 years Te130_0n2b_penalty_config = limit_config.LimitConfig(Te130_0n2b_prior, Te130_0n2b_counts) set_limit.configure_signal(Te130_0n2b_penalty_config) # Set new configs this time with more counts Te130_2n2b_counts = numpy.arange(8.7e6, 13.3e6, 0.1e6, dtype=float) sigma = 2.2647e6 # To use in penalty term (20%, Andy's document on # systematics) Te130_2n2b_penalty_config = limit_config.LimitConfig(Te130_2n2b_prior, Te130_2n2b_counts, sigma) set_limit.configure_background(Te130_2n2b._name, Te130_2n2b_penalty_config, plot_systematic=True) B8_Solar_counts = numpy.arange(12.0e3, 13.0e3, 0.1e3, dtype=float) sigma = 501.1988 # To use in penalty term B8_Solar_penalty_config = limit_config.LimitConfig(B8_Solar_prior, B8_Solar_counts, sigma) set_limit.configure_background(B8_Solar._name, B8_Solar_penalty_config, plot_systematic=True) # Calculate confidence limit print "90% CL at: " + str(set_limit.get_limit()) + " counts" plot_chi_squared.chi_squared_vs_signal(Te130_0n2b_config, penalty=Te130_0n2b_penalty_config) for syst_analyser in set_limit._syst_analysers.values(): store.dump_ndarray(syst_analyser._name+".hdf5", syst_analyser)
# Note extrapolating here to 10 years Te130_0n2b_penalty_config = limit_config.LimitConfig( Te130_0n2b_prior, Te130_0n2b_counts) set_limit.configure_signal(Te130_0n2b_penalty_config) # Set new configs this time with more counts Te130_2n2b_counts = numpy.arange(8.7e6, 13.3e6, 0.1e6, dtype=float) sigma = 2.2647e6 # To use in penalty term (20%, Andy's document on # systematics) Te130_2n2b_penalty_config = limit_config.LimitConfig( Te130_2n2b_prior, Te130_2n2b_counts, sigma) set_limit.configure_background(Te130_2n2b._name, Te130_2n2b_penalty_config, plot_systematic=True) B8_Solar_counts = numpy.arange(12.0e3, 13.0e3, 0.1e3, dtype=float) sigma = 501.1988 # To use in penalty term B8_Solar_penalty_config = limit_config.LimitConfig(B8_Solar_prior, B8_Solar_counts, sigma) set_limit.configure_background(B8_Solar._name, B8_Solar_penalty_config, plot_systematic=True) # Calculate confidence limit print "90% CL at: " + str(set_limit.get_limit()) + " counts" plot_chi_squared.chi_squared_vs_signal(Te130_0n2b_config, penalty=Te130_0n2b_penalty_config) for syst_analyser in set_limit._syst_analysers.values(): store.dump_ndarray(syst_analyser._name + ".hdf5", syst_analyser)
# Set chi squared calculator set_limit.set_calculator(calculator) # Calculate confidence limit sig_num_decays = set_limit.get_limit() half_life = converter.counts_to_half_life(sig_num_decays) print ("90% CL with Te130_2n2b floating at: " + str(sig_num_decays) + " ROI counts") print "90% CL with Te130_2n2b floating at: " + str(half_life) + " y" fig1 = plot_chi_squared.chi_squared_vs_signal(Te130_0n2b_config) fig1.Draw("AP") raw_input("RETURN to continue") for syst_analyser in set_limit._syst_analysers.values(): store.dump_ndarray(syst_analyser._name+"_2.hdf5", syst_analyser) # 3/ Fix no backgrounds and float all# Te130_0n2b = store.load(args.signal) # Reload background spectra Te130_2n2b = store.load(args.two_nu) B8_Solar = store.load(args.b8_solar) # Need to reset all of these for correct scaling Te130_0n2b._num_decays = Te130_0n2b.sum() Te130_0n2b._raw_events = 200034 Te130_2n2b._num_decays = Te130_2n2b.sum() print "Te130_2n2b._num_decays:", Te130_2n2b._num_decays Te130_2n2b._raw_events = 75073953 B8_Solar._num_decays = B8_Solar.sum() print "B8_Solar._num_decays:", B8_Solar._num_decays
# Set chi squared calculator set_limit.set_calculator(calculator) # Calculate confidence limit sig_num_decays = set_limit.get_limit() half_life = converter.counts_to_half_life(sig_num_decays) print("90% CL with Te130_2n2b floating at: " + str(sig_num_decays) + " ROI counts") print "90% CL with Te130_2n2b floating at: " + str(half_life) + " y" fig1 = plot_chi_squared.chi_squared_vs_signal(Te130_0n2b_config) fig1.Draw("AP") raw_input("RETURN to continue") for syst_analyser in set_limit._syst_analysers.values(): store.dump_ndarray(syst_analyser._name + "_2.hdf5", syst_analyser) # 3/ Fix no backgrounds and float all# Te130_0n2b = store.load(args.signal) # Reload background spectra Te130_2n2b = store.load(args.two_nu) B8_Solar = store.load(args.b8_solar) # Need to reset all of these for correct scaling Te130_0n2b._num_decays = Te130_0n2b.sum() Te130_0n2b._raw_events = 200034 Te130_2n2b._num_decays = Te130_2n2b.sum() print "Te130_2n2b._num_decays:", Te130_2n2b._num_decays Te130_2n2b._raw_events = 75073953 B8_Solar._num_decays = B8_Solar.sum() print "B8_Solar._num_decays:", B8_Solar._num_decays
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 "raw events:", spectrum._raw_events print "events:", spectrum.sum() signals.append(spectrum) # Load background spectra floating_backgrounds = [] Xe136_2n2b = store.load(args.two_nu) print Xe136_2n2b._name print "Num decays:", Xe136_2n2b._num_decays print "raw events:", Xe136_2n2b._raw_events print "events:", Xe136_2n2b.sum() floating_backgrounds.append(Xe136_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 "raw events:", B8_Solar._raw_events print "events:", B8_Solar.sum() floating_backgrounds.append(B8_Solar) # Apply FV and livetime cuts fv_radius = 1200.0 # 1.2m PRC 86, 021601 (2012) 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 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 # Signal configuration signal_configs_np = [] # no penalty term signal_configs = [] prior = 0.0 Xe136_0n2b_n1_counts = numpy.linspace(signals[0]._num_decays, 0.0, 100, False) # endpoint=False in linspace arrays Xe136_0n2b_n1_config_np = limit_config.LimitConfig(prior, Xe136_0n2b_n1_counts) Xe136_0n2b_n1_config = limit_config.LimitConfig(prior, Xe136_0n2b_n1_counts) signal_configs_np.append(Xe136_0n2b_n1_config_np) signal_configs.append(Xe136_0n2b_n1_config) Xe136_0n2b_n2_counts = numpy.linspace(signals[1]._num_decays, 0.0, 100, False) Xe136_0n2b_n2_config_np = limit_config.LimitConfig(prior, Xe136_0n2b_n2_counts) Xe136_0n2b_n2_config = limit_config.LimitConfig(prior, Xe136_0n2b_n2_counts) signal_configs_np.append(Xe136_0n2b_n2_config_np) signal_configs.append(Xe136_0n2b_n2_config) Xe136_0n2b_n3_counts = numpy.linspace(signals[2]._num_decays, 0.0, 100, False) Xe136_0n2b_n3_config_np = limit_config.LimitConfig(prior, Xe136_0n2b_n3_counts) Xe136_0n2b_n3_config = limit_config.LimitConfig(prior, Xe136_0n2b_n3_counts) signal_configs_np.append(Xe136_0n2b_n3_config_np) signal_configs.append(Xe136_0n2b_n3_config) Xe136_0n2b_n7_counts = numpy.linspace(signals[3]._num_decays, 0.0, 100, False) Xe136_0n2b_n7_config_np = limit_config.LimitConfig(prior, Xe136_0n2b_n7_counts) Xe136_0n2b_n7_config = limit_config.LimitConfig(prior, Xe136_0n2b_n7_counts) signal_configs_np.append(Xe136_0n2b_n7_config_np) signal_configs.append(Xe136_0n2b_n7_config) # Background configuration # Xe136_2n2b Xe136_2n2b_prior = 1.132e6 # Based on KLZ T_1/2, for 1 years # Since we used cut method to cut to livetime # No penalty term Xe136_2n2b_counts_np = numpy.array([Xe136_2n2b_prior]) Xe136_2n2b_config_np = limit_config.LimitConfig(Xe136_2n2b_prior, Xe136_2n2b_counts_np) # With penalty term Xe136_2n2b_counts = numpy.linspace(0.947*Xe136_2n2b_prior, 1.053*Xe136_2n2b_prior, 51) # 51 bins to make sure midpoint (no variation from prior) is included # to use in penalty term (5.3% PRC 86, 021601 (2012)) sigma = 0.053 * Xe136_2n2b_prior Xe136_2n2b_config = limit_config.LimitConfig(Xe136_2n2b_prior, Xe136_2n2b_counts, sigma) # B8_Solar # Assume same rate as SNO+ for now 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, 10) # 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 Xe136_atm_weight = 135.907219 # Molar Mass Calculator, http://www.webqc.org/mmcalc.php, 2015-05-07 Xe134_atm_weight = 133.90539450 # Molar Mass Calculator, http://www.webqc.org/mmcalc.php, 2015-06-03 # We want the atomic weight of the enriched Xenon XeEn_atm_weight = 0.9093*Xe136_atm_weight + 0.0889*Xe134_atm_weight Xe136_abundance = 0.089 # Xenon @ Periodic Table of Chemical Elements, http://www/webqc.org/periodictable-Xenon-Xe.html, 05/07/2015 loading = 0.0244 # PRC 86, 021601 (2012) ib_radius = 1540. # mm, PRC 86, 021601 (2012) scint_density = 7.5628e-7 # kg/mm^3, calculated by A Back 2015-07-28 # Make a list of associated nuclear physics info nuclear_params = [] # n=1: phase_space = 6.02e-16 matrix_element = 2.57 # 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.54e-17 matrix_element = 1.e-3 nuclear_params.append((phase_space, matrix_element)) # chi squared calculator calculator = chi_squared.ChiSquared() livetime = 112.3 / 365.25 # y, KamLAND-Zen 112.3 live days # 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(Xe136_2n2b._name, Xe136_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( "Xe136", Xe136_atm_weight, XeEn_atm_weight, Xe136_abundance, phase_space, matrix_element, loading=loading, fv_radius=fv_radius, outer_radius=ib_radius, scint_density=scint_density, 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(Xe136_2n2b._name, Xe136_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( "Xe136", Xe136_atm_weight, XeEn_atm_weight, Xe136_abundance, phase_space, matrix_element, loading=loading, fv_radius=fv_radius, outer_radius=ib_radius, scint_density=scint_density, 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+"Xe136_2n2b_config.hdf5", Xe136_2n2b_config) store.dump_ndarray(output_dir+"B8_Solar_config.hdf5", B8_Solar_config)