Пример #1
0
def chi2_to_plots(df_chi2, regularisation_settings, chi2_cut, channel):
    '''
    Plot chi2 figures
    '''
    # variable = regularisation_settings.variable
    plot_outpath = regularisation_settings.outpath.replace('tables/', 'plots/') + 'tauscan/'
    make_folder_if_not_exists(plot_outpath)

    fig1 = plt.figure()
    ax1 = fig1.add_subplot(1, 1, 1)
    ax1.set_xlim([pow(10,-6), 1])
    ax1.set_ylim([pow(10,-6), 1])
    for var in df_chi2.columns:
        if var == 'tau': continue

        plt.loglog(
            df_chi2['tau'],
            df_chi2[var],
            label = variables_latex[var],
        )
    plt.axhline(y=chi2_cut, color='black', linestyle='dashed')
    handles, labels = ax1.get_legend_handles_labels()
    ax1.legend(handles, labels, loc=4)
    ax1.set_xlabel('Regularisation Parameter \ensuremath{\\tau}')
    ax1.set_ylabel('\ensuremath{1-P(\\chi^{2}|NDF)}')

    pltName = os.path.join(plot_outpath,'{channel}_all_tauscan.pdf'.format(channel = channel))
    fig1.savefig(pltName) 
    print "Written plots to {plot_outpath}{channel}_all_tauscan.pdf".format(plot_outpath = plot_outpath, channel = channel)

    return
Пример #2
0
def chi2_to_df(chi2, taus, regularisation_settings, appendage=''):
    '''
    Take the list of taus and chi2 for each variable and append to those already there
    '''
    variable = regularisation_settings.variable
    channel = regularisation_settings.channel
    outpath = regularisation_settings.outpath

    df_new = pd.DataFrame(chi2)
    df_tau = pd.DataFrame(taus)

    # better output path
    make_folder_if_not_exists(outpath)
    tblName = os.path.join(outpath,'tbl_{}_tauscan{}.txt'.format(channel, appendage))
    df_existing = get_df_from_file(tblName)

    if df_existing is not None:
        df_new = pd.concat([df_new, df_existing], axis=1)
        if 'tau' not in df_existing.columns:
            df_new = pd.concat([df_new, df_tau], axis=1)

    # overwrite old df with new one
    with open(tblName,'w') as f:
        df_new.to_string(f, index=True)
        f.write('\n')
        f.close()
    print('DataFrame {} written to file'.format(tblName))
    # return the new df
    return df_new
    def save(self, phase_space):
        '''
        Saves the normalisation output into a JSON.
        I would like to change this to a pandas Dataframe at somepoint after 
        a few issues have been worked out
        '''
        from dps.utils.pandas_utilities import write_tuple_to_df
        from dps.utils.file_utilities import make_folder_if_not_exists
        # If normalisation hasnt been calculated  - then go calculate it!
        if not self.is_normalised: self.calculate_normalisation()

        output_folder = self.output_folder.format(
            com = self.com,
            var = self.variable,
            ps  = phase_space,
            cat = self.name,
        )
        make_folder_if_not_exists(output_folder)

        file_template = '{type}_{channel}.txt'
        f = file_template.format(
            type='normalisation', 
            channel=self.channel
        )

        write_tuple_to_df(
            self.normalisation,
            output_folder + f
        )
        return 
Пример #4
0
def chi2_to_df(chi2, taus, regularisation_settings, appendage=''):
    '''
    Take the list of taus and chi2 for each variable and append to those already there
    '''
    variable = regularisation_settings.variable
    channel = regularisation_settings.channel
    outpath = regularisation_settings.outpath

    df_new = pd.DataFrame(chi2)
    df_tau = pd.DataFrame(taus)

    # better output path
    make_folder_if_not_exists(outpath)
    tblName = os.path.join(outpath,'tbl_{}_tauscan{}.txt'.format(channel, appendage))
    df_existing = get_df_from_file(tblName)

    if df_existing is not None:
        df_new = pd.concat([df_new, df_existing], axis=1)
        if 'tau' not in df_existing.columns:
            df_new = pd.concat([df_new, df_tau], axis=1)

    # overwrite old df with new one
    with open(tblName,'w') as f:
        df_new.to_string(f, index=True)
        f.write('\n')
        f.close()
    print('DataFrame {} written to file'.format(tblName))
    # return the new df
    return df_new
def makeLatexTable( chi2, gChi2, outputPath, channel, crossSectionType ):
	'''
	Make the chi2 latex table
	'''
	models = chi2[chi2.keys()[0]]['Model']
	latexHeader = '\\begin{table}\n'
	if crossSectionType == 'normalised':
		latexHeader += '\t\caption{Results of a $\chi^{2}$ test between the normalised cross sections in data and several MC models.}\n'
		latexHeader += '\t\label{tb:Chi2_normalised}\n'
	elif crossSectionType == 'absolute':
		latexHeader += '\t\caption{Results of a $\chi^{2}$ test between the absolute cross sections in data and several MC models.}\n'
		latexHeader += '\t\label{tb:Chi2_absolute}\n'	
	latexHeader += '\t\centering\n'
	latexHeader += '\t\\scriptsize\n'

	latexContent = ''
	latexContent += makeTableContent(chi2, gChi2, models = ["TTJets_powhegPythia8", "TTJets_powhegPythia8_withMCTheoryUnc"], spacing=True)
	latexContent += makeTableContent(chi2, gChi2, models = ["TTJets_powhegHerwig", "TTJets_amcatnloPythia8", "TTJets_madgraphMLM"])

	latexFooter = '\\end{table}\n'
	latexTable = latexHeader+latexContent+latexFooter

	print latexTable
	make_folder_if_not_exists(outputPath)
	file_template = outputPath + '/chi2_{channel}.tex'.format(channel=channel)
	output_file = open(file_template, 'w')
	output_file.write(latexTable)
	output_file.close()
def generate_resolution_plots(histogram_information, var):
    '''
    Save the reconstructed resolution to root file
    Plot rexonstructed vs generated resolution
    '''

    histograms = [info['hist'] for info in histogram_information]
    first_hist = histograms[0]
    rebin_hist = first_hist.Rebin2D( 10, 10, "rebinned" ) # Make a coarser fine bin - mor stats for fit and saves compute time
    res_r_hist = rebin_hist.ProjectionX().Clone('res_r_'+var) #Initialise resolution plots
    res_g_hist = rebin_hist.ProjectionX().Clone('res_g_'+var)
    res_r_g_bias_hist = rebin_hist.ProjectionX().Clone('res_r_g_bias')

    n_bins = rebin_hist.GetNbinsX()
    for n_bin in range (0, n_bins):
        r_res, g_res = get_bin_resolution(rebin_hist, n_bin)
        res_r_hist.SetBinContent(n_bin, r_res)
        res_g_hist.SetBinContent(n_bin, g_res)
        res_r_hist.SetBinError(n_bin, 0)
        res_g_hist.SetBinError(n_bin, 0)
        res_r_g_bias_hist.SetBinContent(n_bin, r_res-g_res)

    make_folder_if_not_exists('plots/resolutionStudies/')

    # c = TCanvas('c1', 'c1', 800, 600)
    # c.SetLogy()
    # c.SetGrid()
    # # res_r_hist.GetXaxis().SetRangeUser(0, 1500)
    # res_r_hist.SetTitle("Reco(Gen) resolution;"+var+"; Resolution (GeV)")
    # res_r_hist.SetFillColor(3)
    # res_r_hist.SetFillStyle(3003);
    # res_r_hist.Draw("hist")
    # res_g_hist.SetFillColor(2)
    # res_g_hist.SetFillStyle(3003);
    # res_g_hist.Draw("hist same")
    # leg = TLegend(0.1,0.8,0.38,0.9);
    # leg.AddEntry(res_r_hist,"Res of Reco","f")
    # leg.AddEntry(res_g_hist,"Res of Gen","f")
    # leg.Draw()
    # c.Update()
    # c.SaveAs("plots/resolutionStudies/Resolution_"+var+".png")

    # c2 = TCanvas('c2', 'c2', 800, 600)
    # c.SetLogy()
    # c2.SetGrid()
    # res_r_g_bias_hist.SetTitle("Resolution Bias;"+var+"; Reco-Gen Resolution(GeV)")
    # # res_r_g_bias_hist.GetXaxis().SetRangeUser(0, 1500)
    # res_r_g_bias_hist.Draw("hist")
    # leg2 = TLegend(0.75,0.1,0.9,0.2);
    # leg2.AddEntry(res_r_g_bias_hist,"Resolution Bias","f")
    # leg2.Draw()
    # c2.Update()
    # c2.SaveAs("plots/resolutionStudies/ResolutionBias_"+var+".png")


    f = TFile("plots/resolutionStudies/resolution.root", "update")
    res_r_hist.Write(res_r_hist.GetName(),TObject.kOverwrite)
    f.Close()

    return
Пример #7
0
def make_covariance_plot(options, syst_name, matrix, label='Covariance'):
    '''
    Take the matrix in list form and bin edges in list form to create a TH2F of the covariance matrix
    Saves to plots/covariance_matrices/{PhaseSpace}/{Channel}/{Variable}/
    '''
    variable = options['variable']
    channel = options['channel']
    phase_space = options['phase_space']
    norm = options['normalisation_type']

    matrix_max = matrix.max()
    matrix_min = matrix.min()

    if (matrix_max == 0):
        return

    fig = plt.figure(figsize=CMS.figsize, dpi=CMS.dpi, facecolor=CMS.facecolor)
    ax = fig.add_subplot(1, 1, 1)
    ax.set_aspect('equal')
    if label == 'Correlation':
        im = plt.imshow(matrix,
                        interpolation='nearest',
                        cmap=my_cmap,
                        vmin=-1,
                        vmax=1)
    else:
        im = plt.imshow(matrix, interpolation='nearest', cmap=my_cmap)

    plt_title = variables_latex[variable] + ' ' + title
    if variable in ['HT', 'MET', 'WPT', 'ST', 'lepton_pt']:
        plt_title += ' [GeV]'

    ax.invert_yaxis()

    x_title = 'Bin i'
    y_title = 'Bin j'
    plt.title(plt_title, loc='right', **CMS.title)
    plt.xlabel(x_title, CMS.x_axis_title)
    plt.ylabel(y_title, CMS.y_axis_title)
    plt.tick_params(**CMS.axis_label_major)
    plt.tick_params(**CMS.axis_label_minor)
    plt.colorbar(im, fraction=0.046, pad=0.04)
    plt.tight_layout()

    # Output folder of covariance matrices
    covariance_matrix_output_path = 'plots/covariance_matrices/{phase_space}/{channel}/{norm}/'
    if options['mcUncertainty']:
        covariance_matrix_output_path = 'plots/covariance_matrices/mcUncertainty/{phase_space}/{channel}/{norm}/'
    covariance_matrix_output_path = covariance_matrix_output_path.format(
        channel=channel,
        phase_space=phase_space,
        norm=norm,
    )
    make_folder_if_not_exists(covariance_matrix_output_path)
    plt.savefig(covariance_matrix_output_path + syst_name + '_' + variable +
                '_' + label + '_matrix.pdf')
    fig.clf()
    plt.close()
    gc.collect()
Пример #8
0
def plot_data_vs_refold(args, regularisation_settings, tau):
    '''
    Plot the differences between the unfolded and refolded distributions

    TODO Include also with best tau - redo unfolding with best tau then come here
    '''
    from ROOT import gStyle

    variable = regularisation_settings.variable
    channel = regularisation_settings.channel
    plot_outpath = regularisation_settings.outpath.replace('tables/', 'plots/')+'tauscan/taus/'
    make_folder_if_not_exists(plot_outpath)

    # tau as string name for output
    tau = str(tau).replace('.', 'p')

    outfile = plot_outpath+'data_vs_refold_'+channel+'_'+variable+'_tau_'+tau+'.pdf'
    if args.run_measured_as_data:
        outfile = plot_outpath+'measured_vs_refold_'+channel+'_'+variable+'_tau_'+tau+'.pdf'
    if args.run_smeared_measured_as_data:
        outfile = plot_outpath+'smeared_vs_refold_'+channel+'_'+variable+'_tau_'+tau+'.pdf'
    if args.unfolded_binning:
        outfile = outfile.replace('.pdf', '_unf_binning.pdf')

    c = TCanvas('c1','c1',1000,800)
    gStyle.SetOptStat(0)

    p1 = TPad("pad1", "p1",0.0,0.2,1.0,1.0,21)
    p1.SetFillColor(0);
    p1.Draw()
    p2 = TPad("pad2", "p2",0.0,0.0,1.0,0.2,22)
    p2.SetFillColor(0);
    p2.Draw()

    p1.cd()
    regularisation_settings.h_data.SetTitle("Data vs Refolded Data;;NEvents")
    regularisation_settings.h_data.Draw()

    regularisation_settings.h_refolded.SetLineColor(2)
    regularisation_settings.h_refolded.Draw("same")

    leg1 = TLegend(0.7, 0.8, 0.9, 0.9)
    leg1.SetLineColor(0)
    leg1.SetFillColor(0)
    leg1.AddEntry(regularisation_settings.h_data, "Data")
    leg1.AddEntry(regularisation_settings.h_refolded, "Refolded Data")
    leg1.Draw()

    p2.cd()
    h_ratio = regularisation_settings.h_data.Clone()
    h_ratio.Divide(regularisation_settings.h_refolded)
    h_ratio.SetTitle(";"+variable+";")
    h_ratio.SetLineColor(1);
    h_ratio.Draw()

    c.SaveAs(outfile)
    c.Delete()
    print "Written plots to {outfile}".format(outfile = outfile)
    return
Пример #9
0
    def submit(self):
        '''
            Submits all registered jobs to the local HTCondor scheduler using
            a job template (DailyPythonScripts/condor/job_template) description
            file and the 'condor_submit' command
        '''
        today = time.strftime("%d-%m-%Y")
        job_folder = 'jobs/{0}/'.format(today)
        make_folder_if_not_exists(job_folder)
        make_folder_if_not_exists(job_folder + 'logs')
        # construct jobs
        self._construct_jobs()
        # convert each job into a pickle file
        # construct a class ad for each job
        with open('condor/job_template', 'r') as template:
            job_template = template.read()
        condor_jobs = []

        # prepare DPS for submission
        self._dps_tar_directory_on_hdfs = '/TopQuarkGroup/condor_dps/{you}/{now}/'.format(
                                                                                            you = getpass.getuser(), 
                                                                                            now = time.strftime('%d_%m_%Y_%H_%M') 
                                                                                            )

        for i, job in enumerate(self.prepared_jobs):
            job_file = job_folder + 'job_{0}.pkl'.format(i)
            job_desc_file = job_folder + 'job_{0}.dsc'.format(i)
            job_description = job_template.replace('%pkl_file%', job_file)
            job_description = job_description.replace('%dir_of_dps_on_hdfs%',
                                                      self._dps_tar_directory_on_hdfs)
            job_description = job_description.replace('%total_memory%',
                                                      str(self.request_memory))
            job_description = job_description.replace('%n_jobs_to_run%',
                                                      str(self.n_jobs_to_run))
            job_description = job_description.replace('%n_jobs_to_split%',
                                                      str(self.n_jobs_to_split))
            input_files = []
            if hasattr(job, 'additional_input_files'):
                input_files.extend(job.additional_input_files)
            input_files_str = ','.join(input_files)
            job_description = job_description.replace('%input_files%',
                                                      input_files_str)
            job_description = job_description.replace('%today%', today)

            with open(job_file, 'w+') as jf:
                pickle.dump(job, jf)
            with open(job_desc_file, 'w+') as jdf:
                jdf.write(job_description)

            condor_jobs.append(job_desc_file)

        prepare_process = subprocess.Popen(['./condor/prepare_dps.sh',self._dps_tar_directory_on_hdfs])
        prepare_process.communicate()
        
        # # submit jobs
        for j in condor_jobs:
            p = subprocess.Popen(['condor_submit', j])
            p.communicate()  # wait until command completed
Пример #10
0
def unfold_results(results, category, channel, h_truth, h_measured, h_response,
                   method):
    global variable, path_to_JSON
    h_data = value_error_tuplelist_to_hist(results, bin_edges[variable])
    unfolding = Unfolding(h_truth, h_measured, h_response, method=method)

    #turning off the unfolding errors for systematic samples
    if category != 'central':
        unfoldCfg.Hreco = 0

    h_unfolded_data = unfolding.unfold(h_data)

    #export the D and SV distributions
    SVD_path = path_to_JSON + '/' + variable + '/unfolding_objects/' + channel + '/kv_' + str(
        unfoldCfg.SVD_k_value) + '/'
    make_folder_if_not_exists(SVD_path)
    if method == 'TSVDUnfold':
        SVDdist = TFile(
            SVD_path + method + '_SVDdistributions_' + category + '.root',
            'recreate')
        directory = SVDdist.mkdir('SVDdist')
        directory.cd()
        unfolding.unfoldObject.GetD().Write()
        unfolding.unfoldObject.GetSV().Write()
        #    unfolding.unfoldObject.GetUnfoldCovMatrix(data_covariance_matrix(h_data), unfoldCfg.SVD_n_toy).Write()
        SVDdist.Close()
    else:
        SVDdist = TFile(
            SVD_path + method + '_SVDdistributions_Hreco' +
            str(unfoldCfg.Hreco) + '_' + category + '.root', 'recreate')
        directory = SVDdist.mkdir('SVDdist')
        directory.cd()
        unfolding.unfoldObject.Impl().GetD().Write()
        unfolding.unfoldObject.Impl().GetSV().Write()
        h_truth.Write()
        h_measured.Write()
        h_response.Write()
        #    unfolding.unfoldObject.Impl().GetUnfoldCovMatrix(data_covariance_matrix(h_data), unfoldCfg.SVD_n_toy).Write()
        SVDdist.Close()

    #export the whole unfolding object if it doesn't exist
    if method == 'TSVDUnfold':
        unfolding_object_file_name = SVD_path + method + '_unfoldingObject_' + category + '.root'
    else:
        unfolding_object_file_name = SVD_path + method + '_unfoldingObject_Hreco' + str(
            unfoldCfg.Hreco) + '_' + category + '.root'
    if not os.path.isfile(unfolding_object_file_name):
        unfoldingObjectFile = TFile(unfolding_object_file_name, 'recreate')
        directory = unfoldingObjectFile.mkdir('unfoldingObject')
        directory.cd()
        if method == 'TSVDUnfold':
            unfolding.unfoldObject.Write()
        else:
            unfolding.unfoldObject.Impl().Write()
        unfoldingObjectFile.Close()

    del unfolding
    return hist_to_value_error_tuplelist(h_unfolded_data)
