def importHistograms(filepath):

    # dictionary structure for collecting all histograms
    hists = {}

    f_allhists = HistogramGetter.getHistograms(filepath)

    for fs, sp in f_allhists:
        if fs not in hists:
            hists[fs] = {}

        for hkey in f_allhists[(fs, sp)]:
            if hkey not in hists[fs]:
                hists[fs][hkey] = f_allhists[(fs, sp)][hkey].Clone()

            else:
                hists[fs][hkey].Add(f_allhists[(fs, sp)][hkey])

            hname = hists[fs][hkey].GetName()
            if "HTo2X" in hname:
                if "4Mu" in hname:
                    # hkey has the form KEY_HTo2XTo4Mu_mH_mX_cTau
                    matches = Patterns["HTo2XTo4Mu"].match(hname)
                    fs = "4Mu"

                elif "2Mu2J" in hname:
                    # hname has the form KEY_HTo2XTo2Mu2J_mH_mX_cTau
                    matches = Patterns["HTo2XTo2Mu2J"].match(hname)
                    if "reHLT_CosmicSeed" in hname:
                        matches = Patterns[
                            "HTo2XTo2Mu2J_reHLT_CosmicSeed"].match(hname)
                    if "reHLT_ppSeed" in hname:
                        matches = Patterns["HTo2XTo2Mu2J_reHLT_ppSeed"].match(
                            hname)

                if matches:
                    sp = tuple(map(int, matches.group(2, 3, 4)))

                    hname = hname.replace("_{}_{}_{}".format(*sp), "")

                    hists[fs][hkey].SetName(hname)

            else:
                raise NotImplementedError(
                    "Only signal samples supported at this point")

    return hists
import re
import ROOT as R
import DisplacedDimuons.Analysis.Plotter as Plotter
import DisplacedDimuons.Analysis.RootTools as RT
import DisplacedDimuons.Analysis.Selections as Selections
from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr
import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter

TRIGGER = False

# get histograms
HISTS = HistogramGetter.getHistograms(
    '../analyzers/roots/Main/nMinusOnePlots.root')
f = R.TFile.Open('../analyzers/roots/Main/nMinusOnePlots.root')


# make per sample plots
def makePerSamplePlots():
    for ref in HISTS:
        for key in HISTS[ref]:
            if type(ref) == tuple:
                if ref[0] == '4Mu': name = 'HTo2XTo4Mu_'
                elif ref[0] == '2Mu2J': name = 'HTo2XTo2Mu2J_'
                name += SPStr(ref[1])
                if TRIGGER:
                    name = 'Trig-' + name
                lumi = SPLumiStr(ref[0], *ref[1])
                legName = HistogramGetter.PLOTCONFIG['HTo2XTo' +
                                                     ref[0]]['LATEX']
            else:
                name = ref
import re
import ROOT as R
import DisplacedDimuons.Analysis.Plotter as Plotter
import DisplacedDimuons.Analysis.RootTools as RT
from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr
import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter
import DisplacedDimuons.Analysis.PlotterParser as PlotterParser

ARGS = PlotterParser.PARSER.parse_args()

TRIGGER = ARGS.TRIGGER
CUTSTRING = ARGS.CUTSTRING
MCONLY = ARGS.MCONLY

# get histograms
HISTS = HistogramGetter.getHistograms(
    '../analyzers/roots/Main/RecoMuonPlots.root')
f = R.TFile.Open('../analyzers/roots/Main/RecoMuonPlots.root')


# make plots that are per sample
def makePerSamplePlots():
    for ref in HISTS:
        if not type(ref) == tuple: continue
        for key in HISTS[ref]:
            if 'deltaRGR' in key: continue
            if 'VS' in key: continue
            if type(ref) == tuple:
                if ref[0] == '4Mu':
                    name = 'HTo2XTo4Mu_'
                    latexFS = '4#mu'
                elif ref[0] == '2Mu2J':
Beispiel #4
0
import re
import ROOT as R
import DisplacedDimuons.Analysis.Plotter as Plotter
import DisplacedDimuons.Analysis.RootTools as RT
from DisplacedDimuons.Common.Constants import SIGNALPOINTS
from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr
import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter
import DisplacedDimuons.Analysis.PlotterParser as PlotterParser

ARGS = PlotterParser.PARSER.parse_args()

TRIGGER = ARGS.TRIGGER
CUTSTRING = ARGS.CUTSTRING

# get histograms
HISTS = HistogramGetter.getHistograms(
    '../analyzers/roots/Main/SignalVertexFitEffPlots.root')
f = R.TFile.Open('../analyzers/roots/Main/SignalVertexFitEffPlots.root')


# make overlaid plots that combine all signal points
def makeEffPlots(quantity, fs, SP=None):
    HKeys = {
        'Eff': '{}Eff',
        'Den': '{}Den',
    }
    for key in HKeys:
        HKeys[key] = HKeys[key].format(quantity)

    h = {}
    p = {}
    g = {}
Beispiel #5
0
def importHistograms(DISTRIBUTION_SPECS):
    """
    Read and add specified histograms from one or many files.

    Extracts histograms from one or many ROOT files (defined via the argument
    'DISTRIBUTION_SPECS') and adds them to the given HistSpecs objects.

    Parameters
    ----------
    DISTRIBUTION_SPECS : HistSpecs object
        An instance of the HistSpecs class, which defines all the relevant histogram
        properties

    """

    # perform some basic sanity checks
    for el in DISTRIBUTION_SPECS:
        filepath = el.getAttribute("filepath")
        histname_identifier = el.getAttribute("histname_identifier")
        histname_exclude = el.getAttribute("histname_exclude")

        types = ((filepath, str), (histname_identifier, str),
                 (histname_exclude, list))
        for o, t in types:
            if not isinstance(o, t):
                raise Exception(
                    "Invalid type of {}: should be {}, but is {}".format(
                        o, t, type(o)))

        if not os.path.exists(filepath):
            raise Exception("No such file: {}".format(filepath))

    # dictionary structure for collecting the relevant distributions
    hists = {}

    cnt_files = 1
    for el in DISTRIBUTION_SPECS:
        filepath = el.getAttribute("filepath")
        histname_identifier = el.getAttribute("histname_identifier")
        histname_exclude = el.getAttribute("histname_exclude")

        print("[{}/{}] Reading file {}...".format(cnt_files,
                                                  len(DISTRIBUTION_SPECS),
                                                  filepath))

        f_allhists = HistogramGetter.getHistograms(filepath)

        histogram = None

        for dataset in f_allhists:
            selected_hists_names = getHistNames(f_allhists,
                                                dataset,
                                                histname_identifier,
                                                exclude=histname_exclude)
            print("hist names: {}".format(selected_hists_names))

            if len(selected_hists_names) > 1:
                raise Exception(
                    "Ambiguous histogram identifier: {} would select the following {} histograms: {}"
                    .format(histname_identifier, len(selected_hists_names),
                            '\n'.join(selected_hists_names)))

            for key in selected_hists_names:
                if histogram is None:
                    histogram = f_allhists[dataset][key].Clone()
                else:
                    histogram.Add(f_allhists[dataset][key])

        if histogram:
            print("\tImported histogram {}".format(histogram.GetName()))
        else:
            print("\tNo histograms found.")

        # prepare the histogram
        RT.addFlows(histogram)

        if el.getAttribute("histogram") is not None:
            print(
                "Warning: Histogram already exists in the HistSpecs object and will be overwritten"
            )

        # add the actual histrogram to the corresponding HistSpecs object
        el.setAttribute("histogram", histogram)

        cnt_files += 1
        del f_allhists
def collectHistograms(file_specs, hist_patterns_and_excludes):

    # structure for storing the histograms
    h = {
        f: {
            "appearance": app,
            "descr": d,
            "hists": {}
        }
        for app, f, d in file_specs
    }

    # lists of keys for each file (for consistency checks)
    lists_of_keys = {f: [] for __, f, __ in file_specs}

    cnt = 1
    for __, f, __ in file_specs:
        print("[{}/{}] Reading file {}...".format(cnt, len(file_specs), f))
        cnt += 1

        f_hists = HistogramGetter.getHistograms(f)

        for pattern, exclude in hist_patterns_and_excludes:

            for dataset in f_hists:
                selected_hists_names = getHistNames(f_hists,
                                                    dataset,
                                                    pattern,
                                                    exclude=exclude)

                for key in selected_hists_names:
                    if key not in h[f]["hists"]:
                        h[f]["hists"][key] = f_hists[dataset][key].Clone()
                    else:
                        h[f]["hists"][key].Add(f_hists[dataset][key])

                    lists_of_keys[f].append(key)

        print("\tImported {} histograms".format(len(h[f]["hists"].keys())))

    # check whether all the histograms exist in all the files
    found_inconsistency = False
    for i, f in enumerate(lists_of_keys):
        for j in range(len(lists_of_keys.keys())):
            if i == j:
                continue

            for key in lists_of_keys[f]:
                if key not in lists_of_keys[lists_of_keys.keys()[j]]:
                    print("[WARNING] Inconsistency in file contents. "
                          "Histogram {} not present in file {}".format(
                              key,
                              lists_of_keys.keys()[j]))
                    found_inconsistency = True

    if not found_inconsistency:
        print("[INFO] Consistency checks passed")
    else:
        print("[WARNING] Consistency checks failed")

    return h
    "pTdiff": (-1.1, 10.0),
    "d0": (0.0, 200),
    "L1pTres": (-1.0, 8.0),
    "L2pTres": (-1.0, 8.0),
    "dimVtxChi2": (0.0, 60.0),
    "dimLxySig": (0.0, 230.0),
    "chi2": (0.0, 30.0),
    "pTSig": (0.0, 2.0),
    "nStations": (0.0, 10.0),
    "nCSCDTHits": (10.0, 60.0),
    "chargeprod": (-1.0, 2.0),
    "charge": (-1.0, 2.0),
}

HISTS = HistogramGetter.getHistograms(
    "/afs/cern.ch/work/s/stempl/private/DDM/cosmics-studies/simulation-validation/Cosmics2016_UGMT-bottomOnly_HLT-ppSeed.root"
)


def makePerSamplePlots(selection=None):
    rebinning_exceptions = ("pTdiff", "nCSCDTHits")

    h = {}
    p = {}
    for dataset in HISTS:
        if selection is not None:
            selected_hists_names = getHistNames(dataset, *selection)
        else:
            selected_hists_names = HISTS[dataset]

        for key in selected_hists_names:
import re
import ROOT as R
from ROOT import gStyle, gPad
import DisplacedDimuons.Analysis.Plotter as Plotter
import DisplacedDimuons.Analysis.RootTools as RT
from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr
import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter

TRIGGER = True
PRINTINTEGRALS = False

# get histograms
HISTS = HistogramGetter.getHistograms(
    '../analyzers/roots/muonQualityStudies_HTo2XTo2Mu2J_1000_150_1000.root')

#HISTS = HistogramGetter.getHistograms('../analyzers/roots/muonQualityStudies_HTo2XTo2Mu2J_125_20_1300.root')
#f = R.TFile.Open('../analyzers/roots/muonQualityStudies_HTo2XTo2Mu2J_1000_150_1000.root')


