Exemple #1
0
def test_recursive_getattr_fail(logging_mixin: Any, mocker: Any) -> None:
    """ Test for failure of recursive getattr.

    It will fail the same was as the standard getattr.
    """
    obj = mocker.MagicMock(spec=["sole_attr"])

    with pytest.raises(AttributeError) as exception_info:
        utils.recursive_getattr(obj, "nonexistent_attr")
    assert "nonexistent_attr" in exception_info.value.args[0]
Exemple #2
0
def merge_pt_hard_binned_analyses(analyses: Iterator[Tuple[Any, analysis_objects.JetHBase]],
                                  hist_attribute_name: str,
                                  output_analysis_object: Any) -> None:
    """ Merge together all scaled histograms.

    Args:
        analyses: Pt hard dependent analyses which should be merged together.
        hist_attribute_name: Name of the attribute where the hist is stored.
        output_analysis_object: Object where the histogram will be stored under ``hist_attribute_name``.
    Returns:
        None
    """
    output_hist: Hist = None
    for _, analysis in analyses:
        input_hist = utils.recursive_getattr(analysis, hist_attribute_name)
        if output_hist is None:
            # NOTE: We don't need to set a new name - it will be fine with the same name.
            output_hist = input_hist.Clone()
            # Reset so we can just Add() all hists without worrying which hist is being processed
            output_hist.Reset()
            # NOTE: Sumw2 is kept even after resetting.

        output_hist.Add(input_hist)

    # Save the final result
    utils.recursive_setattr(output_analysis_object, hist_attribute_name, output_hist)
Exemple #3
0
def test_recursive_setattr(setup_recursive_setattr: Any) -> None:
    """ Test setting an attribute with recursive setattr. """
    # Setup
    obj, path = setup_recursive_setattr

    # Set the attribute and check the result
    new_value = "new value"
    utils.recursive_setattr(obj, path, new_value)
    assert utils.recursive_getattr(obj, path) == new_value
Exemple #4
0
def _get_hists_from_analysis_objects(analyses: Mapping[str, analysis_objects.JetHBase],
                                     hist_attribute_name: str) -> Dict[str, Hist]:
    """ Retrieve histograms from an analysis object stored under specified attribute names.

    Args:
        analyses: Analysis objects to be processed according to values in this pt hard bin.
        hist_attribute_name: Names of the attributes to retrieve the histograms.
    Returns:
        Extracted histograms.
    """
    hists: Dict[str, Hist] = {}
    for key, analysis in analyses.items():
        hists[key] = utils.recursive_getattr(analysis, hist_attribute_name)
    return hists
Exemple #5
0
def test_recursive_getattr(logging_mixin, mocker, path, expected):
    """ Tests for recursive getattr. """
    # Setup mock objects from which we will recursively grab attributes
    mock_obj1 = mocker.MagicMock(spec=["standard_attr", "attr1"])
    mock_obj2 = mocker.MagicMock(spec=["attr3"])
    mock_obj3 = mocker.MagicMock(spec=["my_attr"])
    mock_obj1.standard_attr = "standard_attr_value"
    mock_obj1.attr1 = mock_obj2
    mock_obj2.attr3 = mock_obj3
    mock_obj3.my_attr = "recursive_attr_value"

    # For convenience
    obj = mock_obj1
    # Check the returned value
    assert expected == utils.recursive_getattr(obj, path)
def _plot_response_spectra_with_ROOT(
        plot_labels: plot_base.PlotLabels, output_name: str,
        merged_analysis: analysis_objects.JetHBase, pt_hard_analyses: Analyses,
        hist_attribute_name: str, colors: Sequence[Tuple[float, float,
                                                         float]]) -> None:
    """ Plot 1D response spectra with ROOT.

    Args:
        plot_labels: Labels for the plot.
        output_name: Name under which the plot should be stored.
        merged_analysis: Full merged together analysis object.
        pt_hard_analyses: Pt hard dependent analysis objects to be plotted.
        hist_attribute_name: Name of the attribute under which the histogram is stored.
        colors: List of colors to be used for plotting the pt hard spectra.
    """
    # Setup
    canvas = ROOT.TCanvas("canvas", "canvas")
    canvas.SetLogy(True)
    # Legend
    legend = ROOT.TLegend(0.37, 0.55, 0.9, 0.9)
    legend.SetHeader(r"p_{\mathrm{T}}\:\mathrm{bins}", "C")
    # Increase text size
    legend.SetTextSize(0.025)
    # Use two columns because we have a lot of entries.
    legend.SetNColumns(2)
    # Remove the legend border
    legend.SetBorderSize(0)
    # Make the legend transparent
    legend.SetFillStyle(0)

    # First, we plot the merged analysis. This is the sum of the various pt hard bin contributions.
    merged_hist = utils.recursive_getattr(merged_analysis, hist_attribute_name)
    # Apply axis labels (which must be set on the hist)
    plot_labels.apply_labels(merged_hist)
    # Style the merged hist to ensure that it is possible to see the points
    merged_hist.SetMarkerStyle(ROOT.kFullCircle)
    merged_hist.SetMarkerSize(1)
    merged_hist.SetMarkerColor(ROOT.kBlack)
    merged_hist.SetLineColor(ROOT.kBlack)
    # Ensure that the max is never beyond 300 for better presentation.
    max_limit = merged_hist.GetXaxis().GetXmax()
    if max_limit > 300:
        max_limit = 300
    merged_hist.GetXaxis().SetRangeUser(0, max_limit)

    # Label and draw
    legend.AddEntry(merged_hist, "Merged")
    merged_hist.Draw("same")

    # Now, we plot the pt hard dependent hists
    for i, ((key_index, analysis),
            color) in enumerate(zip(pt_hard_analyses.items(), colors)):
        # Setup
        color = ROOT.TColor.GetColor(*color)
        # Determine the proper label.
        label = labels.pt_range_string(
            pt_bin=key_index.pt_hard_bin,
            lower_label="T",
            upper_label="hard",
            only_show_lower_value_for_last_bin=True,
        )

        # Retrieve and style the hist
        hist = utils.recursive_getattr(analysis, hist_attribute_name)
        hist.SetMarkerStyle(ROOT.kFullCircle + i)
        hist.SetMarkerSize(1)
        hist.SetMarkerColor(color)
        hist.SetLineColor(color)

        # Label and draw
        legend.AddEntry(hist, labels.use_label_with_root(label))
        hist.Draw("same")

    # Final presentation settings
    legend.Draw()

    # Save and cleanup
    output_name += "_ROOT"
    plot_base.save_plot(merged_analysis.output_info, canvas, output_name)
def _plot_response_spectra_with_matplotlib(
        plot_labels: plot_base.PlotLabels, output_name: str,
        merged_analysis: analysis_objects.JetHBase, pt_hard_analyses: Analyses,
        hist_attribute_name: str, colors: Sequence[Tuple[float, float,
                                                         float]]) -> None:
    """ Plot 1D response spectra with matplotlib.

    Args:
        plot_labels: Labels for the plot.
        output_name: Name under which the plot should be stored.
        merged_analysis: Full merged together analysis object.
        pt_hard_analyses: Pt hard dependent analysis objects to be plotted.
        hist_attribute_name: Name of the attribute under which the histogram is stored.
        colors: List of colors to be used for plotting the pt hard spectra.
    """
    # Setup
    fig, ax = plt.subplots(figsize=(8, 6))
    plot_labels.apply_labels(ax)

    # First, we plot the merged analysis. This is the sum of the various pt hard bin contributions.
    merged_hist = utils.recursive_getattr(merged_analysis, hist_attribute_name)
    merged_hist = histogram.Histogram1D.from_existing_hist(merged_hist)
    ax.errorbar(
        merged_hist.x,
        merged_hist.y,
        yerr=merged_hist.errors,
        label="Merged",
        color="black",
        marker=".",
        linestyle="",
    )

    # Now, we plot the pt hard dependent hists
    for (key_index, analysis), color in zip(pt_hard_analyses.items(), colors):
        # Determine the proper label.
        label = labels.pt_range_string(
            pt_bin=key_index.pt_hard_bin,
            lower_label="T",
            upper_label="hard",
            only_show_lower_value_for_last_bin=True,
        )

        # Plot the histogram.
        hist = utils.recursive_getattr(analysis, hist_attribute_name)
        h = histogram.Histogram1D.from_existing_hist(hist)
        ax.errorbar(
            h.x,
            h.y,
            yerr=h.errors,
            label=label,
            color=color,
            marker=".",
            linestyle="",
        )

    # Final presentation settings
    # Ensure that the max is never beyond 300 for better presentation.
    max_limit = np.max(merged_hist.x)
    if max_limit > 300:
        max_limit = 300
    ax.set_xlim(0, max_limit)
    ax.set_yscale("log")
    ax.legend(loc="best", frameon=False)
    fig.tight_layout()

    # Save and cleanup
    output_name += "_mpl"
    plot_base.save_plot(merged_analysis.output_info, fig, output_name)
    plt.close(fig)
Exemple #8
0
def test_recursive_getattr_defualt_value(logging_mixin: Any,
                                         mocker: Any) -> None:
    """ Test for retrieving a default value with getattr. """
    obj = mocker.MagicMock(spec=["sole_attr"])
    assert "default_value" == utils.recursive_getattr(obj, "nonexistent_attr",
                                                      "default_value")