Пример #11
0
    def submit(self):
        '''
            Submits all registered jobs to the local HTCondor scheduler using
            a job template (DailyPythonScripts/condor/job_template) description
            file and the 'condor_submit' command
        '''
        today = time.strftime("%d-%m-%Y")
        job_folder = 'jobs/{0}/'.format(today)
        make_folder_if_not_exists(job_folder)
        make_folder_if_not_exists(job_folder + 'logs')
        # construct jobs
        self._construct_jobs()
        # convert each job into a pickle file
        # construct a class ad for each job
        with open('dps/condor/job_template', 'r') as template:
            job_template = template.read()
        condor_jobs = []

        # prepare DPS for submission
        self._dps_tar_directory_on_hdfs = '/TopQuarkGroup/condor_dps/{you}/{now}/'.format(
                                                                                            you = getpass.getuser(), 
                                                                                            now = time.strftime('%d_%m_%Y_%H_%M') 
                                                                                            )

        for i, job in enumerate(self.prepared_jobs):
            job_file = job_folder + 'job_{0}.pkl'.format(i)
            job_desc_file = job_folder + 'job_{0}.dsc'.format(i)
            job_description = job_template.replace('%pkl_file%', job_file)
            job_description = job_description.replace('%dir_of_dps_on_hdfs%',
                                                      self._dps_tar_directory_on_hdfs)
            job_description = job_description.replace('%total_memory%',
                                                      str(self.request_memory))
            job_description = job_description.replace('%n_jobs_to_run%',
                                                      str(self.n_jobs_to_run))
            job_description = job_description.replace('%n_jobs_to_split%',
                                                      str(self.n_jobs_to_split))
            input_files = []
            if hasattr(job, 'additional_input_files'):
                input_files.extend(job.additional_input_files)
            input_files_str = ','.join(input_files)
            job_description = job_description.replace('%input_files%',
                                                      input_files_str)
            job_description = job_description.replace('%today%', today)

            with open(job_file, 'w+') as jf:
                pickle.dump(job, jf)
            with open(job_desc_file, 'w+') as jdf:
                jdf.write(job_description)

            condor_jobs.append(job_desc_file)

        prepare_process = subprocess.Popen(['./dps/condor/prepare_dps.sh',self._dps_tar_directory_on_hdfs])
        prepare_process.communicate()
        
        # # submit jobs
        for j in condor_jobs:
            p = subprocess.Popen(['condor_submit', j])
            p.communicate()  # wait until command completed
def makeAllPlots(file_name, output_directory_base):
    centre_of_mass, channel, variable, sample, tau_value = get_info_from_file_name( file_name )

    k_value = 0
    output_folder = '{option_output}/{centre_of_mass}TeV/{variable}/{channel}/{sample}/'
    output_folder = output_folder.format(option_output=output_directory_base,
                                         centre_of_mass=centre_of_mass,
                                         variable=variable,
                                         channel=channel,
                                         sample = sample)
    make_folder_if_not_exists(output_folder)
    output_formats = ['pdf']

    bins = array('d', bin_edges_vis[variable])
    nbins = len(bins) - 1

    msg = 'Producing unfolding pull plots for {0} variable, channel: {1}'
    print(msg.format(variable, channel))
    print ('Output folder: {0}'.format(output_folder))

    pulls = get_data(file_name, subset='pull')
    bias = get_data(file_name, subset='bias')
    
    fit_results = []
    mean_bias_in_each_bin = []
    sumBias2 = 0
    for bin_i in range(0, nbins):
        fr = plot_pull(pulls, centre_of_mass, channel, variable, k_value,
                       tau_value, output_folder, output_formats,
                       bin_index=bin_i, n_bins=nbins)

        mean_bias_in_bin_i = mean_bias(bias, bin_index=bin_i, n_bins=nbins)

        sumBias2 += mean_bias_in_bin_i**2
        mean_bias_in_each_bin.append( abs(mean_bias_in_bin_i) * 100 )
        fit_results.append(fr)

    mean_bias_over_all_bins = sqrt(sumBias2) / nbins * 100

    plot_fit_results(fit_results, centre_of_mass, channel, variable, k_value, tau_value,
                     output_folder, output_formats, bins)

    plot_bias_in_all_bins( mean_bias_in_each_bin,
                            mean_bias_over_all_bins,
                            centre_of_mass, channel, variable, tau_value,
                            output_folder, output_formats, 
                            bins
                            )
    # plot all bins
    plot_pull(pulls, centre_of_mass, channel, variable, k_value, tau_value,
              output_folder, output_formats)
    del pulls  # deleting to make space in memory

    difference = get_data(file_name, subset='difference')
    plot_difference(difference, centre_of_mass, channel, variable, k_value,
                    tau_value, output_folder, output_formats)
def compare_vjets_templates( variable = 'MET', met_type = 'patType1CorrectedPFMet',
                             title = 'Untitled', channel = 'electron' ):
    ''' Compares the V+jets templates in different bins
     of the current variable'''
    global fit_variable_properties, b_tag_bin, save_as
    variable_bins = variable_bins_ROOT[variable]
    histogram_template = get_histogram_template( variable )
    
    for fit_variable in electron_fit_variables:
        all_hists = {}
        inclusive_hist = None
        save_path = 'plots/%dTeV/fit_variables/%s/%s/' % ( measurement_config.centre_of_mass_energy, variable, fit_variable )
        make_folder_if_not_exists( save_path + '/vjets/' )
        
        max_bins = len( variable_bins )
        for bin_range in variable_bins[0:max_bins]:
            
            params = {'met_type': met_type, 'bin_range':bin_range, 'fit_variable':fit_variable, 'b_tag_bin':b_tag_bin, 'variable':variable}
            fit_variable_distribution = histogram_template % params
            # format: histograms['data'][qcd_fit_variable_distribution]
            histograms = get_histograms_from_files( [fit_variable_distribution], histogram_files )
            prepare_histograms( histograms, rebin = fit_variable_properties[fit_variable]['rebin'], scale_factor = measurement_config.luminosity_scale )
            all_hists[bin_range] = histograms['V+Jets'][fit_variable_distribution]
    
        # create the inclusive distributions
        inclusive_hist = deepcopy( all_hists[variable_bins[0]] )
        for bin_range in variable_bins[1:max_bins]:
            inclusive_hist += all_hists[bin_range]
        for bin_range in variable_bins[0:max_bins]:
            if not all_hists[bin_range].Integral() == 0:
                all_hists[bin_range].Scale( 1 / all_hists[bin_range].Integral() )
        # normalise all histograms
        inclusive_hist.Scale( 1 / inclusive_hist.Integral() )
        # now compare inclusive to all bins
        histogram_properties = Histogram_properties()
        histogram_properties.x_axis_title = fit_variable_properties[fit_variable]['x-title']
        histogram_properties.y_axis_title = fit_variable_properties[fit_variable]['y-title']
        histogram_properties.y_axis_title = histogram_properties.y_axis_title.replace( 'Events', 'a.u.' )
        histogram_properties.x_limits = [fit_variable_properties[fit_variable]['min'], fit_variable_properties[fit_variable]['max']]
        histogram_properties.title = title
        histogram_properties.additional_text = channel_latex[channel] + ', ' + b_tag_bins_latex[b_tag_bin]
        histogram_properties.name = variable + '_' + fit_variable + '_' + b_tag_bin + '_VJets_template_comparison'
        histogram_properties.y_max_scale = 1.5
        measurements = {bin_range + ' GeV': histogram for bin_range, histogram in all_hists.iteritems()}
        measurements = OrderedDict( sorted( measurements.items() ) )
        fit_var = fit_variable.replace( 'electron_', '' )
        fit_var = fit_var.replace( 'muon_', '' )
        graphs = spread_x( measurements.values(), fit_variable_bin_edges[fit_var] )
        for key, graph in zip( sorted( measurements.keys() ), graphs ):
            measurements[key] = graph
        compare_measurements( models = {'inclusive' : inclusive_hist},
                             measurements = measurements,
                             show_measurement_errors = True,
                             histogram_properties = histogram_properties,
                             save_folder = save_path + '/vjets/',
                             save_as = save_as )
Пример #14
0
def df_to_latexFile(filename, df):
    '''
	Convert data frame to latex and save to file
	'''
    import os
    from dps.utils.file_utilities import make_folder_if_not_exists
    make_folder_if_not_exists(os.path.dirname(filename))
    f = open(filename, 'w')
    f.write(df.to_latex())
    f.close()
def df_to_latexFile(filename, df):
	'''
	Convert data frame to latex and save to file
	'''
	import os
	from dps.utils.file_utilities import make_folder_if_not_exists
	make_folder_if_not_exists(os.path.dirname(filename))
	f = open(filename, 'w')
	f.write(df.to_latex())
	f.close()
def print_xsections(xsections, channel, toFile=True):
    global savePath, variable, k_value, met_type, b_tag_bin
    printout = '\n'
    printout += '=' * 60
    printout = '\n'
    printout += 'Results for %s variable, %s channel, k-value %s, met type %s, %s b-tag region\n' % (
        variable, channel, k_value, met_type, b_tag_bin)
    printout += '=' * 60
    printout += '\n'
    rows = {}
    header = 'Measurement'
    scale = 100

    bins = variable_bins_ROOT[variable]
    assert (len(bins) == len(xsections['central']))

    for bin_i, variable_bin in enumerate(bins):
        header += '& $\sigma_{meas}$ %s bin %s~\GeV' % (variable, variable_bin)
        for source in categories:
            value, error = xsections[source][bin_i]
            relativeError = getRelativeError(value, error)
            text = ' $(%.2f \pm %.2f) \cdot 10^{-2}$ ' % (
                value * scale,
                error * scale) + '(%.2f' % (relativeError * 100) + '\%)'
            if rows.has_key(source):
                rows[source].append(text)
            else:
                rows[source] = [translateOptions[source], text]

    header += '\\\\ \n'
    printout += header
    printout += '\hline\n'
    for item in rows['central']:
        printout += item + '&'
    printout = printout.rstrip('&')
    printout += '\\\\ \n'

    for source in sorted(rows.keys()):
        if source == 'central':
            continue
        for item in rows[source]:
            printout += item + '&'
        printout = printout.rstrip('&')
        printout += '\\\\ \n'
    printout += '\hline \n\n'

    make_folder_if_not_exists(savePath + '/' + variable)
    if toFile:
        output_file = open(
            savePath + '/' + variable + '/normalised_xsection_result_' +
            channel + '_' + met_type + '_kv' + str(k_value) + '.tex', 'w')
        output_file.write(printout)
        output_file.close()
    else:
        print printout
def make_covariance_plot( options, syst_name, matrix, label='Covariance' ):    
    '''
    Take the matrix in list form and bin edges in list form to create a TH2F of the covariance matrix
    Saves to plots/covariance_matrices/{PhaseSpace}/{Channel}/{Variable}/
    '''
    variable = options['variable']
    channel = options['channel']
    phase_space = options['phase_space']
    norm=options['normalisation_type']

    matrix_max = matrix.max()
    matrix_min = matrix.min()

    if( matrix_max == 0):
        return

    fig = plt.figure( figsize = CMS.figsize, dpi = CMS.dpi, facecolor = CMS.facecolor )
    ax = fig.add_subplot(1,1,1)
    ax.set_aspect('equal')
    if label=='Correlation':
        im=plt.imshow(matrix, interpolation='nearest', cmap = my_cmap, vmin = -1, vmax = 1 )
    else:
        im=plt.imshow(matrix, interpolation='nearest', cmap = my_cmap )

    plt_title = variables_latex[variable]+' '+title
    if variable in ['HT', 'MET', 'WPT', 'ST', 'lepton_pt']:
        plt_title += ' [GeV]'

    ax.invert_yaxis()

    x_title = 'Bin i'
    y_title = 'Bin j'
    plt.title( plt_title,loc='right', **CMS.title )
    plt.xlabel( x_title, CMS.x_axis_title )
    plt.ylabel( y_title, CMS.y_axis_title )
    plt.tick_params( **CMS.axis_label_major )
    plt.tick_params( **CMS.axis_label_minor ) 
    plt.colorbar(im,fraction=0.046, pad=0.04)
    plt.tight_layout()

    # Output folder of covariance matrices
    covariance_matrix_output_path = 'plots/covariance_matrices/{phase_space}/{channel}/{norm}/'
    if options['mcUncertainty']:
        covariance_matrix_output_path = 'plots/covariance_matrices/mcUncertainty/{phase_space}/{channel}/{norm}/'
    covariance_matrix_output_path = covariance_matrix_output_path.format(
        channel = channel,
        phase_space = phase_space,
        norm = norm,
        )
    make_folder_if_not_exists(covariance_matrix_output_path)
    plt.savefig(covariance_matrix_output_path+syst_name+'_'+variable+'_'+label+'_matrix.pdf')
    fig.clf()
    plt.close()
    gc.collect()
Пример #18
0
def saveAs(canvas, name, outputFormats=['png'], outputFolder=''):
    canvas.RedrawAxis()
    if not outputFolder == '' and not outputFolder.endswith('/'):
        outputFolder += '/'
    for outputFormat in outputFormats:
        fullFileName = outputFolder + name + '.' + outputFormat
        if '/' in fullFileName:
            path = fullFileName[:fullFileName.rfind('/')]
            make_folder_if_not_exists(path)
        
        canvas.SaveAs(fullFileName)
Пример #19
0
def print_output(signal_region_hists, output_folder_to_use, branchName,
                 channel):
    '''Printout on normalisation of different samples to screen and table'''
    print 'Normalisation after selection'
    print 'Single Top :', signal_region_hists['SingleTop'].integral(
        overflow=True)
    print '-' * 60
    mcSum = signal_region_hists['SingleTop'].integral(overflow=True)
    print 'Total DATA :', signal_region_hists['SingleTop'].integral(
        overflow=True)
    print 'Total MC   :', mcSum
    print '=' * 60

    output_folder = output_folder_to_use + 'tables/'
    make_folder_if_not_exists(output_folder)

    summary = {}
    summary['SingleTop'] = []
    summary['TotalMC'] = []
    summary['DataToMC'] = []

    # Bin by Bin
    for bin in signal_region_hists['SingleTop'].bins_range():
        ST = signal_region_hists['SingleTop'].integral(xbin1=bin,
                                                       xbin2=bin,
                                                       overflow=True)

        totalMC = ST
        if totalMC > 0:
            dataToMC = ST / totalMC
        else:
            dataToMC = -99
        summary['SingleTop'].append(ST)
        summary['TotalMC'].append(totalMC)
        summary['DataToMC'].append(dataToMC)

    # Total
    ST = signal_region_hists['SingleTop'].integral(overflow=True)

    totalMC = ST
    if totalMC > 0:
        dataToMC = ST / totalMC
    else:
        dataToMC = -99
    summary['SingleTop'].append(ST)
    summary['TotalMC'].append(totalMC)
    summary['DataToMC'].append(dataToMC)

    order = ['SingleTop', 'TotalMC', 'DataToMC']

    d = dict_to_df(summary)
    d = d[order]
    df_to_file(output_folder + channel + '_' + branchName + '.txt', d)
    return
def create_toy_mc(input_files, sample, output_folder, n_toy, centre_of_mass, config):
    from dps.utils.file_utilities import make_folder_if_not_exists
    from dps.utils.toy_mc import generate_toy_MC_from_distribution, generate_toy_MC_from_2Ddistribution
    from dps.utils.Unfolding import get_unfold_histogram_tuple
    make_folder_if_not_exists(output_folder)
    output_file_name = get_output_file_name(output_folder, sample, n_toy, centre_of_mass)
    variable_bins = bin_edges_vis.copy()
    with root_open(output_file_name, 'recreate') as f_out:

        input_file_index = 0
        for input_file in input_files:

            input_file_hists = File(input_file)

            for channel in config.analysis_types.keys():
                if channel is 'combined':continue
                for variable in variable_bins:
                    output_dir = f_out.mkdir(str(input_file_index) + '/' + channel + '/' + variable, recurse=True)
                    cd = output_dir.cd
                    mkdir = output_dir.mkdir
                    h_truth, h_measured, h_response, _ = get_unfold_histogram_tuple(input_file_hists,
                                                                            variable,
                                                                            channel,
                                                                            centre_of_mass = centre_of_mass,
                                                                            visiblePS = True,
                                                                            load_fakes=False)

                    cd()

                    mkdir('Original')
                    cd ('Original')
                    h_truth.Write('truth')
                    h_measured.Write('measured')
                    h_response.Write('response')

                    for i in range(1, n_toy+1):
                        toy_id = 'toy_{0}'.format(i)
                        mkdir(toy_id)
                        cd(toy_id)
                        # create histograms
                        # add tuples (truth, measured, response) of histograms
                        truth = generate_toy_MC_from_distribution(h_truth)
                        measured = generate_toy_MC_from_distribution(h_measured)
                        response = generate_toy_MC_from_2Ddistribution(h_response)

                        truth.SetName('truth')
                        measured.SetName('measured')
                        response.SetName('response')

                        truth.Write()
                        measured.Write()
                        response.Write()
            input_file_index += 1
def main():
    '''
        Main function for this script
    '''
    set_root_defaults(msg_ignore_level=3001)

    parser = OptionParser()
    parser.add_option("-o", "--output",
                      dest="output_folder", default='data/pull_data/',
                      help="output folder for pull data files")
    parser.add_option("-n", "--n_input_mc", type=int,
                      dest="n_input_mc", default=100,
                      help="number of toy MC used for the tests")
    parser.add_option("--tau", type='float',
                      dest="tau_value", default=-1.,
                      help="tau-value for SVD unfolding")
    parser.add_option("-m", "--method", type='string',
                      dest="method", default='TUnfold',
                      help="unfolding method")
    parser.add_option("-f", "--file", type='string',
                      dest="file", default='data/toy_mc/unfolding_toy_mc.root',
                      help="file with toy MC")
    parser.add_option("-v", "--variable", dest="variable", default='MET',
                      help="set the variable to analyse (defined in config/variable_binning.py)")
    parser.add_option("--com", "--centre-of-mass-energy", dest="CoM", default=13,
                      help='''set the centre of mass energy for analysis.
                      Default = 8 [TeV]''', type=int)
    parser.add_option("-c", "--channel", type='string',
                      dest="channel", default='combined',
                      help="channel to be analysed: electron|muon|combined")
    parser.add_option("-s", type='string',
                      dest="sample", default='madgraph',
                      help="channel to be analysed: electron|muon|combined")

    (options, _) = parser.parse_args()

    centre_of_mass = options.CoM
    measurement_config = XSectionConfig(centre_of_mass)
    make_folder_if_not_exists(options.output_folder)

    use_n_toy = options.n_input_mc
    method = options.method
    variable = options.variable
    sample = options.sample
    tau_value = options.tau_value

    create_unfolding_pull_data(options.file, method, options.channel,
                               centre_of_mass, variable,
                               sample,
                               measurement_config.unfolding_central,
                               use_n_toy,
                               options.output_folder,
                               tau_value)
def tau_from_scan(unfoldingObject, regularisation_settings):
    variable = regularisation_settings.variable

    # Plots that get outputted by the scan
    lCurve = TGraph()
    scanResult = TSpline3()
    d = "signal"
    a = ""

    # Parameters of scan
    # Number of points to scan, and min/max tau
    nScan = 1000
    minTau = 1.0e-6
    maxTau = 1.0e-0

    if variable == "abs_lepton_eta":
        minTau = 1.0e-8
        maxTau = 1.0e-3
    elif variable == "lepton_pt":
        minTau = 1.0e-6
        maxTau = 1.0e-2
    elif variable == "NJets":
        minTau = 1.0e-6
        maxTau = 1.0e-2

    # Scan is performed here
    iBest = unfoldingObject.ScanTau(nScan, minTau, maxTau, scanResult, TUnfoldDensity.kEScanTauRhoSquareAvg)

    # Plot the scan result
    # Correlation as function of log tau
    canvas = TCanvas()
    scanResult.SetMarkerColor(600)
    scanResult.SetMarkerSize(1)
    scanResult.SetMarkerStyle(5)
    scanResult.Draw("LP")

    # Add point corresponding to optimum tau
    t = Double(0)
    x = Double(0)
    scanResult.GetKnot(iBest, t, x)
    bestTau = Graph(1)
    bestTau.SetPoint(1, t, x)
    bestTau.markercolor = "red"
    bestTau.SetMarkerSize(1.25)
    bestTau.Draw("*")

    # Write to file
    output_dir = regularisation_settings.output_folder
    make_folder_if_not_exists(output_dir)
    canvas.SaveAs(output_dir + "/{0}.png".format(variable))

    return unfoldingObject.GetTau()
def unfold_results(results, category, channel, h_truth, h_measured, h_response, method):
    global variable, path_to_JSON
    h_data = value_error_tuplelist_to_hist(results, bin_edges[variable])
    unfolding = Unfolding(h_truth, h_measured, h_response, method=method)
    
    #turning off the unfolding errors for systematic samples
    if category != 'central':
        unfoldCfg.Hreco = 0
    
    h_unfolded_data = unfolding.unfold(h_data)
    
    #export the D and SV distributions
    SVD_path = path_to_JSON + '/' + variable + '/unfolding_objects/' + channel + '/kv_' + str(unfoldCfg.SVD_k_value) + '/'
    make_folder_if_not_exists(SVD_path)
    if method == 'TSVDUnfold':
        SVDdist = TFile(SVD_path + method + '_SVDdistributions_' + category + '.root', 'recreate')
        directory = SVDdist.mkdir('SVDdist')
        directory.cd()
        unfolding.unfoldObject.GetD().Write()
        unfolding.unfoldObject.GetSV().Write()
        #    unfolding.unfoldObject.GetUnfoldCovMatrix(data_covariance_matrix(h_data), unfoldCfg.SVD_n_toy).Write()
        SVDdist.Close()
    else:
        SVDdist = TFile(SVD_path + method + '_SVDdistributions_Hreco' + str(unfoldCfg.Hreco) + '_' + category + '.root', 'recreate')
        directory = SVDdist.mkdir('SVDdist')
        directory.cd()
        unfolding.unfoldObject.Impl().GetD().Write()
        unfolding.unfoldObject.Impl().GetSV().Write()
        h_truth.Write()
        h_measured.Write()
        h_response.Write()
        #    unfolding.unfoldObject.Impl().GetUnfoldCovMatrix(data_covariance_matrix(h_data), unfoldCfg.SVD_n_toy).Write()
        SVDdist.Close()

    #export the whole unfolding object if it doesn't exist
    if method == 'TSVDUnfold':
        unfolding_object_file_name = SVD_path + method + '_unfoldingObject_' + category + '.root'
    else:
        unfolding_object_file_name = SVD_path + method + '_unfoldingObject_Hreco' + str(unfoldCfg.Hreco) + '_' + category + '.root'
    if not os.path.isfile(unfolding_object_file_name):
        unfoldingObjectFile = TFile(unfolding_object_file_name, 'recreate')
        directory = unfoldingObjectFile.mkdir('unfoldingObject')
        directory.cd()
        if method == 'TSVDUnfold':
            unfolding.unfoldObject.Write()
        else:
            unfolding.unfoldObject.Impl().Write()
        unfoldingObjectFile.Close()
    
    del unfolding
    return hist_to_value_error_tuplelist(h_unfolded_data)
def print_xsections(xsections, channel, toFile = True):
    global savePath, variable, k_value, met_type, b_tag_bin
    printout = '\n'
    printout += '=' * 60
    printout = '\n'
    printout += 'Results for %s variable, %s channel, k-value %s, met type %s, %s b-tag region\n' % (variable, channel, k_value, met_type, b_tag_bin)
    printout += '=' * 60
    printout += '\n'
    rows = {}
    header = 'Measurement'
    scale = 100
    
    bins = variable_bins_ROOT[variable]
    assert(len(bins) == len(xsections['central']))
    
    for bin_i, variable_bin in enumerate(bins):
        header += '& $\sigma_{meas}$ %s bin %s~\GeV' % (variable, variable_bin)
        for source in categories:
            value, error = xsections[source][bin_i]
            relativeError = getRelativeError(value, error)
            text = ' $(%.2f \pm %.2f) \cdot 10^{-2}$ ' % (value * scale, error * scale) + '(%.2f' % (relativeError * 100) + '\%)'
            if rows.has_key(source):
                rows[source].append(text)
            else:
                rows[source] = [translateOptions[source], text]
        
    header += '\\\\ \n'
    printout += header
    printout += '\hline\n'
    for item in rows['central']:
        printout += item + '&'
    printout = printout.rstrip('&')
    printout += '\\\\ \n'

    for source in sorted(rows.keys()):
        if source == 'central':
            continue
        for item in rows[source]:
            printout += item + '&'
        printout = printout.rstrip('&')
        printout += '\\\\ \n'
    printout += '\hline \n\n'
    
    make_folder_if_not_exists(savePath + '/' + variable)
    if toFile:
        output_file = open(savePath + '/' + variable + '/normalised_xsection_result_' + channel + '_' + met_type + '_kv' + str(k_value) + '.tex', 'w')
        output_file.write(printout)
        output_file.close()
    else:
        print printout
def print_output(signal_region_hists, output_folder_to_use, branchName, channel):
	'''Printout on normalisation of different samples to screen and table'''
	print 'Normalisation after selection'
	print 'Single Top :', signal_region_hists['SingleTop'].integral(overflow=True)
	print '-'*60
	mcSum = signal_region_hists['SingleTop'].integral(overflow=True)
	print 'Total DATA :', signal_region_hists['SingleTop'].integral(overflow=True)
	print 'Total MC   :', mcSum
	print '='*60

	output_folder = output_folder_to_use + 'tables/'
	make_folder_if_not_exists(output_folder)

	summary = {}
	summary['SingleTop']    = []
	summary['TotalMC']      = []
	summary['DataToMC']     = []

	# Bin by Bin
	for bin in signal_region_hists['SingleTop'].bins_range():
		ST      = signal_region_hists['SingleTop'].integral(xbin1=bin, xbin2=bin, overflow=True)

		totalMC = ST
		if totalMC > 0:
			dataToMC = ST / totalMC
		else:
			dataToMC = -99
		summary['SingleTop'].append(ST)
		summary['TotalMC'].append(totalMC)
		summary['DataToMC'].append(dataToMC)

	# Total
	ST      = signal_region_hists['SingleTop'].integral(overflow=True)

	totalMC = ST
	if totalMC > 0:
		dataToMC = ST / totalMC
	else:
		dataToMC = -99
	summary['SingleTop'].append(ST)
	summary['TotalMC'].append(totalMC)
	summary['DataToMC'].append(dataToMC)

	order=['SingleTop', 'TotalMC', 'DataToMC']

	d = dict_to_df(summary)
	d = d[order]
	df_to_file(output_folder+channel+'_'+branchName+'.txt', d)
	return
def create_unfolding_pull_data(input_file_name,
                               method,
                               channel,
                               centre_of_mass,
                               variable,
                               sample,
                               responseFile,
                               n_toy_data,
                               output_folder,
                               tau_value,
                               run_matrix=None):
    '''
        Sets up all variables for check_multiple_data_multiple_unfolding
    '''
    set_root_defaults(msg_ignore_level=3001)
    timer = Timer()
    input_file = File(input_file_name, 'read')
    folder_template = '{path}/{centre_of_mass}TeV/{variable}/{sample}/'

    msg_template = 'Producing unfolding pull data for {variable},'
    msg_template += ' tau-value {value}'
    inputs = {
        'path': output_folder,
        'centre_of_mass': centre_of_mass,
        'variable': variable,
        'sample': sample,
        'value': round(tau_value, 4),
    }

    h_response = get_response_histogram(responseFile, variable, channel)
    output_folder = folder_template.format(**inputs)
    make_folder_if_not_exists(output_folder)
    print(msg_template.format(**inputs))
    print('Output folder: {0}'.format(output_folder))
    print('Response here :', h_response)
    output_file_name = check_multiple_data_multiple_unfolding(
        input_file,
        method,
        channel,
        variable,
        h_response,
        n_toy_data,
        output_folder,
        tau_value,
    )
    print('Runtime', timer.elapsed_time())

    return output_file_name
Пример #27
0
def df_to_file(filename, df, index=True):
	'''
	Save a dataframe to an output text file
	Nicely human readable
	'''
	# Make the folder if it doesnt exist
	import os
	from dps.utils.file_utilities import make_folder_if_not_exists
	make_folder_if_not_exists(os.path.dirname(filename))

	with open(filename,'w') as f:
		df.to_string(f, index=index)
		f.write('\n')
		print('DataFrame written to {}'.format(f))
		f.close()
	return
Пример #28
0
def df_to_file(filename, df, index=True):
    '''
	Save a dataframe to an output text file
	Nicely human readable
	'''
    # Make the folder if it doesnt exist
    import os
    from dps.utils.file_utilities import make_folder_if_not_exists
    make_folder_if_not_exists(os.path.dirname(filename))

    with open(filename, 'w') as f:
        df.to_string(f, index=index)
        f.write('\n')
        # print('DataFrame written to {}'.format(f))
        f.close()
    return
def plotting_purity_stability(variable, channel, binning_criteria, bin_edges ):
    '''
    Purity, stability and resolution plots.
    '''
    p = binning_criteria['p_i']
    s = binning_criteria['s_i']

    hist_stability = value_tuplelist_to_hist(s, bin_edges)
    hist_purity = value_tuplelist_to_hist(p, bin_edges)

    hist_purity.color = 'red'
    hist_stability.color = 'blue'

    hist_stability.linewidth = 4
    hist_purity.linewidth = 4

    fig = plt.figure( figsize = ( 20, 16 ), dpi = 200, facecolor = 'white' )
    axes = plt.axes()
    axes.minorticks_on()
    axes.set_xlim( [bin_edges[0], bin_edges[-1]] )
    axes.set_ylim( [0,1] )

    axes.xaxis.labelpad = 12
    axes.yaxis.labelpad = 12

    rplt.hist( hist_stability , stacked=False, axes = axes, label = 'Stability' )
    rplt.hist( hist_purity, stacked=False, axes = axes, label = 'Purity' )

    plt.tick_params( **CMS.axis_label_major )
    plt.tick_params( **CMS.axis_label_minor )

    x_title = '$' + variables_latex[variable] + '$'
    if variable in ['HT', 'ST', 'MET', 'lepton_pt', 'WPT']: x_title += '[GeV]'
    plt.xlabel( x_title, CMS.x_axis_title )

    leg = plt.legend(loc=4,prop={'size':40})

    plt.tight_layout()

    plot_filepath = 'plots/binning/purity_stability/'
    make_folder_if_not_exists(plot_filepath)
    plot_filename = channel + '_' + variable+'_purityStability.pdf'
    fig.savefig(plot_filepath+plot_filename, bbox_inches='tight')
Пример #30
0
def plotting_purity_stability(variable, channel, binning_criteria, bin_edges):
    '''
    Purity, stability and resolution plots.
    '''
    p = binning_criteria['p_i']
    s = binning_criteria['s_i']

    hist_stability = value_tuplelist_to_hist(s, bin_edges)
    hist_purity = value_tuplelist_to_hist(p, bin_edges)

    hist_purity.color = 'red'
    hist_stability.color = 'blue'

    hist_stability.linewidth = 4
    hist_purity.linewidth = 4

    fig = plt.figure(figsize=(20, 16), dpi=200, facecolor='white')
    axes = plt.axes()
    axes.minorticks_on()
    axes.set_xlim([bin_edges[0], bin_edges[-1]])
    axes.set_ylim([0, 1])

    axes.xaxis.labelpad = 12
    axes.yaxis.labelpad = 12

    rplt.hist(hist_stability, stacked=False, axes=axes, label='Stability')
    rplt.hist(hist_purity, stacked=False, axes=axes, label='Purity')

    plt.tick_params(**CMS.axis_label_major)
    plt.tick_params(**CMS.axis_label_minor)

    x_title = '$' + variables_latex[variable] + '$'
    if variable in ['HT', 'ST', 'MET', 'lepton_pt', 'WPT']: x_title += '[GeV]'
    plt.xlabel(x_title, CMS.x_axis_title)

    leg = plt.legend(loc=4, prop={'size': 40})

    plt.tight_layout()

    plot_filepath = 'plots/binning/purity_stability/'
    make_folder_if_not_exists(plot_filepath)
    plot_filename = channel + '_' + variable + '_purityStability.pdf'
    fig.savefig(plot_filepath + plot_filename, bbox_inches='tight')
def create_unfolding_pull_data(input_file_name, method, channel,
                               centre_of_mass, variable,
                               sample, 
                               responseFile,
                               n_toy_data,
                               output_folder, 
                               tau_value,
                                run_matrix=None):
    '''
        Sets up all variables for check_multiple_data_multiple_unfolding
    '''
    set_root_defaults(msg_ignore_level=3001)
    timer = Timer()
    input_file = File(input_file_name, 'read')
    folder_template = '{path}/{centre_of_mass}TeV/{variable}/{sample}/'

    msg_template = 'Producing unfolding pull data for {variable},'
    msg_template += ' tau-value {value}'
    inputs = {
        'path': output_folder,
        'centre_of_mass': centre_of_mass,
        'variable': variable,
        'sample': sample,
        'value': round(tau_value,4),
    }

    h_response = get_response_histogram(responseFile, variable, channel)
    output_folder = folder_template.format(**inputs)
    make_folder_if_not_exists(output_folder)
    print(msg_template.format(**inputs))
    print('Output folder: {0}'.format(output_folder))
    print ('Response here :',h_response)
    output_file_name = check_multiple_data_multiple_unfolding(
                                input_file, method, channel, variable, 
                                h_response,
                                n_toy_data,
                                output_folder, 
                                tau_value,
                            )
    print('Runtime', timer.elapsed_time())

    return output_file_name
Пример #32
0
def plot_data_vs_refold(args, regularisation_settings, tau):
    '''
    Plot the differences between the unfolded and refolded distributions

    TODO Include also with best tau - redo unfolding with best tau then come here
    '''
    tau = str(tau).replace('.', 'p')
    # data =  hist_to_value_error_tuplelist(regularisation_settings.h_data)
    # measured = hist_to_value_error_tuplelist(regularisation_settings.h_measured)
    variable = regularisation_settings.variable
    channel = regularisation_settings.channel
    plot_outpath = regularisation_settings.outpath.replace('tables/', 'plots/')+variable+'/'
    make_folder_if_not_exists(plot_outpath)
    outfile = plot_outpath+channel+'_unfold_refold_test_tau_'+tau+'.pdf'
    if args.run_measured_as_data:
        outfile = plot_outpath+channel+'_run_measured_as_data_tau_'+tau+'.pdf'

    c = TCanvas('c1','c1',600,400)
    c.SetFillColor(2);
    p1 = TPad("pad1", "p1",0.0,0.2,1.0,1.0,21)
    p2 = TPad("pad2", "p2",0.0,0.0,1.0,0.2,22)
    p1.SetFillColor(0);
    p2.SetFillColor(0);
    p1.Draw()
    p2.Draw()
    p1.cd()
    regularisation_settings.h_refolded.SetMarkerStyle(10);
    regularisation_settings.h_refolded.SetMarkerColor(4);
    # regularisation_settings.h_refolded.SetMarkerSize(10);
    regularisation_settings.h_refolded.Draw()
    regularisation_settings.h_data.SetFillColor(3);
    regularisation_settings.h_data.Draw("hist same");

    p2.cd()
    h_ratio = regularisation_settings.h_data.Clone()
    h_ratio.Divide(regularisation_settings.h_refolded)
    h_ratio.SetMarkerSize(0.1);
    h_ratio.Draw()
    c.SaveAs(outfile)
    c.Delete()
    return
Пример #33
0
def makeLatexTable(chi2, gChi2, outputPath, channel, crossSectionType):
    '''
	Make the chi2 latex table
	'''
    models = chi2[chi2.keys()[0]]['Model']
    latexHeader = '\\begin{table}\n'
    if crossSectionType == 'normalised':
        latexHeader += '\t\caption{Results of a $\chi^{2}$ test between the normalised cross sections in data and several MC models.}\n'
        latexHeader += '\t\label{tb:Chi2_normalised}\n'
    elif crossSectionType == 'absolute':
        latexHeader += '\t\caption{Results of a $\chi^{2}$ test between the absolute cross sections in data and several MC models.}\n'
        latexHeader += '\t\label{tb:Chi2_absolute}\n'
    latexHeader += '\t\centering\n'
    latexHeader += '\t\\scriptsize\n'

    latexContent = ''
    latexContent += makeTableContent(chi2,
                                     gChi2,
                                     models=[
                                         "TTJets_powhegPythia8",
                                         "TTJets_powhegPythia8_withMCTheoryUnc"
                                     ],
                                     spacing=True)
    latexContent += makeTableContent(chi2,
                                     gChi2,
                                     models=[
                                         "TTJets_powhegHerwig",
                                         "TTJets_amcatnloPythia8",
                                         "TTJets_madgraphMLM"
                                     ])

    latexFooter = '\\end{table}\n'
    latexTable = latexHeader + latexContent + latexFooter

    print latexTable
    make_folder_if_not_exists(outputPath)
    file_template = outputPath + '/chi2_{channel}.tex'.format(channel=channel)
    output_file = open(file_template, 'w')
    output_file.write(latexTable)
    output_file.close()
Пример #34
0
def plotting_resolution(variable, channel, residual, resolution, bin_number,
                        bin_low, bin_high):
    '''
    Resolution plots.
    '''
    bin_width = bin_high - bin_low

    unit = ''
    if variable in ['HT', 'ST', 'MET', 'lepton_pt', 'WPT']: unit += '[GeV]'

    title = "channel = {}, variable = ${}${}, {}-{}".format(
        channel, variables_latex[variable], unit, bin_low, bin_high)

    fig = plt.figure()
    axes = plt.axes()
    rplt.hist(residual, axes=axes, label='Residuals')
    plt.axvline(x=resolution, linewidth=1, color='r', label='Resolution')
    plt.axvline(x=bin_width / 2, linewidth=1, color='blue', label='Bin Width')

    axes.set_ylim(ymin=0)
    axes.set_xlabel('Residual')
    axes.set_ylabel('N')
    fig.suptitle('Residual Distribution', fontsize=14, fontweight='bold')
    plt.title(title, loc='right')

    leg = plt.legend(loc='best')
    leg.draw_frame(False)

    plt.tight_layout()

    plot_filepath = 'plots/binning/residuals/'
    make_folder_if_not_exists(plot_filepath)
    plot_filename = '{}_{}_{}_Residual.pdf'.format(channel, variable,
                                                   str(bin_number))
    fig.savefig(plot_filepath + plot_filename, bbox_inches='tight')
    fig.clf()
    plt.close()
    gc.collect()
    return
def compare_vjets_btag_regions( variable = 'MET', met_type = 'patType1CorrectedPFMet',
                                title = 'Untitled', channel = 'electron' ):
    ''' Compares the V+Jets template in different b-tag bins'''
    global fit_variable_properties, b_tag_bin, save_as, b_tag_bin_ctl
    b_tag_bin_ctl = '0orMoreBtag'
    variable_bins = variable_bins_ROOT[variable]
    histogram_template = get_histogram_template( variable )
    
    for fit_variable in electron_fit_variables:
        if '_bl' in fit_variable:
                b_tag_bin_ctl = '1orMoreBtag'
        else:
            b_tag_bin_ctl = '0orMoreBtag'
        save_path = 'plots/%dTeV/fit_variables/%s/%s/' % ( measurement_config.centre_of_mass_energy, variable, fit_variable )
        make_folder_if_not_exists( save_path + '/vjets/' )
        histogram_properties = Histogram_properties()
        histogram_properties.x_axis_title = fit_variable_properties[fit_variable]['x-title']
        histogram_properties.y_axis_title = fit_variable_properties[fit_variable]['y-title']
        histogram_properties.y_axis_title = histogram_properties.y_axis_title.replace( 'Events', 'a.u.' )
        histogram_properties.x_limits = [fit_variable_properties[fit_variable]['min'], fit_variable_properties[fit_variable]['max']]
        histogram_properties.title = title
        histogram_properties.additional_text = channel_latex[channel] + ', ' + b_tag_bins_latex[b_tag_bin_ctl]
        histogram_properties.y_max_scale = 1.5
        for bin_range in variable_bins:
            params = {'met_type': met_type, 'bin_range':bin_range, 'fit_variable':fit_variable, 'b_tag_bin':b_tag_bin, 'variable':variable}
            fit_variable_distribution = histogram_template % params
            fit_variable_distribution_ctl = fit_variable_distribution.replace( b_tag_bin, b_tag_bin_ctl )
            # format: histograms['data'][qcd_fit_variable_distribution]
            histograms = get_histograms_from_files( [fit_variable_distribution, fit_variable_distribution_ctl], {'V+Jets' : histogram_files['V+Jets']} )
            prepare_histograms( histograms, rebin = fit_variable_properties[fit_variable]['rebin'], scale_factor = measurement_config.luminosity_scale )
            histogram_properties.name = variable + '_' + bin_range + '_' + fit_variable + '_' + b_tag_bin_ctl + '_VJets_template_comparison'
            histograms['V+Jets'][fit_variable_distribution].Scale( 1 / histograms['V+Jets'][fit_variable_distribution].Integral() )
            histograms['V+Jets'][fit_variable_distribution_ctl].Scale( 1 / histograms['V+Jets'][fit_variable_distribution_ctl].Integral() )
            compare_measurements( models = {'no b-tag' : histograms['V+Jets'][fit_variable_distribution_ctl]},
                             measurements = {'$>=$ 2 b-tags': histograms['V+Jets'][fit_variable_distribution]},
                             show_measurement_errors = True,
                             histogram_properties = histogram_properties,
                             save_folder = save_path + '/vjets/',
                             save_as = save_as )
def plot_fit_results( histograms, category, channel ):
    global variable, b_tag_bin, output_folder, phase_space
    from dps.utils.plotting import Histogram_properties, make_data_mc_comparison_plot
    fit_variables = histograms.keys()

    variableBins = None
    if phase_space == 'VisiblePS':
        variableBins = variable_bins_visiblePS_ROOT
    elif phase_space == 'FullPS':
        variableBins = variable_bins_ROOT

    for variable_bin in variableBins[variable]:
        path = output_folder + str( measurement_config.centre_of_mass_energy ) + 'TeV/' + variable + '/' + category + '/fit_results/'
        make_folder_if_not_exists( path )
        for fit_variable in fit_variables:
            plotname = channel + '_' + fit_variable + '_bin_' + variable_bin
            # check if template plots exist already
            for output_format in output_formats:
                if os.path.isfile( plotname + '.' + output_format ):
                    continue

            # plot with matplotlib
            h_data = histograms[fit_variable][variable_bin]['data']
            h_signal = histograms[fit_variable][variable_bin]['signal']
            h_background = histograms[fit_variable][variable_bin]['background']

            histogram_properties = Histogram_properties()
            histogram_properties.name = plotname
            histogram_properties.x_axis_title = fit_variables_latex[fit_variable]
            histogram_properties.y_axis_title = 'Events/(%s)' % get_unit_string(fit_variable)
            label, _ = get_cms_labels( channel )
            histogram_properties.title = label
            histogram_properties.x_limits = measurement_config.fit_boundaries[fit_variable]

            make_data_mc_comparison_plot( [h_data, h_background, h_signal],
                                         ['data', 'background', 'signal'],
                                         ['black', 'green', 'red'], histogram_properties,
                                         save_folder = path, save_as = output_formats )
Пример #37
0
def chi2_to_plots(args,df_chi2, regularisation_settings, chi2_cut, channel):
    '''
    Plot chi2 figures
    '''
    plot_outpath = regularisation_settings.outpath.replace('tables/', 'plots/') + 'tauscan/'
    make_folder_if_not_exists(plot_outpath)

    fig1 = plt.figure()
    ax1 = fig1.add_subplot(1, 1, 1)
    ax1.set_xlim([pow(10,-6), 1])
    ax1.set_ylim([pow(10,-6), 1])
    for var in df_chi2.columns:
        if var == 'tau': continue

        # Plot tau distributions for each variable
        plt.loglog(
            df_chi2['tau'],
            df_chi2[var],
            label = variables_latex[var],
        )
    # Plot current chi2 cutoff value
    plt.axhline(y=chi2_cut, color='black', linestyle='dashed')

    # Plot legend
    handles, labels = ax1.get_legend_handles_labels()
    ax1.legend(handles, labels, loc=4)

    # Plot axis titles
    ax1.set_xlabel('Regularisation Parameter \ensuremath{\\tau}')
    ax1.set_ylabel('\ensuremath{1-P(\\chi^{2}|NDF)}')

    # Save plot
    pltName = os.path.join(plot_outpath,'{channel}_all_tauscan.pdf'.format(channel = channel))
    if args.unfolded_binning:
        pltName = pltName.replace('.pdf', '_unf_binning.pdf')
    fig1.savefig(pltName) 
    print "Written plots to {plot_outpath}{pltName}".format(plot_outpath = plot_outpath, pltName = pltName)
    return
Пример #38
0
    def save(self, phase_space):
        '''
        Saves the normalisation output into a JSON.
        I would like to change this to a pandas Dataframe at somepoint after 
        a few issues have been worked out
        '''
        from dps.utils.pandas_utilities import write_tuple_to_df
        from dps.utils.file_utilities import make_folder_if_not_exists
        # If normalisation hasnt been calculated  - then go calculate it!
        if not self.is_normalised: self.calculate_normalisation()

        output_folder = self.output_folder.format(
            com=self.com,
            var=self.variable,
            ps=phase_space,
            cat=self.name,
        )
        make_folder_if_not_exists(output_folder)

        file_template = '{type}_{channel}.txt'
        f = file_template.format(type='normalisation', channel=self.channel)

        write_tuple_to_df(self.normalisation, output_folder + f)
        return
def plotting_resolution(variable, channel, residual, resolution, bin_number, bin_low, bin_high ):
    '''
    Resolution plots.
    '''
    bin_width = bin_high - bin_low
    
    unit = ''
    if variable in ['HT', 'ST', 'MET', 'lepton_pt', 'WPT']: unit += '[GeV]'

    title = "channel = {}, variable = ${}${}, {}-{}".format(channel, variables_latex[variable], unit, bin_low, bin_high)

    fig = plt.figure()
    axes = plt.axes()
    rplt.hist(residual, axes = axes, label = 'Residuals')
    plt.axvline(x=resolution, linewidth=1, color='r', label = 'Resolution')
    plt.axvline(x=bin_width/2, linewidth=1, color='blue', label = 'Bin Width')

    axes.set_ylim(ymin = 0)
    axes.set_xlabel('Residual')
    axes.set_ylabel('N')
    fig.suptitle('Residual Distribution', fontsize=14, fontweight='bold')
    plt.title(title, loc='right')

    leg = plt.legend(loc='best')
    leg.draw_frame(False)   

    plt.tight_layout()

    plot_filepath = 'plots/binning/residuals/'
    make_folder_if_not_exists(plot_filepath)
    plot_filename = '{}_{}_{}_Residual.pdf'.format(channel, variable, str(bin_number))
    fig.savefig(plot_filepath+plot_filename, bbox_inches='tight')
    fig.clf()
    plt.close()
    gc.collect()
    return
def main():
    global measurement_config, histogram_files
    global electron_fit_variables, muon_fit_variables, fit_variable_properties
    global b_tag_bin, category, histogram_files, variables
    global b_tag_bin_ctl
    
    title_template = '$%.1f$ fb$^{-1}$(%d TeV)'
    e_title = title_template % ( measurement_config.new_luminosity / 1000., measurement_config.centre_of_mass_energy )
    met_type = 'patType1CorrectedPFMet'
    for variable in variables:
        variable_bins = variable_bins_ROOT[variable]
        histogram_template = get_histogram_template( variable )
        
        for fit_variable in electron_fit_variables:
            if '_bl' in fit_variable:
                b_tag_bin_ctl = '1orMoreBtag'
            else:
                b_tag_bin_ctl = '0orMoreBtag'
            save_path = 'plots/%dTeV/fit_variables/%s/%s/' % ( measurement_config.centre_of_mass_energy, variable, fit_variable )
            make_folder_if_not_exists( save_path )
            make_folder_if_not_exists( save_path + 'qcd/' )
            make_folder_if_not_exists( save_path + 'vjets/' )
            inclusive_histograms = {}
            inclusive_fit_distribution = ''
            inclusive_qcd_distribution = ''
            for bin_range in variable_bins:
                params = {'met_type': met_type, 'bin_range':bin_range, 'fit_variable':fit_variable, 'b_tag_bin':b_tag_bin, 'variable':variable}
                fit_variable_distribution = histogram_template % params
                qcd_fit_variable_distribution = fit_variable_distribution.replace( 'Ref selection', 'QCDConversions' )
                qcd_fit_variable_distribution = qcd_fit_variable_distribution.replace( b_tag_bin, b_tag_bin_ctl )
                histograms = get_histograms_from_files( [fit_variable_distribution, qcd_fit_variable_distribution], histogram_files )
                plot_fit_variable( histograms, fit_variable, variable, bin_range, fit_variable_distribution, qcd_fit_variable_distribution, e_title, save_path )
                # sum histograms for inclusive plots
                for sample, hist in histograms.iteritems():
                    inclusive_fit_distribution = fit_variable_distribution.replace( bin_range, "inclusive" )
                    inclusive_qcd_distribution = qcd_fit_variable_distribution.replace( bin_range, "inclusive" )
                    if not inclusive_histograms.has_key( sample ):
                        inclusive_histograms[sample] = {}
                        inclusive_histograms[sample][inclusive_fit_distribution] = hist[fit_variable_distribution].clone()
                        inclusive_histograms[sample][inclusive_qcd_distribution] = hist[qcd_fit_variable_distribution].clone() 
                    else:
                        inclusive_histograms[sample][inclusive_fit_distribution] += hist[fit_variable_distribution]   
                        inclusive_histograms[sample][inclusive_qcd_distribution] += hist[qcd_fit_variable_distribution]
                        
            plot_fit_variable( inclusive_histograms, fit_variable, variable,
                               'inclusive', inclusive_fit_distribution,
                               inclusive_qcd_distribution, e_title, save_path )
            
        compare_qcd_control_regions( variable, met_type, e_title )
        compare_vjets_btag_regions( variable, met_type, e_title )
        compare_vjets_templates( variable, met_type, e_title )
Пример #41
0
def plot_probability_matrix(p_matrix, variable, channel):
    '''
    Plot the probability matrix
    '''
    from dps.config.variable_binning import bin_edges_vis
    from dps.config.latex_labels import variables_latex
    from dps.config import CMS
    from dps.utils.file_utilities import make_folder_if_not_exists
    from root_numpy import hist2array

    import matplotlib as mpl
    mpl.use( 'agg' )

    import matplotlib.pyplot as plt
    import matplotlib.cm as cm
    # my_cmap = cm.get_cmap( 'jet' )
    my_cmap = cm.get_cmap( 'viridis' )
    import gc

    from matplotlib import rc
    rc( 'font', **CMS.font )
    rc( 'text', usetex = True )

    # hist to numpy array
    values = hist2array(p_matrix)
    edges = bin_edges_vis[variable]
    bin_centres = [np.mean([edges[j],edges[j+1]]) for j in range(0, len(edges)-1)]
    n_gen_bins  = len(values)

    # Get underflow and strip underflow/overflow bins
    underflow = p_matrix.underflow(axis=1)[1:-1]

    # # Fix array such that underflow is included
    # i=0
    # for u, row in zip(underflow, values):
    #     newrow = row[:-1]
    #     newrow = np.insert(newrow, 0, u)
    #     values[i] = newrow
    #     i+=1

    # Cant easily rebin any more so done manually
    rebinned_values = np.zeros((n_gen_bins,n_gen_bins))
    i=0
    for row in values:
        newrow = [ row[j]+row[j+1] for j in range(0, len(row), 2)]
        rebinned_values[i] = newrow
        i+=1

    X, Y = np.meshgrid(bin_centres, bin_centres)
    x = X.ravel()
    y = Y.ravel()
    z = rebinned_values.ravel()

    v_unit = '$'+variables_latex[variable]+'$'
    if variable in ['HT', 'ST', 'MET', 'lepton_pt', 'WPT']: 
        v_unit += ' [GeV]'
    x_title = 'Reconstructed ' + v_unit
    y_title = 'Generated ' + v_unit
    # title = "channel = {}, variable = ${}$".format(channel, variables_latex[variable])
    title = "Response Probability Matrix"
    fig = plt.figure( figsize = CMS.figsize, dpi = CMS.dpi, facecolor = CMS.facecolor )
    ax0 = fig.add_subplot(1,1,1)
    ax0.set_aspect('equal')

    plt.tick_params( **CMS.axis_label_major )
    plt.tick_params( **CMS.axis_label_minor )
    ax0.xaxis.labelpad = 12
    ax0.yaxis.labelpad = 12

    h2d = plt.hist2d(x, y, weights=z, bins=(edges, edges), cmap=my_cmap)
    colorbar = plt.colorbar(h2d[3], fraction=0.046, pad=0.04)
    colorbar.ax.tick_params( **CMS.axis_label_major )

    plt.xlabel( x_title, CMS.x_axis_title )
    plt.ylabel( y_title, CMS.y_axis_title )
    plt.title( title, CMS.title )
    plt.tight_layout()

    # Output folder of covariance matrices
    covariance_matrix_output_path = 'plots/binning/probability_matrices/'
    make_folder_if_not_exists(covariance_matrix_output_path)
    plt.savefig(covariance_matrix_output_path+variable+'_'+channel+'.pdf')
    fig.clf()
    plt.close()
    gc.collect()
	sys.exit()

#set up the config according to the centre of mass energy
config = XSectionConfig(options.centreOfMassEnergy)

#Get the luminosity for the centre of mass energy
luminosity = config.luminosities[options.centreOfMassEnergy]

#Get current working directory
current_working_directory = os.getcwd()

#Get folder to move files to
path_to_AN_folder = config.path_to_files

#move log files separately first, since there is no "logs" category in categories_and_prefixes
make_folder_if_not_exists(path_to_AN_folder + '/logs/')
command = 'mv ' + options.pathToBATOutputFiles + '/*' + str(options.centreOfMassEnergy) + 'TeV*.log ' + path_to_AN_folder + '/logs/'
if options.doNothing:
	print "command = ", command
	print "path to folder = ", path_to_AN_folder + '/logs/'
elif not options.doNothing:
	make_folder_if_not_exists( path_to_AN_folder + "/logs" )

	p = subprocess.Popen(command, shell=True)
	p.wait()

#Now move all other BAT output files.

for category in config.categories_and_prefixes.keys():
	make_folder_if_not_exists(path_to_AN_folder + "/" + category)
	command = 'mv ' + options.pathToBATOutputFiles + '/*' + str(luminosity) + 'pb*' + config.categories_and_prefixes[category] + '.root ' + path_to_AN_folder + "/" + category
Пример #43
0
 def toJSON(self, JSON_file):
     output = self.toDict()
     filename = JSON_file.split('/')[-1]
     directory = JSON_file.replace(filename, '')
     make_folder_if_not_exists(directory)
     write_data_to_JSON(output, JSON_file)
    parser.add_option( "-l", "--log-plots", dest = "log_plots", action = "store_true",
                      help = "plots the y axis in log scale" )

    ( options, args ) = parser.parse_args()
    measurement_config = XSectionConfig( options.CoM)
    
    centre_of_mass = measurement_config.centre_of_mass_energy
    luminosity = measurement_config.luminosity * measurement_config.luminosity_scale
    ttbar_xsection = measurement_config.ttbar_xsection
    load_fakes = options.load_fakes
    method = options.unfolding_method
    path_to_JSON = options.data_path
    plot_location = options.output_folder + '/' + str(centre_of_mass) + 'TeV/' + options.test + '/'
    met_type = measurement_config.translate_options[options.metType]
    log_plots = options.log_plots
    make_folder_if_not_exists( plot_location )

    test = options.test

    input_filename_central = measurement_config.unfolding_madgraph
    input_filename_bias = measurement_config.unfolding_mcatnlo

    variables = ['MET', 'WPT', 'MT', 'ST', 'HT']

    input_file = File( input_filename_central, 'read' )
    input_file_bias = File( input_filename_bias, 'read' )

    print 'Performing', test, 'unfolding checks at', centre_of_mass, 'TeV'
    
    for channel in ['electron', 'muon']:
        for variable in variables:
def main():
    
    parser = OptionParser()
    parser.add_option('--topPtReweighting', dest='applyTopPtReweighting', type='int', default=0 )
    parser.add_option('--topEtaReweighting', dest='applyTopEtaReweighting', type='int', default=0 )
    parser.add_option('-c', '--centreOfMassEnergy', dest='centreOfMassEnergy', type='int', default=13 )
    parser.add_option('--pdfWeight', type='int', dest='pdfWeight', default=-1 )
    parser.add_option('--muFmuRWeight', type='int', dest='muFmuRWeight', default=-1 )
    parser.add_option('--alphaSWeight', type='int', dest='alphaSWeight', default=-1 )
    parser.add_option('--nGeneratorWeights', type='int', dest='nGeneratorWeights', default=1 )
    parser.add_option('-s', '--sample', dest='sample', default='central')
    parser.add_option('-d', '--debug', action='store_true', dest='debug', default=False)
    parser.add_option('-n', action='store_true', dest='donothing', default=False)
    parser.add_option('-e', action='store_true', dest='extraHists', default=False)
    parser.add_option('-f',action='store_true', dest='fineBinned', default=False)

    (options, _) = parser.parse_args()

    measurement_config = XSectionConfig( options.centreOfMassEnergy )

    # Input file name
    file_name = 'crap.root'
    if int(options.centreOfMassEnergy) == 13:
        # file_name = fileNames['13TeV'][options.sample]
        file_name = getFileName('13TeV', options.sample, measurement_config)
        # if options.generatorWeight >= 0:
        #     file_name = 'localInputFile.root'
    else:
        print "Error: Unrecognised centre of mass energy."

    pdfWeight = options.pdfWeight
    muFmuRWeight = options.muFmuRWeight
    alphaSWeight = options.alphaSWeight

    # Output file name
    outputFileName = 'crap.root'
    outputFileDir = 'unfolding/%sTeV/' % options.centreOfMassEnergy
    make_folder_if_not_exists(outputFileDir)
   
    energySuffix = '%sTeV' % ( options.centreOfMassEnergy )

    if options.applyTopEtaReweighting != 0:
        if options.applyTopEtaReweighting == 1:
            outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_withTopEtaReweighting_up.root' % energySuffix
        elif options.applyTopEtaReweighting == -1:
            outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_withTopEtaReweighting_down.root' % energySuffix
    elif options.applyTopPtReweighting != 0:
        if options.applyTopPtReweighting == 1:
            outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_withTopPtReweighting_up.root' % energySuffix
        elif options.applyTopPtReweighting == -1:
            outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_withTopPtReweighting_down.root' % energySuffix            
    elif alphaSWeight == 0:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_alphaSDown.root' % ( energySuffix )
    elif alphaSWeight == 1:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_alphaSUp.root' % ( energySuffix )
    elif muFmuRWeight == 1:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_1muR2muF.root' % ( energySuffix )
    elif muFmuRWeight == 2:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_1muR05muF.root' % ( energySuffix )
    elif muFmuRWeight == 3:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_2muR1muF.root' % ( energySuffix )
    elif muFmuRWeight == 4:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_2muR2muF.root' % ( energySuffix )
    elif muFmuRWeight == 6:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_05muR1muF.root' % ( energySuffix )
    elif muFmuRWeight == 8:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_05muR05muF.root' % ( energySuffix )
    elif pdfWeight >= 0 and pdfWeight <= 99:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric_pdfWeight_%i.root' % ( energySuffix, pdfWeight )
    elif options.sample != 'central':
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_%s_asymmetric.root' % ( energySuffix, options.sample  )
    elif options.fineBinned :
        outputFileName = outputFileDir+'/unfolding_TTJets_%s.root' % ( energySuffix  )
    else:
        outputFileName = outputFileDir+'/unfolding_TTJets_%s_asymmetric.root' % energySuffix

    with root_open( file_name, 'read' ) as f, root_open( outputFileName, 'recreate') as out:
        
            # Get the tree
            treeName = "TTbar_plus_X_analysis/Unfolding/Unfolding"
            if options.sample == "jesup":
                treeName += "_JESUp"
            elif options.sample == "jesdown":
                treeName += "_JESDown"
            elif options.sample == "jerup":
                treeName += "_JERUp"
            elif options.sample == "jerdown":
                treeName += "_JERDown"

            tree = f.Get(treeName)
            nEntries = tree.GetEntries()
            # weightTree = f.Get('TTbar_plus_X_analysis/Unfolding/GeneratorSystematicWeights')
            # if meWeight >= 0 :
            #     tree.AddFriend('TTbar_plus_X_analysis/Unfolding/GeneratorSystematicWeights')
            #     tree.SetBranchStatus('genWeight_*',1)
            #     tree.SetBranchStatus('genWeight_%i' % meWeight, 1)

            # For variables where you want bins to be symmetric about 0, use abs(variable) (but also make plots for signed variable)
            allVariablesBins = bin_edges_vis.copy()
            for variable in bin_edges_vis:

                if 'Rap' in variable:
                    allVariablesBins['abs_%s' % variable] = [0,bin_edges_vis[variable][-1]]


            recoVariableNames = {}
            genVariable_particle_names = {}
            genVariable_parton_names = {}
            histograms = {}
            outputDirs = {}

            for variable in allVariablesBins:
                if options.debug and variable != 'HT' : continue

                if options.sample in measurement_config.met_systematics and variable not in ['MET', 'ST', 'WPT']:
                    continue

                outputDirs[variable] = {}
                histograms[variable] = {}

                #
                # Variable names
                #
                recoVariableName = branchNames[variable]
                sysIndex = None
                if variable in ['MET', 'ST', 'WPT']:
                    if options.sample == "jesup":
                        recoVariableName += '_METUncertainties'
                        sysIndex = 2
                    elif options.sample == "jesdown":
                        recoVariableName += '_METUncertainties'
                        sysIndex = 3
                    elif options.sample == "jerup":
                        recoVariableName += '_METUncertainties'
                        sysIndex = 0
                    elif options.sample == "jerdown":
                        recoVariableName+= '_METUncertainties'
                        sysIndex = 1
                    elif options.sample in measurement_config.met_systematics:
                        recoVariableName += '_METUncertainties'
                        sysIndex = measurement_config.met_systematics[options.sample]

                genVariable_particle_name = None
                genVariable_parton_name = None
                if variable in genBranchNames_particle:
                    genVariable_particle_name = genBranchNames_particle[variable]
                if variable in genBranchNames_parton:
                    genVariable_parton_name = genBranchNames_parton[variable]

                recoVariableNames[variable] = recoVariableName
                genVariable_particle_names[variable] = genVariable_particle_name
                genVariable_parton_names[variable] = genVariable_parton_name 

                for channel in channels:
                    # Make dir in output file
                    outputDirName = variable+'_'+channel.outputDirName
                    outputDir = out.mkdir(outputDirName)
                    outputDirs[variable][channel.channelName] = outputDir

                    #
                    # Book histograms
                    #
                    # 1D histograms
                    histograms[variable][channel.channelName] = {}
                    h = histograms[variable][channel.channelName]
                    h['truth'] = Hist( allVariablesBins[variable], name='truth')
                    h['truthVis'] = Hist( allVariablesBins[variable], name='truthVis')
                    h['truth_parton'] = Hist( allVariablesBins[variable], name='truth_parton')                
                    h['measured'] = Hist( reco_bin_edges_vis[variable], name='measured')
                    h['measuredVis'] = Hist( reco_bin_edges_vis[variable], name='measuredVis')
                    h['measured_without_fakes'] = Hist( reco_bin_edges_vis[variable], name='measured_without_fakes')
                    h['measuredVis_without_fakes'] = Hist( reco_bin_edges_vis[variable], name='measuredVis_without_fakes')
                    h['fake'] = Hist( reco_bin_edges_vis[variable], name='fake')
                    h['fakeVis'] = Hist( reco_bin_edges_vis[variable], name='fakeVis')
                    # 2D histograms
                    h['response'] = Hist2D( reco_bin_edges_vis[variable], allVariablesBins[variable], name='response')
                    h['response_without_fakes'] = Hist2D( reco_bin_edges_vis[variable], allVariablesBins[variable], name='response_without_fakes')
                    h['responseVis_without_fakes'] = Hist2D( reco_bin_edges_vis[variable], allVariablesBins[variable], name='responseVis_without_fakes')
                    h['response_parton'] = Hist2D( reco_bin_edges_vis[variable], allVariablesBins[variable], name='response_parton')
                    h['response_without_fakes_parton'] = Hist2D( reco_bin_edges_vis[variable], allVariablesBins[variable], name='response_without_fakes_parton')

                    if options.fineBinned:
                        minVar = trunc( allVariablesBins[variable][0] )
                        maxVar = trunc( max( tree.GetMaximum(genVariable_particle_names[variable]), tree.GetMaximum( recoVariableNames[variable] ) ) * 1.2 )
                        nBins = int(maxVar - minVar)
                        if variable is 'lepton_eta' or variable is 'bjets_eta':
                            maxVar = 2.5
                            minVar = -2.5
                            nBins = 1000
                        elif 'abs' in variable and 'eta' in variable:
                            maxVar = 3.0
                            minVar = 0.
                            nBins = 1000
                        elif 'Rap' in variable:
                            maxVar = 3.0
                            minVar = -3.0
                            nBins = 1000
                        elif 'NJets' in variable:
                            maxVar = 20.5
                            minVar = 3.5
                            nBins = 17

                        h['truth'] = Hist( nBins, minVar, maxVar, name='truth')
                        h['truthVis'] = Hist( nBins, minVar, maxVar, name='truthVis')
                        h['truth_parton'] = Hist( nBins, minVar, maxVar, name='truth_parton')
                        h['measured'] = Hist( nBins, minVar, maxVar, name='measured')
                        h['measuredVis'] = Hist( nBins, minVar, maxVar, name='measuredVis')
                        h['measured_without_fakes'] = Hist( nBins, minVar, maxVar, name='measured_without_fakes')
                        h['measuredVis_without_fakes'] = Hist( nBins, minVar, maxVar, name='measuredVis_without_fakes')
                        h['fake'] = Hist( nBins, minVar, maxVar, name='fake')
                        h['fakeVis'] = Hist( nBins, minVar, maxVar, name='fakeVis')
                        h['response'] = Hist2D( nBins, minVar, maxVar, nBins, minVar, maxVar, name='response')
                        h['response_without_fakes'] = Hist2D( nBins, minVar, maxVar, nBins, minVar, maxVar, name='response_without_fakes')
                        h['responseVis_without_fakes'] = Hist2D( nBins, minVar, maxVar, nBins, minVar, maxVar, name='responseVis_without_fakes')

                        h['response_parton'] = Hist2D( nBins, minVar, maxVar, nBins, minVar, maxVar, name='response_parton')
                        h['response_without_fakes_parton'] = Hist2D( nBins, minVar, maxVar, nBins, minVar, maxVar, name='response_without_fakes_parton')

                    # Some interesting histograms
                    h['puOffline'] = Hist( 20, 0, 2, name='puWeights_offline')
                    h['eventWeightHist'] = Hist( 100, -2, 2, name='eventWeightHist')                    
                    h['genWeightHist'] = Hist( 100, -2, 2, name='genWeightHist')
                    h['offlineWeightHist'] = Hist( 100, -2, 2, name='offlineWeightHist')
 
                    h['phaseSpaceInfoHist'] = Hist( 10, 0, 1, name='phaseSpaceInfoHist')


            # Counters for studying phase space
            nVis = {c.channelName : 0 for c in channels}
            nVisNotOffline = {c.channelName : 0 for c in channels}
            nOffline = {c.channelName : 0 for c in channels}
            nOfflineNotVis = {c.channelName : 0 for c in channels}
            nFull = {c.channelName : 0 for c in channels}
            nOfflineSL = {c.channelName : 0 for c in channels}

            n=0
            # Event Loop
            # for event, weight in zip(tree,weightTree):
            for event in tree:
                branch = event.__getattr__
                n+=1
                if not n%100000: print 'Processing event %.0f Progress : %.2g %%' % ( n, float(n)/nEntries*100 )
                # if n == 10000: break
                # # #
                # # # Weights and selection
                # # #

                # Pileup weight
                # Don't apply if calculating systematic
                pileupWeight = event.PUWeight
                # print event.PUWeight,event.PUWeight_up,event.PUWeight_down
                if options.sample == "pileupUp":
                    pileupWeight = event.PUWeight_up
                elif options.sample == "pileupDown":
                    pileupWeight = event.PUWeight_down

                # Generator level weight
                genWeight = event.EventWeight * measurement_config.luminosity_scale

                # Offline level weights
                offlineWeight = pileupWeight

                # Lepton weight
                leptonWeight = event.LeptonEfficiencyCorrection

                if options.sample == 'leptonup':
                    leptonWeight = event.LeptonEfficiencyCorrectionUp
                elif options.sample == 'leptondown':
                    leptonWeight == event.LeptonEfficiencyCorrectionDown

                # B Jet Weight
                bjetWeight = event.BJetWeight
                if options.sample == "bjetup":
                    bjetWeight = event.BJetUpWeight
                elif options.sample == "bjetdown":
                    bjetWeight = event.BJetDownWeight
                elif options.sample == "lightjetup":
                    bjetWeight = event.LightJetUpWeight
                elif options.sample == "lightjetdown":
                    bjetWeight = event.LightJetDownWeight

                offlineWeight = event.EventWeight * measurement_config.luminosity_scale
                offlineWeight *= pileupWeight
                offlineWeight *= bjetWeight
                offlineWeight *= leptonWeight

                # Generator weight
                # Scale up/down, pdf
                if pdfWeight >= 0:
                    genWeight *= branch('pdfWeight_%i' % pdfWeight)
                    offlineWeight *= branch('pdfWeight_%i' % pdfWeight)
                    pass

                if muFmuRWeight >= 0:
                    genWeight *= branch('muFmuRWeight_%i' % muFmuRWeight)
                    offlineWeight *= branch('muFmuRWeight_%i' % muFmuRWeight)
                    pass

                if alphaSWeight >= 0:
                    genWeight *= branch('alphaSWeight_%i' % alphaSWeight)
                    offlineWeight *= branch('alphaSWeight_%i' % alphaSWeight)
                    pass

                if options.applyTopPtReweighting != 0:
                    ptWeight = calculateTopPtWeight( branch('lepTopPt_parton'), branch('hadTopPt_parton'), options.applyTopPtReweighting)
                    offlineWeight *= ptWeight
                    genWeight *= ptWeight
                
                if options.applyTopEtaReweighting != 0:
                    etaWeight = calculateTopEtaWeight( branch('lepTopRap_parton'), branch('hadTopRap_parton'), options.applyTopEtaReweighting)
                    offlineWeight *= etaWeight
                    genWeight *= etaWeight

                for channel in channels:
                    # Generator level selection
                    genSelection = ''
                    genSelectionVis = ''
                    if channel.channelName is 'muPlusJets' :
                        genSelection = event.isSemiLeptonicMuon == 1
                        genSelectionVis = event.isSemiLeptonicMuon == 1 and event.passesGenEventSelection == 1
                    elif channel.channelName is 'ePlusJets' :
                        genSelection = event.isSemiLeptonicElectron == 1
                        genSelectionVis = event.isSemiLeptonicElectron == 1 and event.passesGenEventSelection == 1

                    # Offline level selection
                    offlineSelection = 0

                    if channel.channelName is 'muPlusJets' :
                        offlineSelection = int(event.passSelection) == 1
                    elif channel.channelName is 'ePlusJets' :               
                        offlineSelection = int(event.passSelection) == 2

                    # Fake selection
                    fakeSelection = offlineSelection and not genSelection
                    fakeSelectionVis = offlineSelection and not genSelectionVis

                    # Phase space info
                    if genSelection:
                        nFull[channel.channelName] += genWeight
                        if offlineSelection:
                            nOfflineSL[channel.channelName] += genWeight
                    if genSelectionVis:
                        nVis[channel.channelName] += genWeight
                        if not offlineSelection:
                            nVisNotOffline[channel.channelName] += genWeight
                    if offlineSelection:
                        nOffline[channel.channelName] += offlineWeight
                        if not genSelectionVis:
                            nOfflineNotVis[channel.channelName] += offlineWeight

                    for variable in allVariablesBins:
                        if options.sample in measurement_config.met_systematics and variable not in ['MET', 'ST', 'WPT']:
                            continue

                        # # #
                        # # # Variable to plot
                        # # #
                        recoVariable = branch(recoVariableNames[variable])
                        if variable in ['MET', 'ST', 'WPT'] and \
                        sysIndex != None and ( offlineSelection or fakeSelection or fakeSelectionVis ) :
                            recoVariable = recoVariable[sysIndex]
                        
                        if 'abs' in variable:
                            recoVariable = abs(recoVariable)

                        # With TUnfold, reco variable never goes in the overflow (or underflow)
                        # if recoVariable > allVariablesBins[variable][-1]:
                        #     print 'Big reco variable : ',recoVariable
                        #     print 'Setting to :',min( recoVariable, allVariablesBins[variable][-1] - 0.000001 )
                        if not options.fineBinned:
                            recoVariable = min( recoVariable, allVariablesBins[variable][-1] - 0.000001 )
                        genVariable_particle = branch(genVariable_particle_names[variable])
                        if 'abs' in variable:
                            genVariable_particle = abs(genVariable_particle)
                        # #
                        # # Fill histograms
                        # #
                        histogramsToFill = histograms[variable][channel.channelName]
                        if not options.donothing:

                            if genSelection:
                                histogramsToFill['truth'].Fill( genVariable_particle, genWeight)
                            if genSelectionVis:
                                histogramsToFill['truthVis'].Fill( genVariable_particle, genWeight)
                            if offlineSelection:
                                histogramsToFill['measured'].Fill( recoVariable, offlineWeight)
                                histogramsToFill['measuredVis'].Fill( recoVariable, offlineWeight)
                                if genSelectionVis :
                                    histogramsToFill['measuredVis_without_fakes'].Fill( recoVariable, offlineWeight)
                                if genSelection:
                                    histogramsToFill['measured_without_fakes'].Fill( recoVariable, offlineWeight)
                                histogramsToFill['response'].Fill( recoVariable, genVariable_particle, offlineWeight )
                            if offlineSelection and genSelection:
                                histogramsToFill['response_without_fakes'].Fill( recoVariable, genVariable_particle, offlineWeight ) 
                            elif genSelection:
                                histogramsToFill['response_without_fakes'].Fill( allVariablesBins[variable][0]-1, genVariable_particle, genWeight )
                                # if genVariable_particle < 0 : print recoVariable, genVariable_particle
                                # if genVariable_particle < 0 : print genVariable_particle
                            if offlineSelection and genSelectionVis:
                                histogramsToFill['responseVis_without_fakes'].Fill( recoVariable, genVariable_particle, offlineWeight )
                            elif genSelectionVis:
                                histogramsToFill['responseVis_without_fakes'].Fill( allVariablesBins[variable][0]-1, genVariable_particle, genWeight )
                            if fakeSelection:
                                histogramsToFill['fake'].Fill( recoVariable, offlineWeight)
                            if fakeSelectionVis:
                                histogramsToFill['fakeVis'].Fill( recoVariable, offlineWeight)

                            if options.extraHists:
                                if genSelection:
                                    histogramsToFill['eventWeightHist'].Fill(event.EventWeight)
                                    histogramsToFill['genWeightHist'].Fill(genWeight)
                                    histogramsToFill['offlineWeightHist'].Fill(offlineWeight)

            #
            # Output histgorams to file
            #
            for variable in allVariablesBins:
                if options.sample in measurement_config.met_systematics and variable not in ['MET', 'ST', 'WPT']:
                    continue
                for channel in channels:

                    # Fill phase space info
                    h = histograms[variable][channel.channelName]['phaseSpaceInfoHist']
                    h.SetBinContent(1, nVisNotOffline[channel.channelName] / nVis[channel.channelName])
                    h.SetBinContent(2, nOfflineNotVis[channel.channelName] / nOffline[channel.channelName])
                    h.SetBinContent(3, nVis[channel.channelName] / nFull[channel.channelName])
                    # Selection efficiency for SL ttbar
                    h.SetBinContent(4, nOfflineSL[channel.channelName] / nFull[channel.channelName])
                    # Fraction of offline that are SL
                    h.SetBinContent(5, nOfflineSL[channel.channelName] / nOffline[channel.channelName])

                    outputDirs[variable][channel.channelName].cd()
                    for h in histograms[variable][channel.channelName]:
                        histograms[variable][channel.channelName][h].Write()


    with root_open( outputFileName, 'update') as out:
        # Done all channels, now combine the two channels, and output to the same file
        for path, dirs, objects in out.walk():
            if 'electron' in path:
                outputDir = out.mkdir(path.replace('electron','combined'))
                outputDir.cd()
                for h in objects:
                    h_e = out.Get(path+'/'+h)
                    h_mu = out.Get(path.replace('electron','muon')+'/'+h)
                    h_comb = (h_e + h_mu).Clone(h)
                    h_comb.Write()
                pass
            pass
        pass
def make_eff_plots(input_files, file_path, split=''):
    '''
	1D and 2D efficiency plotter
	'''
    #################################################################################################################################
    # PLOT EFFICIENCY
    #################################################################################################################################
    f = TFile(file_path, "OPEN")
    make_folder_if_not_exists('plots/BTagEfficiency/')

    # #################################################################################################################################
    # # PLOT 2D EFFICIENCY
    # #################################################################################################################################
    for generator in input_files.values():
        b_Hist = f.Get(generator + "/bQuarkJets_Ratio_Hist")
        c_Hist = f.Get(generator + "/cQuarkJets_Ratio_Hist")
        udsg_Hist = f.Get(generator + "/udsgQuarkJets_Ratio_Hist")

        b_Canvas = TCanvas("bQuarkJet", "bQuarkJet", 0, 0, 800, 600)
        b_Hist.SetTitle("b quark b tagging efficiency ; pt; eta")
        b_Hist.Draw("colz")
        b_Canvas.Update()
        b_Canvas.SaveAs("plots/BTagEfficiency/bQuarkJet_" + generator +
                        "_BTagEfficiency.png")

        c_Canvas = TCanvas("cQuarkJet", "cQuarkJet", 0, 0, 800, 600)
        c_Hist.SetTitle("c quark b tagging efficiency ; pt; eta")
        c_Hist.Draw("colz")
        c_Canvas.Update()
        c_Canvas.SaveAs("plots/BTagEfficiency/cQuarkJet_" + generator +
                        "_BTagEfficiency.png")

        udsg_Canvas = TCanvas("udsgQuarkJet", "udsgQuarkJet", 0, 0, 800, 600)
        udsg_Hist.SetTitle("udsg quark b tagging efficiency ; pt; eta")
        udsg_Hist.Draw("colz")
        udsg_Canvas.Update()
        udsg_Canvas.SaveAs("plots/BTagEfficiency/udsgQuarkJet_" + generator +
                           "_BTagEfficiency.png")

    #################################################################################################################################
    # PLOT 1D EFFICIENCY
    #################################################################################################################################

    b_pt = {}
    b_eta = {}
    c_pt = {}
    c_eta = {}
    udsg_pt = {}
    udsg_eta = {}

    for generator in input_files.values():
        # Only get generators if they exist in the file
        if not f.GetListOfKeys().Contains(generator): continue

        # Split into categories
        if split == 'generator':
            if generator not in [
                    'PowhegPythia8', 'PowhegHerwigpp', 'aMCatNLOPythia8',
                    'Madgraph'
            ]:
                continue
        if split == 'Shape':
            if generator not in [
                    'PowhegPythia8', 'PowhegPythia8_plusJES',
                    'PowhegPythia8_minusJES', 'PowhegPythia8_plusJER',
                    'PowhegPythia8_minusJER', 'PowhegPythia8_mtop1695',
                    'PowhegPythia8_mtop1755'
            ]:
                continue
        if split == 'Tune':
            if generator not in [
                    'PowhegPythia8', 'PowhegPythia8_fsrup',
                    'PowhegPythia8_fsrdown', 'PowhegPythia8_isrup',
                    'PowhegPythia8_isrdown', 'PowhegPythia8_up',
                    'PowhegPythia8_down'
            ]:
                continue

        b_pt[generator] = asrootpy(
            f.Get(generator + "/bQuarkJets_Ratio_Pt_Hist"))
        b_eta[generator] = asrootpy(
            f.Get(generator + "/bQuarkJets_Ratio_Eta_Hist"))
        c_pt[generator] = asrootpy(
            f.Get(generator + "/cQuarkJets_Ratio_Pt_Hist"))
        c_eta[generator] = asrootpy(
            f.Get(generator + "/cQuarkJets_Ratio_Eta_Hist"))
        udsg_pt[generator] = asrootpy(
            f.Get(generator + "/udsgQuarkJets_Ratio_Pt_Hist"))
        udsg_eta[generator] = asrootpy(
            f.Get(generator + "/udsgQuarkJets_Ratio_Eta_Hist"))

    eff_to_plot = {
        "b parton tagging effienciency (pt)": b_pt,
        "b parton tagging effienciency (eta)": b_eta,
        "c parton tagging effienciency (pt)": c_pt,
        "c parton tagging effienciency (eta)": c_eta,
        "udsg parton tagging effienciency (pt)": udsg_pt,
        "udsg parton tagging effienciency (eta)": udsg_eta,
    }

    print b_pt

    colours = [
        'red', 'blue', 'green', 'chartreuse', 'indigo', 'magenta',
        'darkmagenta', 'hotpink', 'cyan', 'darkred', 'darkgoldenrod',
        'mediumvioletred', 'mediumspringgreen', 'gold', 'darkgoldenrod',
        'slategray', 'dodgerblue', 'cadetblue', 'darkblue', 'seagreen',
        'deeppink', 'deepskyblue'
    ]

    for title, efficiencies in eff_to_plot.iteritems():

        # create figure
        fig_eff = plt.figure(figsize=(20, 16), dpi=400, facecolor='white')
        ax_eff = fig_eff.add_subplot(1, 1, 1)
        ax_eff.minorticks_on()
        ax_eff.xaxis.labelpad = 12
        ax_eff.yaxis.labelpad = 12
        ax_eff.set_ylim(0, 1)
        plt.tick_params(**CMS.axis_label_major)
        plt.tick_params(**CMS.axis_label_minor)

        # plot specifics
        var = 'pt'
        if 'eta' in title:
            var = 'eta'
        parton = 'b'
        if "c parton" in title: parton = 'c'
        if "udsg parton" in title: parton = 'udsg'

        ylimits = []
        if parton == 'b':
            if var == 'pt':
                y_limits = [0.480, 0.75]
            if var == 'eta':
                y_limits = [0.510, 0.75]
        if parton == 'c':
            if var == 'pt':
                y_limits = [0.150, 0.200]
            if var == 'eta':
                y_limits = [0.125, 0.21]
        if parton == 'udsg':
            if var == 'pt':
                y_limits = [0.015, 0.050]
            if var == 'eta':
                y_limits = [0.014, 0.034]
        # labels
        x_title = var
        if var == 'pt':
            x_title += ' [GeV]'
        plt.xlabel(x_title, CMS.x_axis_title)
        plt.ylabel('Efficiency', CMS.y_axis_title)
        template = '%.1f fb$^{-1}$ (%d TeV)'
        label = template % (measurement_config.new_luminosity / 1000,
                            measurement_config.centre_of_mass_energy)
        plt.title(label, loc='right', **CMS.title)

        # plot histograms
        i = 0
        for label, h in efficiencies.iteritems():
            hist = asrootpy(h)
            h.linewidth = 4
            h.color = 'black'
            if label != 'PowhegPythia8':
                hist.linestyle = 'dashed'
                # hist.alpha = 0.8
                hist.linewidth = 2
                h.color = colours[i]

            rplt.hist(h, stacked=False, label=label)
            i += 1

        # plot legend
        leg = plt.legend(loc='best', prop={'size': 25}, ncol=2)
        leg.draw_frame(False)

        ax_eff.set_ylim(y_limits)

        # additional text
        # logo_location = (0.05, 0.95)
        # plt.text(logo_location[0], logo_location[1],
        # 	"CMS",
        # 	transform=ax_eff.transAxes,
        # 	fontsize=42,
        # 	verticalalignment='top',
        # 	horizontalalignment='left'
        # )
        # title_location = (0.05, 0.90)
        # plt.text(title_location[0], title_location[1],
        # 	title,
        # 	transform=ax_eff.transAxes,
        # 	fontsize=42,
        # 	verticalalignment='top',
        # 	horizontalalignment='left'
        # )

        # filename and saving
        name_template = '{parton}_{var}_{split}efficiency.pdf'
        s = ''
        if split: s = split + '_'
        name = name_template.format(
            parton=parton,
            var=var,
            split=s,
        )
        plt.tight_layout()
        fig_eff.savefig('plots/BTagEfficiency/' + name)

    f.Close()
    return
def make_eff_plots(input_files, file_path, split=''):
	'''
	1D and 2D efficiency plotter
	'''
	#################################################################################################################################
	# PLOT EFFICIENCY
	#################################################################################################################################
	f = TFile(file_path, "OPEN")
	make_folder_if_not_exists('plots/BTagEfficiency/')

	# #################################################################################################################################
	# # PLOT 2D EFFICIENCY
	# #################################################################################################################################
	for generator in input_files.values():
		b_Hist = f.Get(generator+"/bQuarkJets_Ratio_Hist")
		c_Hist = f.Get(generator+"/cQuarkJets_Ratio_Hist")
		udsg_Hist = f.Get(generator+"/udsgQuarkJets_Ratio_Hist")

		b_Canvas = TCanvas("bQuarkJet","bQuarkJet", 0, 0, 800, 600)
		b_Hist.SetTitle("b quark b tagging efficiency ; pt; eta")
		b_Hist.Draw("colz")
		b_Canvas.Update()
		b_Canvas.SaveAs("plots/BTagEfficiency/bQuarkJet_"+generator+"_BTagEfficiency.png")

		c_Canvas = TCanvas("cQuarkJet","cQuarkJet", 0, 0, 800, 600)
		c_Hist.SetTitle("c quark b tagging efficiency ; pt; eta")
		c_Hist.Draw("colz")
		c_Canvas.Update()
		c_Canvas.SaveAs("plots/BTagEfficiency/cQuarkJet_"+generator+"_BTagEfficiency.png")
		
		udsg_Canvas = TCanvas("udsgQuarkJet","udsgQuarkJet", 0, 0, 800, 600)
		udsg_Hist.SetTitle("udsg quark b tagging efficiency ; pt; eta")
		udsg_Hist.Draw("colz")
		udsg_Canvas.Update()
		udsg_Canvas.SaveAs("plots/BTagEfficiency/udsgQuarkJet_"+generator+"_BTagEfficiency.png")

	#################################################################################################################################
	# PLOT 1D EFFICIENCY
	#################################################################################################################################

	b_pt 		= {}
	b_eta 		= {}
	c_pt 		= {}
	c_eta 		= {}
	udsg_pt 	= {}
	udsg_eta 	= {}

	for generator in input_files.values():
		# Only get generators if they exist in the file
		if not f.GetListOfKeys().Contains(generator): continue

		# Split into categories
		if split == 'generator':
			if generator not in [
				'PowhegPythia8', 
				'PowhegHerwigpp', 
				'aMCatNLOPythia8', 
				'Madgraph'
				]: continue
		if split == 'Shape':
			if generator not in [
				'PowhegPythia8', 
				'PowhegPythia8_plusJES', 
				'PowhegPythia8_minusJES', 
				'PowhegPythia8_plusJER', 
				'PowhegPythia8_minusJER',  
				'PowhegPythia8_mtop1695', 
				'PowhegPythia8_mtop1755'
				]: continue
		if split == 'Tune':
			if generator not in [
				'PowhegPythia8', 
				'PowhegPythia8_fsrup', 
				'PowhegPythia8_fsrdown', 
				'PowhegPythia8_isrup', 
				'PowhegPythia8_isrdown',
				'PowhegPythia8_up', 
				'PowhegPythia8_down'
				]: continue

		b_pt[generator] 	= asrootpy( f.Get(generator+"/bQuarkJets_Ratio_Pt_Hist") )
		b_eta[generator] 	= asrootpy( f.Get(generator+"/bQuarkJets_Ratio_Eta_Hist") )
		c_pt[generator] 	= asrootpy( f.Get(generator+"/cQuarkJets_Ratio_Pt_Hist") )
		c_eta[generator] 	= asrootpy( f.Get(generator+"/cQuarkJets_Ratio_Eta_Hist") )
		udsg_pt[generator] 	= asrootpy( f.Get(generator+"/udsgQuarkJets_Ratio_Pt_Hist") )
		udsg_eta[generator] = asrootpy( f.Get(generator+"/udsgQuarkJets_Ratio_Eta_Hist") )

	eff_to_plot = {
		"b parton tagging effienciency (pt)" : b_pt,
		"b parton tagging effienciency (eta)" : b_eta,
		"c parton tagging effienciency (pt)" : c_pt,
		"c parton tagging effienciency (eta)" : c_eta,
		"udsg parton tagging effienciency (pt)" : udsg_pt,
		"udsg parton tagging effienciency (eta)" : udsg_eta,
	}

	print b_pt

	colours = [
		'red', 'blue', 'green', 'chartreuse', 'indigo', 
		'magenta', 'darkmagenta', 'hotpink', 'cyan', 'darkred', 
		'darkgoldenrod', 'mediumvioletred', 'mediumspringgreen', 
		'gold', 'darkgoldenrod', 'slategray', 'dodgerblue', 
		'cadetblue', 'darkblue', 'seagreen', 'deeppink', 'deepskyblue' 
	]

	for title, efficiencies in eff_to_plot.iteritems():

		# create figure
		fig_eff = plt.figure( figsize = ( 20, 16 ), dpi = 400, facecolor = 'white' )
		ax_eff = fig_eff.add_subplot(1, 1, 1)
		ax_eff.minorticks_on()
		ax_eff.xaxis.labelpad = 12
		ax_eff.yaxis.labelpad = 12
		ax_eff.set_ylim( 0, 1 )
		plt.tick_params( **CMS.axis_label_major )
		plt.tick_params( **CMS.axis_label_minor )

		# plot specifics
		var = 'pt'
		if 'eta' in title:
			var = 'eta'
		parton = 'b'
		if "c parton" in title: parton = 'c'
		if "udsg parton" in title: parton = 'udsg'

		ylimits=[]
		if parton == 'b':
			if var == 'pt':
				y_limits = [0.480,0.75]
			if var == 'eta':
				y_limits = [0.510,0.75]
		if parton == 'c':
			if var == 'pt':
				y_limits = [0.150,0.200]
			if var == 'eta':
				y_limits = [0.125,0.21]
		if parton == 'udsg':
			if var == 'pt':
				y_limits = [0.015,0.050]
			if var == 'eta':
				y_limits = [0.014,0.034]
		# labels
		x_title = var
		if var == 'pt':
			x_title+=' [GeV]'
		plt.xlabel( x_title, CMS.x_axis_title )
		plt.ylabel( 'Efficiency', CMS.y_axis_title)
		template = '%.1f fb$^{-1}$ (%d TeV)'
		label = template % ( measurement_config.new_luminosity/1000, measurement_config.centre_of_mass_energy)
		plt.title( label,loc='right', **CMS.title )

		# plot histograms
		i=0
		for label, h in efficiencies.iteritems():
			hist = asrootpy( h )
			h.linewidth = 4
			h.color = 'black'
			if label != 'PowhegPythia8':
				hist.linestyle = 'dashed'
				# hist.alpha = 0.8	
				hist.linewidth = 2
				h.color = colours[i]

			rplt.hist( h, stacked=False, label = label )
			i+=1

		# plot legend
		leg = plt.legend(loc='best',prop={'size':25},ncol=2)
		leg.draw_frame(False)	

		ax_eff.set_ylim( y_limits )

		# additional text 
		# logo_location = (0.05, 0.95)
		# plt.text(logo_location[0], logo_location[1], 
		# 	"CMS", 
		# 	transform=ax_eff.transAxes, 
		# 	fontsize=42,
		# 	verticalalignment='top',
		# 	horizontalalignment='left'
		# )
		# title_location = (0.05, 0.90)
		# plt.text(title_location[0], title_location[1], 
		# 	title,
		# 	transform=ax_eff.transAxes, 
		# 	fontsize=42,
		# 	verticalalignment='top',
		# 	horizontalalignment='left'
		# )

		# filename and saving
		name_template = '{parton}_{var}_{split}efficiency.pdf'
		s=''
		if split: s = split+'_' 
		name = name_template.format(
			parton=parton,
			var=var,
			split=s,
		)
		plt.tight_layout()
		fig_eff.savefig('plots/BTagEfficiency/'+name)

	f.Close()
	return
Пример #48
0
    sys.exit()

#set up the config according to the centre of mass energy
config = XSectionConfig(options.centreOfMassEnergy)

#Get the luminosity for the centre of mass energy
luminosity = config.luminosities[options.centreOfMassEnergy]

#Get current working directory
current_working_directory = os.getcwd()

#Get folder to move files to
path_to_AN_folder = config.path_to_files

#move log files separately first, since there is no "logs" category in categories_and_prefixes
make_folder_if_not_exists(path_to_AN_folder + '/logs/')
command = 'mv ' + options.pathToBATOutputFiles + '/*' + str(
    options.centreOfMassEnergy) + 'TeV*.log ' + path_to_AN_folder + '/logs/'
if options.doNothing:
    print "command = ", command
    print "path to folder = ", path_to_AN_folder + '/logs/'
elif not options.doNothing:
    make_folder_if_not_exists(path_to_AN_folder + "/logs")

    p = subprocess.Popen(command, shell=True)
    p.wait()

#Now move all other BAT output files.

for category in config.categories_and_prefixes.keys():
    make_folder_if_not_exists(path_to_AN_folder + "/" + category)
def main():
    ########## 			SETUP 			##########
    t = time.time()
    gStyle.SetOptStat("")

    #################################################################################################################################
    # READ THE OPTIONS
    #################################################################################################################################
    parser = ArgumentParser()
    parser.add_argument("-t",
                        "--test",
                        dest="test",
                        action="store_true",
                        help="Run over a few events only")
    parser.add_argument("-p",
                        "--plots",
                        dest="make_plots",
                        action="store_true",
                        help="Print out files to .png")
    parser.add_argument("-o",
                        "--only_plots",
                        dest="only_plots",
                        action="store_true",
                        help="Print out files to .png")
    parser.add_argument("-d",
                        "--debug",
                        dest="debug",
                        action="store_true",
                        help="Run debugger")
    args = parser.parse_args()
    if args.test: print "RUNNING OVER TEST SAMPLE"
    debug = args.debug

    #################################################################################################################################
    # ADD THE GENERATOR INPUT FILES
    #################################################################################################################################
    samples = [
        "PowhegPythia8",
        "PowhegHerwigpp",
        "aMCatNLOPythia8",
        "Madgraph",
        "PowhegPythia8_fsrup",
        "PowhegPythia8_fsrdown",
        "PowhegPythia8_isrup",
        "PowhegPythia8_isrdown",
        # "PowhegPythia8_ueup",
        # "PowhegPythia8_uedown",
        # "PowhegPythia8_mtop1755",
        # "PowhegPythia8_mtop1695",
        # "PowhegPythia8_hdampup",
        # "PowhegPythia8_hdampdown",
        # "PowhegPythia8_erdOn",
        # "PowhegPythia8_QCDbased_erdOn",
        # "PowhegPythia8_GluonMove",
    ]
    if debug:
        print "Constructed Input Files and Read Arguments"
        t = get_time(t)

    #################################################################################################################################
    # INITIALISE THE BINNING AND WEIGHTS
    #################################################################################################################################
    pt_binning = [30, 50, 70, 100, 140, 200, 300, 600, 1000]
    # pt_binning = [30, 50, 70, 100, 140, 200]
    barrel_endcap_split = 1.3

    if debug:
        print "Initialised Pt and Eta binning"
        t = get_time(t)

    #################################################################################################################################
    # INITIALISE THE INPUT AND OUTPUT PATHS
    #################################################################################################################################
    file_path = 'dps/experimental/DougsJESEff/JESEfficiency.root'

    output_file = root_open(file_path, "recreate")
    make_folder_if_not_exists('plots/JetEfficiency/Summary/')

    #################################################################################################################################
    # CALCULATE THE JET PT / PSEUDOJET PT GAUSSIANS
    #################################################################################################################################
    r = {}
    for sample in samples:
        make_folder_if_not_exists('plots/JetEfficiency/' + sample)

        r[sample] = {}
        r[sample]['BarrelLightJet'] = {}
        r[sample]['BarrelBJet'] = {}
        r[sample]['EndcapLightJet'] = {}
        r[sample]['EndcapBJet'] = {}
        for i in range(1, len(pt_binning)):
            r[sample]['BarrelLightJet'][i] = Hist(
                50,
                0,
                2,
                name='Residuals_Bin_BarrelLightJet_' + sample + '_' + str(i))
            r[sample]['BarrelBJet'][i] = Hist(
                50,
                0,
                2,
                name='Residuals_Bin_BarrelBJet_' + sample + '_' + str(i))
            r[sample]['EndcapLightJet'][i] = Hist(
                50,
                0,
                2,
                name='Residuals_Bin_EndcapLightJet_' + sample + '_' + str(i))
            r[sample]['EndcapBJet'][i] = Hist(
                50,
                0,
                2,
                name='Residuals_Bin_EndcapBJet_' + sample + '_' + str(i))

        file_name = getFileName(sample, measurement_config)
        print "Calculating JES Efficiency For Generator : ", sample
        treeName = "TTbar_plus_X_analysis/JESAnalyser/JESAnalyser"
        file_name = getUnmergedDirectory(file_name)

        tree = ROOT.TChain(treeName)
        filenames = glob.glob(file_name)
        for f in filenames:
            tree.Add(f)

        nEntries = tree.GetEntries()
        print 'Number of entries:', nEntries
        n = 0
        for event in tree:
            branch = event.__getattr__
            n += 1
            if not n % 1000000:
                print 'Processing event %.0f Progress : %.2g %%' % (
                    n, float(n) / nEntries * 100)
            # if n > 1000: break

            jetPts = branch('jetPt')
            isBJets = branch('isB')
            isBarrels = branch('isBarrel')
            recoGenRatios = branch('recoGenRatio')

            for jpt, isBJet, isBarrel, recoGenRatio in zip(
                    jetPts, isBJets, isBarrels, recoGenRatios):
                if jpt <= 30: continue
                # Find Jet Pt Bin to Fill
                for i, edge in enumerate(pt_binning):
                    if jpt > edge:
                        continue
                    else:
                        break

                # DEBUG PURPOSES
                # print "- "*30
                # print "Jet Pt : {}".format(jpt)
                # print "is a BJet : {}".format(isBJet)
                # print "is in Barrel : {}".format(isBarrel)
                # print "recoGen ratio : {}".format(recoGenRatio)
                # print "filled in Bin {}".format(i)
                # raw_input()

                if isBarrel:
                    if isBJet:
                        r[sample]['BarrelBJet'][i].Fill(recoGenRatio)
                    else:
                        r[sample]['BarrelLightJet'][i].Fill(recoGenRatio)
                else:
                    if isBJet:
                        r[sample]['EndcapBJet'][i].Fill(recoGenRatio)
                    else:
                        r[sample]['EndcapLightJet'][i].Fill(recoGenRatio)

    #################################################################################################################################
    # FIT THE GAUSSIANS AND CREATE AVERAGE JET PT / PSEUDOJET PT HISTOGRAMS
    #################################################################################################################################
    h_mean = {}
    for sample in samples:
        h_mean[sample] = {}
        for quadrant in [
                'BarrelLightJet', 'BarrelBJet', 'EndcapLightJet', 'EndcapBJet'
        ]:
            gaussian_fit = []
            for i, hist in r[sample][quadrant].iteritems():
                try:
                    f = hist.Fit("gaus", "SMQ", "", 0, 2)
                    mean = f.Parameter(1)
                except:
                    # Jet pt 20-30 not available
                    mean = -1
                    print "Cannot fit histogram"
                gaussian_fit.append(mean)

                # Plot individual pt bins
                canvas = TCanvas("c", "c", 0, 0, 800, 600)
                hist.SetTitle(" ; pt; jet pT / pseudo jet pT")
                hist.Draw()
                canvas.Update()
                canvas.SaveAs('plots/JetEfficiency/' + sample + "/" +
                              quadrant + "_" + str(i) + "_JetEfficiency.png")

            # Combine <pt ratio> into one hist
            h_mean[sample][quadrant] = value_tuplelist_to_hist(
                gaussian_fit, pt_binning)
            canvas = TCanvas("c", "c", 0, 0, 800, 600)
            h_mean[sample][quadrant].SetTitle(
                "JES efficiency ; pt; <jet over genjet>")
            h_mean[sample][quadrant].Draw()
            canvas.Update()
            canvas.SaveAs('plots/JetEfficiency/' + sample + "/" + quadrant +
                          "_JetAveEfficiency.png")

    #################################################################################################################################
    # FIND THE CORRECTION, RATIO OF <Central Pt> / <Variation Pt>
    #################################################################################################################################
    h_jes = {}
    for sample in samples:
        h_jes[sample] = {}
        for quadrant in [
                'BarrelLightJet', 'BarrelBJet', 'EndcapLightJet', 'EndcapBJet'
        ]:

            h_jes[sample][quadrant] = h_mean['PowhegPythia8'][quadrant].Clone()
            h_jes[sample][quadrant].Divide(h_jes[sample][quadrant],
                                           h_mean[sample][quadrant], 1, 1, "B")

            canvas = TCanvas("c", "c", 0, 0, 800, 600)
            h_jes[sample][quadrant].SetTitle(
                "JES efficiency ; pt; <jet over genjet> over <jet over genjet>"
            )
            h_jes[sample][quadrant].Draw()
            canvas.Update()
            canvas.SaveAs('plots/JetEfficiency/Summary/' + sample + "_" +
                          quadrant + "_JetCorrection.png")

    colours = [
        'red', 'blue', 'green', 'chartreuse', 'indigo', 'magenta',
        'darkmagenta', 'hotpink', 'cyan', 'darkred', 'darkgoldenrod',
        'mediumvioletred', 'mediumspringgreen', 'gold', 'darkgoldenrod',
        'slategray', 'dodgerblue', 'cadetblue', 'darkblue', 'seagreen',
        'deeppink', 'deepskyblue'
    ]

    for quadrant in [
            'BarrelLightJet', 'BarrelBJet', 'EndcapLightJet', 'EndcapBJet'
    ]:
        i = 0
        fig_eff = plt.figure(figsize=(20, 16), dpi=400, facecolor='white')
        ax_eff = fig_eff.add_subplot(1, 1, 1)
        ax_eff.minorticks_on()
        ax_eff.xaxis.labelpad = 12
        ax_eff.yaxis.labelpad = 12
        ax_eff.set_ylim(0, 1)
        plt.tick_params(**CMS.axis_label_major)
        plt.tick_params(**CMS.axis_label_minor)

        y_limits = [0.95, 1.05]
        y_title = '<jet over genjet> / <jet over genjet>'
        x_title = 'Jet Pt [GeV]'
        plt.xlabel(x_title, CMS.x_axis_title)
        plt.ylabel(y_title, CMS.y_axis_title)

        template = '%.1f fb$^{-1}$ (%d TeV)'
        label = template % (measurement_config.new_luminosity / 1000.,
                            measurement_config.centre_of_mass_energy)
        plt.title(label, loc='right', **CMS.title)

        for sample, hists in h_jes.iteritems():
            hist = hists[quadrant]
            hist.linewidth = 4
            hist.color = 'black'
            l = sample
            if sample != 'PowhegPythia8':
                hist.linestyle = 'dashed'
                hist.linewidth = 2
                if 'aMCatNLOPythia8' in sample:
                    hist.color = 'blue'
                    hist.linestyle = 'solid'
                if 'PowhegHerwigpp' in sample:
                    hist.color = 'red'
                    hist.linestyle = 'solid'
                if 'Madgraph' in sample:
                    hist.color = 'green'
                    hist.linestyle = 'solid'
                if 'fsr' in sample:
                    hist.color = 'hotpink'
                    l = l.replace('down', '')
                    if 'up' in sample: l = ''
                if 'isr' in sample:
                    hist.color = 'cyan'
                    l = l.replace('down', '')
                    if 'up' in sample: l = ''

            rplt.hist(hist, stacked=False, label=l)
            i += 1

        # plot legend
        leg = plt.legend(loc='best', prop={'size': 25}, ncol=2)
        leg.draw_frame(False)
        ax_eff.set_ylim(y_limits)

        # plt.text(0.05, 0.97,
        #     r"{}".format(quadrant),
        #     transform=ax_eff.transAxes,
        #     fontsize=42,
        #     verticalalignment='top',
        #     horizontalalignment='left'
        # )

        plt.tight_layout()

        fig_eff.savefig('plots/JetEfficiency/Summary/' + quadrant +
                        "_JetCorrections.pdf")
def main():
    parser = OptionParser(__doc__)
    parser.add_option(
        "-v",
        "--variable",
        dest="variable",
        default='MET',
        help="set the variable to analyse (MET, HT, ST, MT, WPT)")
    parser.add_option(
        "-s",
        "--centre-of-mass-energy",
        dest="CoM",
        default=8,
        help="set the centre of mass energy for analysis. Default = 8 [TeV]",
        type=int)
    parser.add_option("-o",
                      "--output",
                      dest="output_folder",
                      default='plots/unfolding_pulls',
                      help="output folder for unfolding pull plots")
    parser.add_option("-c",
                      "--channel",
                      type='string',
                      dest="channel",
                      default='combined',
                      help="channel to be analysed: electron|muon|combined")

    (options, args) = parser.parse_args()
    if len(args) == 0:
        print('No input files specified.')
        print('Run script with "-h" for usage')
        sys.exit(-1)
    files = args

    centre_of_mass = options.CoM
    variable = options.variable
    channel = options.channel
    output_folder_base = options.output_folder + '/' + \
        str(centre_of_mass) + 'TeV/' + variable + '/' + channel + '/'
    make_folder_if_not_exists(output_folder_base)
    output_formats = ['pdf']

    bins = array('d', bin_edges_full[variable])
    nbins = len(bins) - 1

    kValues = sorted(getkValueRange(files))

    sigmaForEachK = []
    tau = -1
    for k in kValues:
        if k is 1:
            continue

        output_folder = output_folder_base + '/kv' + str(k) + '/'
        make_folder_if_not_exists(output_folder)
        print(
            'Producing unfolding pull plots for {0} variable, k-value of {1}, channel: {2}.'
            .format(variable, k, channel))
        print('Output folder: {0}'.format(output_folder))
        pulls = get_data(files, subset='pull')

        maxSigma = 0
        minSigma = 100
        for bin_i in range(0, nbins):
            fitResults = plot_pull(pulls,
                                   centre_of_mass,
                                   channel,
                                   variable,
                                   k,
                                   tau,
                                   output_folder,
                                   output_formats,
                                   bin_index=bin_i,
                                   n_bins=nbins)
            if fitResults.sigma > maxSigma:
                maxSigma = fitResults.sigma
            if fitResults.sigma < minSigma:
                minSigma = fitResults.sigma

        # plot all bins
        allBinsFitResults = plot_pull(pulls, centre_of_mass, channel, variable,
                                      k, tau, output_folder, output_formats)

        allBinsSigma = allBinsFitResults.sigma
        sigmaForEachK.append([k, allBinsSigma, maxSigma, minSigma])
        print('All bins sigma :', allBinsFitResults.sigma)
        print('Max/min sigma :', maxSigma, minSigma)
        print('Spread :', maxSigma - minSigma)
        del pulls  # deleting to make space in memory
    print()

    kValues = list(zip(*sigmaForEachK)[0])
    kValuesup = []
    kValuesdown = []
    sigmas = list(zip(*sigmaForEachK)[1])
    sigmaups = list(zip(*sigmaForEachK)[2])
    sigmadowns = list(zip(*sigmaForEachK)[3])
    spread = []

    for i in range(0, len(sigmas)):
        spread.append((sigmaups[i] - sigmadowns[i]) / sigmas[i])
        sigmaups[i] = sigmaups[i] - sigmas[i]
        sigmadowns[i] = sigmas[i] - sigmadowns[i]
        kValuesup.append(0.5)
        kValuesdown.append(0.5)
    print(spread)
    kValueChoice = spread.index(min(spread))
    print(kValueChoice)

    graph = asrootpy(
        TGraphAsymmErrors(len(sigmas), array('d', kValues), array('d', sigmas),
                          array('d', kValuesdown), array('d', kValuesup),
                          array('d', sigmadowns), array('d', sigmaups)))
    graphSpread = asrootpy(
        TGraphAsymmErrors(len(sigmas), array('d', kValues), array('d', spread),
                          array('d', kValuesdown), array('d', kValuesup),
                          array('d', sigmadowns), array('d', sigmaups)))

    # plot with matplotlib
    plt.figure(figsize=(20, 16), dpi=200, facecolor='white')

    ax0 = plt.axes()
    ax0.minorticks_on()
    ax0.grid(True, 'major', linewidth=2)
    ax0.grid(True, 'minor')
    plt.tick_params(**CMS.axis_label_major)
    plt.tick_params(**CMS.axis_label_minor)

    ax0.xaxis.set_major_formatter(FormatStrFormatter('%d'))
    ax0.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))
    ax0.xaxis.labelpad = 11

    rplt.errorbar(graph,
                  xerr=True,
                  emptybins=True,
                  axes=ax0,
                  marker='o',
                  ms=15,
                  mew=3,
                  lw=2)
    rplt.errorbar(graphSpread,
                  xerr=None,
                  yerr=False,
                  axes=ax0,
                  linestyle='-',
                  marker='s',
                  ms=10,
                  mew=1,
                  lw=2)

    for output_format in output_formats:
        print(output_folder_base)
        plt.savefig(output_folder_base + '/TESTGRAPH' + '.' + output_format)

    print(kValues)
    print(kValuesup)
    print(kValuesdown)
    print(sigmas)
    print(sigmaups)
    print(sigmadowns)
    print(sigmaForEachK)
def make_template_plots(histograms, category, channel):
    global variable, translate_options, b_tag_bin, save_path
    ROOT.TH1.SetDefaultSumw2(False)
    ROOT.gROOT.SetBatch(True)
    ROOT.gROOT.ProcessLine('gErrorIgnoreLevel = 1001;')
    plotting.setStyle()
    gStyle.SetTitleYOffset(1.4)
    ROOT.gROOT.ForceStyle()

    for variable_bin in variable_bins_ROOT[variable]:
        path = save_path + '/' + variable + '/' + category + '/fit_templates/'
        make_folder_if_not_exists(path)
        plotname = path + channel + '_templates_bin_' + variable_bin + '.png'
        # check if template plots exist already
        if os.path.isfile(plotname):
            continue
        canvas = Canvas(width=700, height=500)
        canvas.SetLeftMargin(0.15)
        canvas.SetBottomMargin(0.15)
        canvas.SetTopMargin(0.05)
        canvas.SetRightMargin(0.05)
        legend = plotting.create_legend(x0=0.7, y1=0.8)
        h_signal = histograms[variable_bin]['signal']
        h_VJets = histograms[variable_bin]['V+Jets']
        h_QCD = histograms[variable_bin]['QCD']

        h_signal.GetXaxis().SetTitle('Lepton #eta')
        h_signal.GetYaxis().SetTitle('Normalised Events')
        h_signal.GetXaxis().SetTitleSize(0.05)
        h_signal.GetYaxis().SetTitleSize(0.05)
        h_signal.SetMinimum(0)
        h_signal.SetMaximum(0.2)
        h_signal.SetLineWidth(2)
        h_VJets.SetLineWidth(2)
        h_QCD.SetLineWidth(2)
        h_signal.SetLineColor(kRed + 1)
        h_VJets.SetLineColor(kBlue)
        h_QCD.SetLineColor(kYellow)
        h_signal.Draw('hist')
        h_VJets.Draw('hist same')
        h_QCD.Draw('hist same')
        legend.AddEntry(h_signal, 'signal', 'l')
        legend.AddEntry(h_VJets, 'V+Jets', 'l')
        legend.AddEntry(h_QCD, 'QCD', 'l')
        legend.Draw()

        mytext = TPaveText(0.5, 0.97, 1, 1.01, "NDC")
        channelLabel = TPaveText(0.18, 0.97, 0.5, 1.01, "NDC")
        if channel == 'electron':
            channelLabel.AddText("e, %s, %s" %
                                 ("#geq 4 jets", b_tag_bins_latex[b_tag_bin]))
        elif channel == 'muon':
            channelLabel.AddText("#mu, %s, %s" %
                                 ("#geq 4 jets", b_tag_bins_latex[b_tag_bin]))
        else:
            channelLabel.AddText("combined, %s, %s" %
                                 ("#geq 4 jets", b_tag_bins_latex[b_tag_bin]))
        mytext.AddText(
            "CMS Preliminary, L = %.1f fb^{-1} at #sqrt{s} = 8 TeV" % (5.8))

        mytext.SetFillStyle(0)
        mytext.SetBorderSize(0)
        mytext.SetTextFont(42)
        mytext.SetTextAlign(13)

        channelLabel.SetFillStyle(0)
        channelLabel.SetBorderSize(0)
        channelLabel.SetTextFont(42)
        channelLabel.SetTextAlign(13)
        mytext.Draw()
        channelLabel.Draw()

        canvas.Modified()
        canvas.Update()
        canvas.SaveAs(plotname)
        canvas.SaveAs(plotname.replace('png', 'pdf'))
