def get_correction_map(variable, chi1_f, chi2_f): """ Get the correction map for the passed variable (integrated) """ chi1_map = get_corr_map(chi1_f, variable) chi2_map = get_corr_map(chi2_f, variable) return divide(chi2_map, chi1_map)
def get_corr_map(corr_f, variable): """ Get the correction map for one file (either chi1 or chi2) for a given variable """ gen_h = corr_f.Get('fold_costh_phi_JpsiPt_JpsiRap_gen_HX') reco_h = corr_f.Get('fold_costh_phi_JpsiPt_JpsiRap_reco_HX') # project the histograms onto the variable and rebin them into the analysis # binning proj_dir = 0 if variable == 'costh' else 1 gen_h = rebin_1d_binning(project(gen_h, proj_dir), ANALYSIS_BINNING[variable]) reco_h = rebin_1d_binning(project(reco_h, proj_dir), ANALYSIS_BINNING[variable]) return divide(reco_h, gen_h)
def get_correction_map(cmfile, use_pt=True, use_acc=False): """ Get the correction map """ map_name = 'fold_costh_phi_JpsiPt_JpsiRap_{}_HX' reco = 'acc' if use_acc else 'reco' if use_pt: gen_dist = project(cmfile.Get(map_name.format('gen')), [0, 1, 2]) reco_dist = project(cmfile.Get(map_name.format(reco)), [0, 1, 2]) else: gen_dist = project(cmfile.Get(map_name.format('gen')), [1, 0]) reco_dist = project(cmfile.Get(map_name.format(reco)), [1, 0]) accmap = divide(reco_dist, gen_dist) return accmap
def main(args): """Main""" frames = args.frames.split(',') if args.bin_variable is not None: bin_var = parse_func_var(args.bin_variable) if args.binning is None: logging.error('You have to define a binning for \'{}\' if you want ' 'to use it as binning variable'.format(bin_var)) sys.exit(1) binning = parse_binning(args.binning) else: binning = None bin_var = None logging.info('Processing gen level file') gen_hists = create_histograms(get_dataframe(args.genlevelfile), frames, args.ncosth, args.nphi, bin_var, binning) logging.info('Processing reco level file') reco_hists = create_histograms(get_dataframe(args.recolevelfile), frames, args.ncosth, args.nphi, bin_var, binning, WEIGHT_F) logging.debug('Scaling gen level hists by '.format(args.scale_gen)) for hist in gen_hists.values(): hist.Scale(args.scale_gen) logging.info('calculating acceptance maps') acc_maps = OrderedDict() for name, hist in reco_hists.iteritems(): gen_map_n = [n for n in gen_hists if n in name] if len(gen_map_n) > 1: logging.warning('Found more than 1 gen level map for \'{}\': {}' .format(name, gen_map_n)) # Still use just the first, since we should always just have 1 acc_maps[name] = divide(hist, gen_hists[gen_map_n[0]]) logging.debug('storing to output file') outfile = r.TFile(args.outfile, 'recreate' if args.recreate else 'update') store_hists(outfile, gen_hists, 'gen_costh_phi', bin_var) store_hists(outfile, reco_hists, 'reco_costh_phi', bin_var) store_hists(outfile, acc_maps, 'acc_map_costh_phi', bin_var)
def get_ratio(dchi1, dchi2, variable, selections, hist_sett, get_weights=None): """ Get the chic2 / chic1 ratio """ hchi1 = create_hist(apply_selections(dchi1, selections), variable, hist_sett, get_weights) hchi2 = create_hist(apply_selections(dchi2, selections), variable, hist_sett, get_weights) # scale such that the integrated ratio is 1 nchi1 = hchi1.Integral() nchi2 = hchi2.Integral() ratio = divide(hchi2, hchi1) ratio.Scale(nchi1 / nchi2) return ratio
def get_acc_mask(cmfile, use_pt, min_acc): """ Define an acceptance (only) map mask to exclude events with very low acceptance values """ logging.info('Masking all bins of correction map with acceptance < {}' .format(min_acc)) if use_pt: gen_dist = project(cmfile.Get(MAP_NAME.format('gen')), [0, 1, 2]) acc_dist = project(cmfile.Get(MAP_NAME.format('acc')), [0, 1, 2]) else: gen_dist = project(cmfile.Get(MAP_NAME.format('gen')), [1, 0]) acc_dist = project(cmfile.Get(MAP_NAME.format('acc')), [1, 0]) accmap = divide(acc_dist, gen_dist) mask = get_array(accmap) < min_acc return mask
def main(args): """Main""" numfile = r.TFile.Open(args.numfile) denomfile = r.TFile.Open(args.denomfile) # use sets so that it is easier to find the histograms with the same names num_hists = set(list_obj(numfile, 'TH1', args.filter)) denom_hists = set(list_obj(denomfile, 'TH1', args.filter)) ratio_hists = num_hists.intersection(denom_hists) outfile = r.TFile(args.outfile, 'update' if args.update else 'recreate') for ratio_n in ratio_hists: logging.debug('Creating: {}'.format(ratio_n)) ratio = divide(numfile.Get(ratio_n), denomfile.Get(ratio_n)) outfile.cd() ratio.Write() outfile.Write('', r.TObject.kWriteDelete) outfile.Close()
def get_correction_map(cmfile, use_pt=False, acc_only=False, min_acc=None): """ Get the correction map from the correction map file """ # TODO: Potentially rebin this thing reco = 'acc' if acc_only else 'reco' if use_pt: gen_dist = project(cmfile.Get(MAP_NAME.format('gen')), [0, 1, 2]) reco_dist = project(cmfile.Get(MAP_NAME.format(reco)), [0, 1, 2]) else: gen_dist = project(cmfile.Get(MAP_NAME.format('gen')), [1, 0]) reco_dist = project(cmfile.Get(MAP_NAME.format(reco)), [1, 0]) accmap = divide(reco_dist, gen_dist) if min_acc is not None: acc_mask = get_acc_mask(cmfile, use_pt, min_acc) else: acc_mask = None return AcceptanceCorrectionProvider(accmap, mask=acc_mask)
def main(args): """Main""" with open(args.bininfo, 'r') as finfo: costh_info = json.load(finfo) fitfile = r.TFile.Open(args.fitres) wsp = fitfile.Get('ws_mass_fit') fit_graph = get_fit_graph(wsp, costh_info['costh_bins'], costh_info['costh_means']) histfile = r.TFile.Open(args.histfile) histlist = list(set(b.GetName() for b in histfile.GetListOfKeys())) ratio_combs = get_ratio_combs([h for h in histlist if 'chic1' in h], [h for h in histlist if 'chic2' in h]) ratios = [] for chi1_hist, chi2_hist in ratio_combs: h_chi1 = histfile.Get(chi1_hist) h_chi1.Scale(1 / h_chi1.Integral()) h_chi2 = histfile.Get(chi2_hist) h_chi2.Scale(1 / h_chi2.Integral()) ratio = divide(h_chi2, h_chi1) ratio.SetBinContent(ratio.GetNbinsX() + 1, 0) ratio.SetBinError(ratio.GetNbinsX() + 1, 0) chisqu, fit_norm = calc_chi2(ratio, fit_graph) ratios.append((get_delta_lambda(chi1_hist, chi2_hist), ratio, chisqu, fit_norm)) ratio.Scale(fit_norm) ratios.sort(key=lambda rr: sp.N(rr[0])) # print before removing "duplicates" print ('# Delta lambda, N, chi2, p, sigma') for ratio in ratios: print('{}, {:.3f}, {:.2f}, {:.3e}, {:.1f}' .format(ratio[0], ratio[3], ratio[2], chi2.sf(ratio[2], fit_graph.GetN() - 1), norm.isf(chi2.sf(ratio[2], fit_graph.GetN() - 1)))) # only retain one of the possible delta lambda = 0 results ratios = unique_w_key(ratios, lambda rr: rr[0]) leg = setup_legend(0.12, 0.12, 0.5, 0.4) leg.SetNColumns(2) plot_toy = [sp.S(x) for x in ['-8/5', '-1', '-1/3', '0', '4/3']] can = mkplot([rr[1] for rr in ratios if rr[0] in plot_toy], yRange=[0, 0.65], yLabel='#chi_{c2} / #chi_{c1}', leg=leg, xRange=[0.0, 1.0], drawOpt='L', legEntries=['#Delta#lambda_{#theta} = ' + str(rr[0]) for rr in ratios if rr[0] in plot_toy]) can = mkplot(fit_graph, can=can, leg=can.attached_tobjects[0], legEntries=['data'], attr=[{'color': 1, 'marker': 20, 'size': 1.5}], drawOpt='samePE') can.SaveAs(args.output)
def baseline_plot(baseline, compplots, **kwargs): """ Make a plot and compare the compplots with the baseline plots. Divides the plot into an absolute value plot in the top and a ratio plot using the baseline as denominator in the bottom. Args: baseline (plotable ROOT object): The baseline plotable that will be used as comparison for all the compplots compplots (plotable ROOT objects): The plotables that should be compared to the baseline Keyword Args: basename (str): Legend entry to be used for the baseline legEntries (list of str): legend entries to be used for the compplots yRangeRatio (tuple of floats): The minimum and maximum y-value for the ratio pad compname (str): Name describing the whole of the compplots that will be used in the y-axis of the ratio pad putline (float or list of floats): Put horizontal lines into the ratio pad at the given values Other Keyword Args are forwarded to mkplot. Returns: TCanvasWrapper: Transparent wrapper holding the plot and all its objects See Also: mkplot, plot_on_canvas """ comp_attr = kwargs.pop('attr', None) if comp_attr is None: comp_attr = default_attributes(open_markers=False, size=1.0) # the baseline will always be black. Try to match the size of the markers to # the one that were requested by the user base_attr = {'color': 1, 'marker': 20, 'size': 1.5} sizes = np.unique([a['size'] for a in comp_attr if 'size' in a]) if len(sizes) == 1: base_attr['size'] = sizes[0] attr = [base_attr] + comp_attr # use the xLabel only for the lower plot xLabel = kwargs.pop('xLabel', None) # add the baseline name to the legend entries (if any) legEntries = kwargs.pop('legEntries', None) base_name = kwargs.pop('basename', 'baseline') if legEntries is not None: legEntries = [base_name] + legEntries # setup canvas can = kwargs.pop('can', None) if can is None: can_name = create_random_str() can = r.TCanvas(can_name, '', 50, 50, 600, 600) can.cd() ppad = r.TPad('_'.join([can.GetName(), 'plotpad']), 'plotpad', 0, 0.3, 1, 1) r.SetOwnership(ppad, False) ppad.Draw() # plot the comparison plot ppad = mkplot([baseline] + make_iterable(compplots), attr=attr, can=ppad, legEntries=legEntries, **kwargs) can.cd() rpad = r.TPad('_'.join([can.GetName(), 'ratiopad']), 'rpad', 0, 0, 1, 0.33) rpad.SetBottomMargin(0.2) r.SetOwnership(rpad, False) rpad.Draw() # remove some kwargs for kwarg in ['yLabel', 'legPos', 'leg', 'legEntries', 'yRange', 'logy']: kwargs.pop(kwarg, None) ratios = [divide(p, baseline) for p in make_iterable(compplots)] # determine the ratios and plot them rpad = mkplot(ratios, attr=comp_attr, can=rpad, xLabel=xLabel, yLabel=' / '.join( [kwargs.pop('compname', 'distribution(s)'), base_name]), yRange=kwargs.pop('yRangeRatio', [None, None]), **kwargs) for hist in rpad.pltables: _set_ratio_properties(hist) putlines = kwargs.pop('putline', None) if putlines is not None: # Simply assume that all others follow the same as the first one lines = _get_ratio_lines(rpad.pltables[0], putlines) for line in lines: line.Draw() rpad.add_pltables(lines) # attach all plots to the returned canvas if not isinstance(can, TCanvasWrapper): can = TCanvasWrapper(can) # can.add_pltables(ppad.pltables + rpad.pltables) # for obj in ppad.attached_tobjects: # can.add_tobject(obj) can.add_tobject(ppad) can.add_tobject(rpad) return can