# make plots that are per sample
def makePerSamplePlots():
    for ref in HISTS:
        print "ref: ,", ref
        if type(ref) == tuple:
            if ref[0] == '4Mu':
                name = 'HTo2XTo4Mu_'
                latexFS = '4#mu'
            elif ref[0] == '2Mu2J':
                name = 'HTo2XTo2Mu2J_'
                latexFS = '2#mu2j'
            if TRIGGER:
import re
import ROOT as R
import DisplacedDimuons.Analysis.Plotter as Plotter
import DisplacedDimuons.Analysis.RootTools as RT
import DisplacedDimuons.Analysis.Selections as Selections
from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr
import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter

TRIGGER = False

# get histograms
HISTS = HistogramGetter.getHistograms('../analyzers/roots/Main/TailCumulativePlots.root')
f = R.TFile.Open('../analyzers/roots/Main/TailCumulativePlots.root')

# make per sample plots
def makePerSamplePlots():
    for ref in HISTS:
        for key in HISTS[ref]:
            if type(ref) == tuple:
                if ref[0] == '4Mu': name = 'HTo2XTo4Mu_'
                elif ref[0] == '2Mu2J' : name = 'HTo2XTo2Mu2J_'
                name += SPStr(ref[1])
                if TRIGGER:
                    name = 'Trig-'+name
                lumi = SPLumiStr(ref[0], *ref[1])
                legName = HistogramGetter.PLOTCONFIG['HTo2XTo'+ref[0]]['LATEX']
            else:
                name = ref
                lumi = ref
                legName = HistogramGetter.PLOTCONFIG[ref]['LATEX']
Beispiel #10
0
import re
import ROOT as R
import DisplacedDimuons.Analysis.Plotter as Plotter
import DisplacedDimuons.Analysis.RootTools as RT
from DisplacedDimuons.Common.Constants import SIGNALPOINTS
from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr
import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter
import DisplacedDimuons.Analysis.PlotterParser as PlotterParser

ARGS = PlotterParser.PARSER.parse_args()
TRIGGER = ARGS.TRIGGER

# get histograms
HISTS = HistogramGetter.getHistograms(
    '../analyzers/roots/Main/SignalRecoEffPlots.root')
f = R.TFile.Open('../analyzers/roots/Main/SignalRecoEffPlots.root')


# make overlaid plots that combine all signal points
def makeEffPlots(quantity, fs, SP=None):
    HKeys = {
        'DSA_Eff': 'DSA_{}Eff',
        'RSA_Eff': 'RSA_{}Eff',
        'REF_Eff': 'REF_{}Eff',
        'REF_Den': 'REF_{}Den',
        'Den': '{}Den',
        #       'Extra'         : '{}Extra'        ,
        'DSA_ChargeEff': 'DSA_{}ChargeEff',
        'RSA_ChargeEff': 'RSA_{}ChargeEff',
        'REF_ChargeEff': 'REF_{}ChargeEff',
        'DSA_ChargeDen': 'DSA_{}ChargeDen',
def makeSystematicsPlots(RESOLUTIONVARIABLE,
                         data_filepath,
                         MC_filepath,
                         d0intervals,
                         strategy="max"):
    HISTS_data = HistogramGetter.getHistograms(data_filepath)
    HISTS_MC = HistogramGetter.getHistograms(MC_filepath)

    # make sure that all given d0 interval limits are actually floats
    d0intervals = [(float(l), float(u)) for l, u in d0intervals]

    data_hists, data_d0hists = importHistogram(
        HISTS_data,
        RESOLUTIONVARIABLE,
        includes=["DSA_lowerLeg", RESOLUTIONVARIABLE],
        excludes=["EffNum", "EffDen"],
    )
    MC_hists, MC_d0hists = importHistogram(
        HISTS_MC,
        RESOLUTIONVARIABLE,
        includes=["DSA_lowerLeg", RESOLUTIONVARIABLE],
        excludes=["EffNum", "EffDen"],
    )

    # define a set of d0 bins for the plots
    d0intervals = [(i, i + 5.) for i in np.arange(0., 30., 5.)]
    d0intervals += [(i, i + 10.) for i in np.arange(30., 100., 10.)]

    def varyRebinningParameter(number_of_rebins_range=range(11)):
        plot_data = {}

        for hists, histtypes in (
            (data_hists, "CosmicsData"),
            (MC_hists, "SignalMC"),
        ):

            plot_data[histtypes] = []

            for h in hists:
                # x coordinates are defined by the varying rebin parameter
                for x_val in number_of_rebins_range:
                    h_vary = h.Clone()
                    h_autoRebin = h.Clone()
                    auto_rebin_parameter = autoRebin(h_autoRebin)

                    # y coordinates are defined by the d0 bins
                    d0min, d0max = extractD0Values(h_vary.GetName())
                    if (d0min, d0max) not in d0intervals: continue
                    y_val = d0min

                    if x_val > 0:
                        h_vary.Rebin(2 * x_val)
                        # z coordinates are defined by the peak position value
                        z_val = h_vary.GetXaxis().GetBinCenter(
                            h_vary.GetMaximumBin())
                    else:
                        # z coordinates are defined by the peak position value
                        z_val = getPeakPosition(h_vary, strategy=strategy)[0]
                        # z_val = h_vary.GetXaxis().GetBinCenter(h_vary.GetMaximumBin())

                    plot_data[histtypes].append(
                        (x_val, y_val, z_val, auto_rebin_parameter))

        return plot_data

    def varyRebinningErrorFraction(fraction_range=np.arange(0, 0.3, 0.01)):
        plot_data = {}

        for hists, histtypes in (
            (data_hists, "CosmicsData"),
            (MC_hists, "SignalMC"),
        ):
            plot_data[histtypes] = []

            for h in hists:
                # x coordinates are defined by the varying fraction parameter
                for x_val in fraction_range:
                    h_vary = h.Clone()

                    # y coordinates are defined by the d0 bins
                    d0min, d0max = extractD0Values(h_vary.GetName())
                    if (d0min, d0max) not in d0intervals: continue
                    y_val = d0min

                    # z coordinates are defined by the peak position value
                    autoRebin(h_vary, error_fraction=x_val)
                    z_val = getPeakPosition(h_vary, strategy=strategy)[0]
                    # z_val = h_vary.GetXaxis().GetBinCenter(h_vary.GetMaximumBin())

                    plot_data[histtypes].append((x_val, y_val, z_val, None))

        return plot_data

    def varyRebinningNeighbors(nNeighbors_range=range(1, 11)):
        plot_data = {}

        for hists, histtypes in (
            (data_hists, "CosmicsData"),
            (MC_hists, "SignalMC"),
        ):
            plot_data[histtypes] = []

            for h in hists:
                # x coordinates are defined by the varying nNeighbors parameter
                for x_val in nNeighbors_range:
                    h_vary = h.Clone()

                    # y coordinates are defined by the d0 bins
                    d0min, d0max = extractD0Values(h_vary.GetName())
                    if (d0min, d0max) not in d0intervals: continue
                    y_val = d0min

                    # z coordinates are defined by the peak position value
                    autoRebin(h_vary, neighboring_bins=x_val)
                    z_val = getPeakPosition(h_vary, strategy=strategy)[0]
                    # z_val = h_vary.GetXaxis().GetBinCenter(h_vary.GetMaximumBin())

                    plot_data[histtypes].append((x_val, y_val, z_val, None))

        return plot_data

    def make2DPlot(
        RESOLUTIONVARIABLE,
        data,
        name="",
        title="",
        lumi="",
        xlabel="",
        ylabel="",
        zlabel="",
        nbinsx=10,
        xrange_min=0,
        xrange_max=10,
        nbinsy=10,
        yrange_min=0,
        yrange_max=100,
        vline=None,
    ):

        hist2D = R.TH2F(name, title, nbinsx, xrange_min, xrange_max, nbinsy,
                        yrange_min, yrange_max)
        hist2D.GetXaxis().SetTitle(xlabel)
        hist2D.GetYaxis().SetTitle(ylabel)
        hist2D.GetZaxis().SetTitle(zlabel)

        # initialize histogram bins
        for bx in range(1, hist2D.GetNbinsX() + 1):
            for by in range(1, hist2D.GetNbinsY() + 1):
                # initialize with value below the z axis minimum in order to
                # make empty bins appear transparent (requires z axis range to be set
                # explicitly)
                hist2D.SetBinContent(hist2D.GetBin(bx, by), -999)

        for d in data:
            hist2D.SetBinContent(hist2D.FindBin((d[0]), (d[1])), d[2])

        # fill in the blanks
        for bx in range(1, hist2D.GetNbinsX() + 1):
            for by in range(1, hist2D.GetNbinsY() + 1):
                if hist2D.GetBinContent(hist2D.GetBin(bx, by)) == -999:
                    hist2D.SetBinContent(hist2D.GetBin(bx, by),
                                         hist2D.GetBinContent(bx, by - 1))

        canvas = Plotter.Canvas(lumi=lumi)
        canvas.addMainPlot(Plotter.Plot(hist2D, "", "colz", "colz"))

        pave = []
        for d in data:
            if d[3] is None: continue

            marker_bin_xcoord = hist2D.GetXaxis().GetBinCenter(
                hist2D.GetXaxis().FindBin(d[3]))
            marker_bin_ycoord = hist2D.GetYaxis().GetBinCenter(
                hist2D.GetYaxis().FindBin(d[1]))

            if marker_bin_ycoord <= 30:
                pave.append(
                    R.TPaveText(marker_bin_xcoord - 0.5,
                                marker_bin_ycoord - 2.5,
                                marker_bin_xcoord + 0.5,
                                marker_bin_ycoord + 2.5))
            else:
                pave.append(
                    R.TPaveText(marker_bin_xcoord - 0.5,
                                marker_bin_ycoord - 2.5,
                                marker_bin_xcoord + 0.5,
                                marker_bin_ycoord + 7.5))
            pave[-1].SetTextAlign(13)
            pave[-1].SetTextFont(42)
            pave[-1].SetMargin(0)
            pave[-1].SetFillStyle(0)
            pave[-1].SetFillColor(0)
            pave[-1].SetLineStyle(0)
            pave[-1].SetLineColor(0)
            pave[-1].SetBorderSize(1)
            pave[-1].AddText(0.5, 0.5, "")
            pave[-1].Draw()

        if vline:
            l = R.TLine(vline, yrange_min, vline, yrange_max)
            l.SetLineColor(R.kWhite)
            l.SetLineWidth(1)
            l.Draw()

        hist2D.GetZaxis().SetRangeUser(-1.0, 0.2)

        canvas.mainPad.SetRightMargin(0.16)

        canvas.finishCanvas()
        canvas.save("pdfs/test_{}_{}_{}_{}".format(
            RESOLUTIONVARIABLE, name, lumi.replace(" ", ""),
            "CosmicSeed" if IS_COSMIC_SEED else "ppSeed"),
                    extList=[".pdf", ".root"])
        canvas.deleteCanvas()

    for datatype, lumi in (
        ("CosmicsData", "2016 Cosmics data"),
        ("SignalMC", "2016 MC signal samples"),
    ):
        varyRebinningParameter_data = varyRebinningParameter()
        make2DPlot(
            RESOLUTIONVARIABLE,
            varyRebinningParameter_data[datatype],
            name="varyRebinningParameter",
            lumi=lumi,
            xlabel="number of rebinning steps",
            ylabel="d0 [cm]",
            zlabel="position of maximum bin"
            if "L1pTres" in RESOLUTIONVARIABLE else "fitted resolution mean",
            nbinsx=10,
            xrange_min=0,
            xrange_max=10,
            nbinsy=20,
            yrange_min=0,
            yrange_max=100,
        )

        varyRebinningErrorFraction_data = varyRebinningErrorFraction()
        make2DPlot(
            RESOLUTIONVARIABLE,
            varyRebinningErrorFraction_data[datatype],
            name="varyRebinningErrorFraction",
            lumi=lumi,
            xlabel="bin error fraction (rebinning)",
            ylabel="d0 [cm]",
            zlabel="position of maximum bin"
            if "L1pTres" in RESOLUTIONVARIABLE else "fitted resolution mean",
            nbinsx=30,
            xrange_min=0,
            xrange_max=0.3,
            nbinsy=20,
            yrange_min=0,
            yrange_max=100,
            vline=0.05,
        )

        varyRebinningNeighbors_data = varyRebinningNeighbors()
        make2DPlot(
            RESOLUTIONVARIABLE,
            varyRebinningNeighbors_data[datatype],
            name="varyRebinningNeighbors",
            lumi=lumi,
            xlabel="number of neighbors (rebinning)",
            ylabel="d0 [cm]",
            zlabel="position of maximum bin"
            if "L1pTres" in RESOLUTIONVARIABLE else "fitted resolution mean",
            nbinsx=9,
            xrange_min=1,
            xrange_max=10,
            nbinsy=20,
            yrange_min=0,
            yrange_max=100,
            vline=6,
        )
def makeResolutionVsD0Plots(
    RESOLUTIONVARIABLE,
    data_filepath,
    MC_filepath,
    d0intervals,
    strategy="max",
):
    HISTS_data = HistogramGetter.getHistograms(data_filepath)
    HISTS_MC = HistogramGetter.getHistograms(MC_filepath)

    # make sure that all given d0 interval limits are actually floats
    d0intervals = [(float(l), float(u)) for l, u in d0intervals]

    h_ylabel_value, h_ylabel_width, h_ylabel_fraction_in_tail, h_ylabel_quality, h_xlabel, canvas_text = getLabels(
        RESOLUTIONVARIABLE)

    data_hists, data_d0hists = importHistogram(
        HISTS_data,
        RESOLUTIONVARIABLE,
        includes=["DSA_lowerLeg", RESOLUTIONVARIABLE],
        excludes=["EffNum", "EffDen"],
    )
    MC_hists, MC_d0hists = importHistogram(
        HISTS_MC,
        RESOLUTIONVARIABLE,
        includes=["DSA_lowerLeg", RESOLUTIONVARIABLE],
        excludes=["EffNum", "EffDen"],
    )

    resVsD0_data = generateGraphData(data_hists,
                                     data_d0hists,
                                     d0intervals=d0intervals,
                                     strategy=STRATEGY)
    resVsD0_MC = generateGraphData(MC_hists,
                                   MC_d0hists,
                                   d0intervals=d0intervals,
                                   strategy=STRATEGY)

    canvas = Plotter.Canvas(lumi="2016 MC vs. Cosmics data")

    # data distributions and specifications
    graph_data = generateGraph(resVsD0_data, distribution="res_val")
    canvas.addMainPlot(Plotter.Plot(graph_data, legend_name_data, "elp", "pe"))
    graph_data.SetLineColor(R.kBlue if IS_COSMIC_SEED else R.kRed)
    graph_data.SetMarkerColor(R.kBlue if IS_COSMIC_SEED else R.kRed)

    # data width distribution and specifications
    graph_data_width = generateGraph(resVsD0_data,
                                     distribution="res_width",
                                     error_axes="")
    if STRATEGY == "max":
        canvas.addMainPlot(
            Plotter.Plot(graph_data_width, legend_name_data + " std. dev.",
                         "elp", "pe"))
    elif STRATEGY == "gaussfit":
        canvas.addMainPlot(
            Plotter.Plot(graph_data_width, legend_name_data + " FWHM", "elp",
                         "pe"))

    graph_data_width.SetLineColor(R.kBlue if IS_COSMIC_SEED else R.kRed)
    graph_data_width.SetMarkerColor(R.kBlue if IS_COSMIC_SEED else R.kRed)
    graph_data_width.SetMarkerStyle(R.kMultiply)

    # MC distribution and specifications
    graph_MC = generateGraph(resVsD0_MC, distribution="res_val")
    canvas.addMainPlot(Plotter.Plot(graph_MC, legend_name_MC, "elp", "pe"))
    graph_MC.SetLineColor(R.kCyan + 1 if IS_COSMIC_SEED else R.kOrange - 3)
    graph_MC.SetMarkerColor(R.kCyan + 1 if IS_COSMIC_SEED else R.kOrange - 3)

    # MC width distributions and specifications
    graph_MC_width = generateGraph(resVsD0_MC,
                                   distribution="res_width",
                                   error_axes="")
    canvas.addMainPlot(
        Plotter.Plot(graph_MC_width, legend_name_MC + " std. dev.", "elp",
                     "pe"))
    # canvas.addMainPlot(Plotter.Plot(graph_MC_width, legend_name_MC + " FWHM", "elp", "pe"))
    graph_MC_width.SetLineColor(R.kCyan + 1 if IS_COSMIC_SEED else R.kOrange -
                                3)
    graph_MC_width.SetMarkerColor(R.kCyan +
                                  1 if IS_COSMIC_SEED else R.kOrange - 3)
    graph_MC_width.SetMarkerStyle(R.kMultiply)

    # add horizontal line at zero
    zero_line_horizontal = R.TLine(resVsD0_data["d0_min"][0], 0.0,
                                   resVsD0_data["d0_max"][-1], 0.0)
    R.SetOwnership(zero_line_horizontal, 0)
    zero_line_horizontal.SetLineColor(R.kGray)
    zero_line_horizontal.SetLineStyle(2)
    zero_line_horizontal.Draw()

    # set axis titles
    canvas.firstPlot.GetXaxis().SetTitle(h_xlabel)
    canvas.firstPlot.GetYaxis().SetTitle("Resolution peak parameters")

    # set axis ranges
    if "L2pTres" in RESOLUTIONVARIABLE:
        if IS_COSMIC_SEED:
            canvas.firstPlot.GetYaxis().SetRangeUser(-0.1, 0.3)
        else:
            canvas.firstPlot.GetYaxis().SetRangeUser(-0.6, 1.5)
    elif "L1pTres" in RESOLUTIONVARIABLE:
        canvas.firstPlot.GetYaxis().SetRangeUser(-1.1, 1.5)

    # create legend
    canvas.makeLegend(lWidth=0.37, pos="tr", fontscale=0.85)
    canvas.legend.resizeHeight()

    if canvas_text:
        pavetext = R.TPaveText(0.18, 0.78, 0.5, 0.9, "NDCNB")
        pavetext.SetTextAlign(13)
        pavetext.SetTextFont(42)
        pavetext.SetMargin(0)
        pavetext.SetFillStyle(0)
        pavetext.SetFillColor(0)
        pavetext.SetLineStyle(0)
        pavetext.SetLineColor(0)
        pavetext.SetBorderSize(0)
        pavetext.AddText(
            0.0,
            0.0,
            canvas_text +
            ",  {} seed".format("cosmic" if IS_COSMIC_SEED else "pp"),
        )
        pavetext.Draw()

    canvas.finishCanvas()
    canvas.save(
        "pdfs/" + FILENAME_TEMPLATE.format(
            RESOLUTIONVARIABLE=RESOLUTIONVARIABLE,
            SEEDING="CosmicSeed" if IS_COSMIC_SEED else "ppSeed"),
        extList=[".pdf", ".root"],
    )
    canvas.deleteCanvas()