Пример #52
0
def generate_toy(n_toy,
                 n_input_mc,
                 config,
                 output_folder,
                 start_at=0,
                 split=1):
    from progressbar import Percentage, Bar, ProgressBar, ETA
    set_root_defaults()
    genWeight = '( EventWeight * {0})'.format(config.luminosity_scale)
    file_name = config.ttbar_category_templates_trees['central']
    make_folder_if_not_exists(output_folder)
    outfile = get_output_file_name(output_folder, n_toy, start_at, n_input_mc,
                                   config.centre_of_mass_energy)

    variable_bins = bin_edges.copy()

    widgets = ['Progress: ', Percentage(), ' ', Bar(), ' ', ETA()]

    with root_open(file_name, 'read') as f_in, root_open(outfile,
                                                         'recreate') as f_out:
        tree = f_in.Get("TTbar_plus_X_analysis/Unfolding/Unfolding")
        n_events = tree.GetEntries()
        print("Number of entries in tree : ", n_events)
        for channel in ['electron', 'muon']:
            print('Channel :', channel)
            gen_selection, gen_selection_vis = '', ''
            if channel is 'muon':
                gen_selection = '( isSemiLeptonicMuon == 1 )'
                gen_selection_vis = '( isSemiLeptonicMuon == 1 && passesGenEventSelection )'
            else:
                gen_selection = '( isSemiLeptonicElectron == 1 )'
                gen_selection_vis = '( isSemiLeptonicElectron == 1 && passesGenEventSelection )'

            selection = '( {0} ) * ( {1} )'.format(genWeight, gen_selection)
            selection_vis = '( {0} ) * ( {1} )'.format(genWeight,
                                                       gen_selection_vis)
            weighted_entries = get_weighted_entries(tree, selection)
            weighted_entries_vis = get_weighted_entries(tree, selection_vis)
            pbar = ProgressBar(widgets=widgets, maxval=n_input_mc).start()

            toy_mc_sets = []
            for variable in ['MET', 'HT', 'ST', 'WPT']:  # variable_bins:
                toy_mc = ToySet(f_out, variable, channel, n_toy)
                toy_mc_sets.append(toy_mc)
            count = 0
            for event in tree:
                # generate 300 weights for each event
                mc_weights = get_mc_weight(weighted_entries, n_toy)
                mc_weights_vis = get_mc_weight(weighted_entries_vis, n_toy)

                if count >= n_input_mc:
                    break
                count += 1
                if count < start_at:
                    continue


#                 weight = event.EventWeight * config.luminosity_scale
#                 # rescale to N input events
#                 weight *= n_events / n_input_mc / split
                weight = 1

                for toy_mc in toy_mc_sets:
                    toy_mc.fill(event, weight, mc_weights, mc_weights_vis)
                if count % 1000 == 1:
                    pbar.update(count)
                    print('Processed {0} events'.format(count))
            pbar.finish()
            for toy_mc in toy_mc_sets:
                toy_mc.write()
    print('Toy MC was saved to file:', outfile)
def plot_fit_results(histograms, category, channel):
    global variable, translate_options, b_tag_bin, save_path
    #ROOT.TH1.SetDefaultSumw2(False)
    ROOT.gROOT.SetBatch(True)
    ROOT.gROOT.ProcessLine('gErrorIgnoreLevel = 1001;')
    plotting.setStyle()
    gStyle.SetTitleYOffset(1.4)
    ROOT.gROOT.ForceStyle()

    for variable_bin in variable_bins_ROOT[variable]:
        path = save_path + '/' + variable + '/' + category + '/fit_results/'
        make_folder_if_not_exists(path)
        plotname = path + channel + '_bin_' + variable_bin + '.png'
        # check if template plots exist already
        if os.path.isfile(plotname):
            continue
        canvas = Canvas(width=700, height=500)
        canvas.SetLeftMargin(0.15)
        canvas.SetBottomMargin(0.15)
        canvas.SetTopMargin(0.05)
        canvas.SetRightMargin(0.05)
        legend = plotting.create_legend(x0=0.7, y1=0.8)
        h_data = histograms[variable_bin]['data']
        h_signal = histograms[variable_bin]['signal']
        h_background = histograms[variable_bin]['background']

        h_data.GetXaxis().SetTitle('Lepton #eta')
        h_data.GetYaxis().SetTitle('Number of Events')
        h_data.GetXaxis().SetTitleSize(0.05)
        h_data.GetYaxis().SetTitleSize(0.05)
        h_data.SetMinimum(0)
        h_data.SetMarkerSize(1)
        h_data.SetMarkerStyle(20)
        gStyle.SetEndErrorSize(20)
        h_data.Draw('P')

        h_signal.SetFillColor(kRed + 1)
        h_background.SetFillColor(kGreen - 3)
        h_signal.SetLineWidth(2)
        h_background.SetLineWidth(2)
        h_signal.SetFillStyle(1001)
        h_background.SetFillStyle(1001)

        mcStack = THStack("MC", "MC")
        mcStack.Add(h_background)
        mcStack.Add(h_signal)

        mcStack.Draw('hist same')
        h_data.Draw('error P same')
        legend.AddEntry(h_data, 'data', 'P')
        legend.AddEntry(h_signal, 'signal', 'F')
        legend.AddEntry(h_background, 'background', 'F')
        legend.Draw()

        mytext = TPaveText(0.5, 0.97, 1, 1.01, "NDC")
        channelLabel = TPaveText(0.18, 0.97, 0.5, 1.01, "NDC")
        if channel == 'electron':
            channelLabel.AddText("e, %s, %s" %
                                 ("#geq 4 jets", b_tag_bins_latex[b_tag_bin]))
        elif channel == 'muon':
            channelLabel.AddText("#mu, %s, %s" %
                                 ("#geq 4 jets", b_tag_bins_latex[b_tag_bin]))
        else:
            channelLabel.AddText("combined, %s, %s" %
                                 ("#geq 4 jets", b_tag_bins_latex[b_tag_bin]))
        mytext.AddText(
            "CMS Preliminary, L = %.1f fb^{-1} at #sqrt{s} = 8 TeV" % (5.8))

        mytext.SetFillStyle(0)
        mytext.SetBorderSize(0)
        mytext.SetTextFont(42)
        mytext.SetTextAlign(13)

        channelLabel.SetFillStyle(0)
        channelLabel.SetBorderSize(0)
        channelLabel.SetTextFont(42)
        channelLabel.SetTextAlign(13)
        mytext.Draw()
        channelLabel.Draw()

        canvas.Modified()
        canvas.Update()
        canvas.SaveAs(plotname)
        canvas.SaveAs(plotname.replace('png', 'pdf'))
	for channel in ['electron', 'muon', 'combined', 'combinedBeforeUnfolding']:  
		if channel != 'combined':continue
		input_file = '{basepath}/{com}TeV/{var}/{ps}/central/xsection_normalised_{channel}_{method}_summary_relative.txt'.format(
			basepath = 	path,
			com = 	com,
			var = variable,
			ps = phase_space,
			channel = channel,
			method = method,
		)
		output_folder = 'plots/systematics/{channel}/{ps}/'.format(
			channel = channel,
			ps = phase_space,
		)
		make_folder_if_not_exists(output_folder)

		systematic_uncertainties = pu.file_to_df(input_file)

		# any group of systematics you want to plot
		l_xsec = []
		l_mc = []
		l_weight = []
		l_met = []
		l_shape = []
		for k in systematic_uncertainties.keys():
			if 'cross_section' in k:  l_xsec.append(k)
			elif 'TTJets_' in k:  l_mc.append(k)
			elif ('Electron' in k or 'Muon' in k or 'PileUp' in k or 'luminosity' in k or 'BJet' in k) and 'En' not in k: l_weight.append(k) 
			elif 'En' in k: l_met.append(k) 
			elif 'JES' in k or 'JER' in k or 'QCD_shape' in k or 'PDF' in k: l_shape.append(k) 
def make_plots_ROOT(histograms, category, save_path, histname, channel):
    global variable, translateOptions, k_value, b_tag_bin, maximum
    ROOT.TH1.SetDefaultSumw2(False)
    ROOT.gROOT.SetBatch(True)
    ROOT.gROOT.ProcessLine('gErrorIgnoreLevel = 1001;')
    plotting.setStyle()
    gStyle.SetTitleYOffset(2.)
    ROOT.gROOT.ForceStyle()
    canvas = Canvas(width=700, height=500)
    canvas.SetLeftMargin(0.18)
    canvas.SetBottomMargin(0.15)
    canvas.SetTopMargin(0.05)
    canvas.SetRightMargin(0.05)
    legend = plotting.create_legend(x0=0.6, y1=0.5)

    hist_data = histograms['unfolded']
    hist_data.GetXaxis().SetTitle(translate_options[variable] + ' [GeV]')
    hist_data.GetYaxis().SetTitle('#frac{1}{#sigma} #frac{d#sigma}{d' +
                                  translate_options[variable] + '} [GeV^{-1}]')
    hist_data.GetXaxis().SetTitleSize(0.05)
    hist_data.GetYaxis().SetTitleSize(0.05)
    hist_data.SetMinimum(0)
    hist_data.SetMaximum(maximum[variable])
    hist_data.SetMarkerSize(1)
    hist_data.SetMarkerStyle(8)
    plotAsym = TGraphAsymmErrors(hist_data)
    plotStatErr = TGraphAsymmErrors(hist_data)

    xsections = read_unfolded_xsections(channel)
    bins = variable_bins_ROOT[variable]
    assert (len(bins) == len(xsections['central']))

    for bin_i in range(len(bins)):
        scale = 1  # / width
        centralresult = xsections['central'][bin_i]
        fit_error = centralresult[1]
        uncertainty = calculateTotalUncertainty(xsections, bin_i)
        uncertainty_total_plus = uncertainty['Total+'][0]
        uncertainty_total_minus = uncertainty['Total-'][0]
        uncertainty_total_plus, uncertainty_total_minus = symmetriseErrors(
            uncertainty_total_plus, uncertainty_total_minus)
        error_up = sqrt(fit_error**2 + uncertainty_total_plus**2) * scale
        error_down = sqrt(fit_error**2 + uncertainty_total_minus**2) * scale
        plotStatErr.SetPointEYhigh(bin_i, fit_error * scale)
        plotStatErr.SetPointEYlow(bin_i, fit_error * scale)
        plotAsym.SetPointEYhigh(bin_i, error_up)
        plotAsym.SetPointEYlow(bin_i, error_down)

    gStyle.SetEndErrorSize(20)
    plotAsym.SetLineWidth(2)
    plotStatErr.SetLineWidth(2)
    hist_data.Draw('P')
    plotStatErr.Draw('same P')
    plotAsym.Draw('same P Z')
    legend.AddEntry(hist_data, 'unfolded', 'P')

    hist_measured = histograms['measured']
    hist_measured.SetMarkerSize(1)
    hist_measured.SetMarkerStyle(20)
    hist_measured.SetMarkerColor(2)
    #hist_measured.Draw('same P')
    #legend.AddEntry(hist_measured, 'measured', 'P')

    for key, hist in sorted(histograms.iteritems()):
        if not 'unfolded' in key and not 'measured' in key:
            hist.SetLineStyle(7)
            hist.SetLineWidth(2)
            # setting colours
            if 'POWHEG' in key or 'matchingdown' in key:
                hist.SetLineColor(kBlue)
            elif 'MADGRAPH' in key or 'matchingup' in key:
                hist.SetLineColor(kRed + 1)
            elif 'MCATNLO' in key or 'scaleup' in key:
                hist.SetLineColor(kGreen - 3)
            elif 'scaledown' in key:
                hist.SetLineColor(kMagenta + 3)
            hist.Draw('hist same')
            legend.AddEntry(hist, translate_options[key], 'l')

    legend.Draw()

    mytext = TPaveText(0.5, 0.97, 1, 1.01, "NDC")
    channelLabel = TPaveText(0.18, 0.97, 0.5, 1.01, "NDC")
    if 'electron' in histname:
        channelLabel.AddText(
            "e, %s, %s, k = %s" %
            ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value))
    elif 'muon' in histname:
        channelLabel.AddText(
            "#mu, %s, %s, k = %s" %
            ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value))
    else:
        channelLabel.AddText(
            "combined, %s, %s, k = %s" %
            ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value))
    mytext.AddText("CMS Preliminary, L = %.1f fb^{-1} at #sqrt{s} = 8 TeV" %
                   (5.8))

    mytext.SetFillStyle(0)
    mytext.SetBorderSize(0)
    mytext.SetTextFont(42)
    mytext.SetTextAlign(13)

    channelLabel.SetFillStyle(0)
    channelLabel.SetBorderSize(0)
    channelLabel.SetTextFont(42)
    channelLabel.SetTextAlign(13)
    mytext.Draw()
    channelLabel.Draw()

    canvas.Modified()
    canvas.Update()

    path = save_path + '/' + variable + '/' + category
    make_folder_if_not_exists(path)
    canvas.SaveAs(path + '/' + histname + '_kv' + str(k_value) + '.png')
    canvas.SaveAs(path + '/' + histname + '_kv' + str(k_value) + '.pdf')
Пример #56
0
    #                  help="use fit inputs instead of fit results")

    (options, args) = parser.parse_args()
    measurement_config = XSectionConfig(options.CoM)
    # caching of variables for shorter access
    translate_options = measurement_config.translate_options
    lumi = measurement_config.new_luminosity
    CoM = measurement_config.centre_of_mass_energy
    electron_histogram_title = 'CMS Preliminary, $\mathcal{L}$ = %.1f fb$^{-1}$ at $\sqrt{s}$ = %d TeV \n e+jets, $\geq$4 jets' % (
        lumi / 1000.0, CoM)
    muon_histogram_title = 'CMS Preliminary, $\mathcal{L}$ = %.1f fb$^{-1}$ at $\sqrt{s}$ = %d TeV \n $\mu$+jets, $\geq$4 jets' % (
        lumi / 1000.0, CoM)

    path_to_JSON = options.path + '/' + str(CoM) + 'TeV/'
    output_folder = options.output_folder + '/%dTeV/' % CoM
    make_folder_if_not_exists(output_folder)
    normalise_to_fit = options.normalise_to_fit
    category = options.category
    met_type = translate_options[options.metType]
    fit_variables = options.fit_variables.replace(',', '_')

    histogram_files = {
        'electron': measurement_config.data_file_electron,
        'muon': measurement_config.data_file_muon,
        'TTJet': measurement_config.ttbar_category_templates[category],
        'V+Jets': measurement_config.VJets_category_templates[category],
        'QCD': measurement_config.
        electron_QCD_MC_file,  # this should also be category-dependent, but unimportant and not available atm
        'SingleTop': measurement_config.SingleTop_category_templates[category]
    }
def plot_central_and_systematics(channel):
    global variable, translate_options, k_value, b_tag_bin, maximum, categories
    ROOT.TH1.SetDefaultSumw2(False)
    ROOT.gROOT.SetBatch(True)
    ROOT.gROOT.ProcessLine('gErrorIgnoreLevel = 1001;')
    plotting.setStyle()
    gStyle.SetTitleYOffset(1.4)
    ROOT.gROOT.ForceStyle()
    canvas = Canvas(width=700, height=500)
    canvas.SetLeftMargin(0.15)
    canvas.SetBottomMargin(0.15)
    canvas.SetTopMargin(0.05)
    canvas.SetRightMargin(0.05)
    legend = plotting.create_legend(x0=0.6, y1=0.5)

    hist_data_central = read_xsection_measurement_results(
        'central', channel)[0]['unfolded']

    hist_data_central.GetXaxis().SetTitle(translate_options[variable] +
                                          ' [GeV]')
    hist_data_central.GetYaxis().SetTitle('#frac{1}{#sigma} #frac{d#sigma}{d' +
                                          translate_options[variable] +
                                          '} [GeV^{-1}]')
    hist_data_central.GetXaxis().SetTitleSize(0.05)
    hist_data_central.GetYaxis().SetTitleSize(0.05)
    hist_data_central.SetMinimum(0)
    hist_data_central.SetMaximum(maximum[variable])
    hist_data_central.SetMarkerSize(1)
    hist_data_central.SetMarkerStyle(20)
    #    plotAsym = TGraphAsymmErrors(hist_data)
    #    plotStatErr = TGraphAsymmErrors(hist_data)
    gStyle.SetEndErrorSize(20)
    hist_data_central.Draw('P')
    #    plotStatErr.Draw('same P')
    #    plotAsym.Draw('same P Z')
    legend.AddEntry(hist_data_central, 'measured (unfolded)', 'P')

    for systematic in categories:
        if systematic != 'central':
            hist_data_systematic = read_xsection_measurement_results(
                systematic, channel)[0]['unfolded']
            hist_data_systematic.SetMarkerSize(0.5)
            hist_data_systematic.SetMarkerStyle(20)
            colour_number = categories.index(systematic) + 1
            if colour_number == 10:
                colour_number = 42
            hist_data_systematic.SetMarkerColor(colour_number)
            hist_data_systematic.Draw('same P')
            legend.AddEntry(hist_data_systematic, systematic, 'P')


#    for central_generator in ['MADGRAPH', 'POWHEG', 'MCATNLO']:
#        hist_MC = read_xsection_measurement_results('central', channel)[0][central_generator]
#        hist_MC.SetLineStyle(7)
#        hist_MC.SetLineWidth(2)
#        #setting colours
#        if central_generator == 'POWHEG':
#            hist_MC.SetLineColor(kBlue)
#        elif central_generator == 'MADGRAPH':
#            hist_MC.SetLineColor(kRed + 1)
#        elif central_generator == 'MCATNLO':
#            hist_MC.SetLineColor(kMagenta + 3)
#        hist_MC.Draw('hist same')
#legend.AddEntry(hist_MC, translate_options[central_generator], 'l')

    legend.Draw()

    mytext = TPaveText(0.5, 0.97, 1, 1.01, "NDC")
    channelLabel = TPaveText(0.18, 0.97, 0.5, 1.01, "NDC")
    if channel == 'electron':
        channelLabel.AddText(
            "e, %s, %s, k_v = %s" %
            ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value))
    elif channel == 'muon':
        channelLabel.AddText(
            "#mu, %s, %s, k_v = %s" %
            ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value))
    else:
        channelLabel.AddText(
            "combined, %s, %s, k_v = %s" %
            ("#geq 4 jets", b_tag_bins_latex[b_tag_bin], k_value))
    mytext.AddText("CMS Preliminary, L = %.1f fb^{-1} at #sqrt{s} = 8 TeV" %
                   (5.8))

    mytext.SetFillStyle(0)
    mytext.SetBorderSize(0)
    mytext.SetTextFont(42)
    mytext.SetTextAlign(13)

    channelLabel.SetFillStyle(0)
    channelLabel.SetBorderSize(0)
    channelLabel.SetTextFont(42)
    channelLabel.SetTextAlign(13)
    mytext.Draw()
    if not channel == 'combination':
        channelLabel.Draw()

    canvas.Modified()
    canvas.Update()

    path = save_path + '/' + variable
    make_folder_if_not_exists(path)
    canvas.SaveAs(path + '/normalised_xsection_' + channel + '_altogether_kv' +
                  str(k_value) + '.png')
    canvas.SaveAs(path + '/normalised_xsection_' + channel + '_altogether_kv' +
                  str(k_value) + '.pdf')