-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #72 from kreczko/kreczko-fast-plotter-1
Towards 1.0.0 alpha 0
- Loading branch information
Showing
5 changed files
with
144 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
""" Features for version 1 """ | ||
from typing import Any, Dict, List | ||
import uproot | ||
|
||
from .hist_collections import EfficiencyHistCollection | ||
|
||
|
||
def create_collection(name, config, style): | ||
LOOKUP = { | ||
"efficiency": EfficiencyHistCollection, | ||
} | ||
collection_class = LOOKUP[config["type"]] | ||
# return collection_class(**config) | ||
return collection_class( | ||
name=name, | ||
title=config["title"], | ||
style=style, | ||
) | ||
|
||
|
||
def _workaround_uproot_issue38(): | ||
# workaround for issue reading TEfficiency | ||
# https://github.com/scikit-hep/uproot5/issues/38 | ||
import skhep_testdata | ||
with uproot.open(skhep_testdata.data_path("uproot-issue38c.root")) as fp: | ||
hist = fp["TEfficiencyName"] | ||
# now all TEfficiency objects should be readable | ||
return hist | ||
|
||
|
||
def read_histogram_file(input_file, histname): | ||
with uproot.open(input_file) as fp: | ||
hist = fp[histname] | ||
# TODO: use filter_dict to get > 1 hist | ||
return hist | ||
|
||
|
||
def make_plots(plot_config: Dict[str, Any], input_files: List[str], output_dir: str): | ||
_workaround_uproot_issue38() | ||
input_file = input_files[0] | ||
|
||
plotter_version = plot_config.pop("plotter-version", "0") | ||
styles = plot_config.pop("styles", {}) | ||
collections = plot_config.pop("collections", {}) | ||
named_styles = {} | ||
for style in styles: | ||
named_styles[style["name"]] = style | ||
|
||
for name, config in collections.items(): | ||
# TODO: needs to me safer | ||
style = named_styles[config.pop("style")] | ||
collection = create_collection(name, config, style) | ||
sources = config.pop("sources") | ||
for source in sources: | ||
label = source.pop("label") | ||
path = source.pop("path") | ||
hist = read_histogram_file(input_file, path) | ||
collection.add_hist( | ||
name=label, | ||
numerator=hist.members["fPassedHistogram"].to_numpy()[0], | ||
denominator=hist.members["fTotalHistogram"].to_numpy()[0], | ||
) | ||
|
||
collection.plot() | ||
collection.save(output_dir) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import os | ||
import numpy as np | ||
|
||
from hist.intervals import ratio_uncertainty | ||
import mplhep as hep | ||
import matplotlib | ||
matplotlib.use("Agg") | ||
import matplotlib.pyplot as plt | ||
|
||
|
||
class EfficiencyHistCollection(): | ||
|
||
def __init__(self, name, title, style): | ||
self.name = name | ||
self.title = title | ||
self.style = style | ||
self.hists = [] | ||
|
||
def add_hist(self, name, numerator, denominator, **kwargs): | ||
self.hists.append(Efficiency(name, numerator, denominator, **kwargs)) | ||
|
||
def plot(self, **kwargs): | ||
hep.style.use("CMS") | ||
fig = plt.figure(figsize=(10, 8)) | ||
for hist in self.hists: | ||
hep.histplot(hist.eff, yerr=hist.eff_err, **kwargs) | ||
|
||
def save(self, output_dir): | ||
output_file = os.path.join(output_dir, f"{self.name}.png") | ||
print(f"Saving {output_file}") | ||
plt.savefig(output_file) | ||
|
||
|
||
class Efficiency: | ||
num: np.ndarray | ||
den: np.ndarray | ||
name: str | ||
|
||
def __init__(self, name, num, den): | ||
self.name = name | ||
self.num = num | ||
self.den = den | ||
self._eff = None | ||
self._eff_err = None | ||
|
||
@property | ||
def eff(self): | ||
if self._eff is None: | ||
old_settings = np.seterr() | ||
np.seterr(divide='ignore', invalid='ignore') | ||
self._eff = np.divide(self.num, self.den, dtype=np.float64) | ||
np.seterr(**old_settings) | ||
self._eff[np.isnan(self._eff)] = 0.0 | ||
|
||
return self._eff | ||
|
||
@property | ||
def eff_err(self): | ||
if self._eff_err is None: | ||
if np.any(self.num > self.den): | ||
raise ValueError( | ||
"Found numerator larger than denominator while calculating binomial uncertainty" | ||
) | ||
self._eff_err = ratio_uncertainty(self.num, self.den, uncertainty_type="efficiency") | ||
return self._eff_err | ||
|
||
def plot(self, **kwargs): | ||
hep.histplot(self.eff, yerr=self.eff_err, **kwargs) | ||
|
||
def __repr__(self): | ||
return f"EfficiencyHist(num={self.num}, den={self.den})" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
[bumpversion] | ||
current_version = 0.10.4 | ||
current_version = 1.0.0a0 | ||
commit = True | ||
tag = False | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters