From 819f4fe9dbdfb87015ab307c7f932906daf965e0 Mon Sep 17 00:00:00 2001 From: Daniel Hundhausen Date: Mon, 21 Oct 2024 17:30:12 +0200 Subject: [PATCH] dump commit; nan issue w/ trafo unresolved --- configs/V29/objects/met_ht_mht.yaml | 13 +++++ menu_tools/object_performance/config.py | 4 +- menu_tools/object_performance/plotter.py | 7 +-- .../ElectronsIsolation_Barrel_-999_V29.yaml | 13 +---- .../reference_data/HT_50perc_350_V29.yaml | 9 +--- .../reference_data/HT_90perc_350_V29.yaml | 9 +--- .../tests/test_turnons_v29.py | 6 ++- .../object_performance/turnon_collection.py | 32 ++++++------- menu_tools/utils/objects.py | 48 +++++++++---------- 9 files changed, 64 insertions(+), 77 deletions(-) diff --git a/configs/V29/objects/met_ht_mht.yaml b/configs/V29/objects/met_ht_mht.yaml index 8e0a6e45..0dbda384 100644 --- a/configs/V29/objects/met_ht_mht.yaml +++ b/configs/V29/objects/met_ht_mht.yaml @@ -1,3 +1,16 @@ +jet: + eta_ranges: + inclusive: [0, 8] + ids: + ht: + label: "Gen HT" + trafo: "HT" + cuts: + event: + inclusive: + - "abs({eta}) < 2.4" + - "{pt} > 30" + phase1PuppiHT: label: "Histogrammed Puppi HT" ids: diff --git a/menu_tools/object_performance/config.py b/menu_tools/object_performance/config.py index b389a0da..d8fffa6d 100644 --- a/menu_tools/object_performance/config.py +++ b/menu_tools/object_performance/config.py @@ -24,7 +24,9 @@ def reference_object(self) -> Object: assert ( len(object_id_strs) == 1 ), f"Multiple reference objects defined in {self.plot_name}!" - return ReferenceObject(self._cfg["reference_object"], self.version) + return ReferenceObject( + list(self._cfg["reference_object"].keys())[0], self.version + ) @property def test_objects(self) -> dict[str, Any]: diff --git a/menu_tools/object_performance/plotter.py b/menu_tools/object_performance/plotter.py index 776d26ac..e205d29e 100755 --- a/menu_tools/object_performance/plotter.py +++ b/menu_tools/object_performance/plotter.py @@ -105,6 +105,7 @@ def _save_json(self, file_name): xbins = self.turnon_collection.bins xbins = 0.5 * (xbins[1:] + xbins[:-1]) + print(len(xbins)) if self.cfg.iso_vs_eff_plot: efficiency = self._get_iso_vs_eff_hist(gen_hist_trig[0]) @@ -117,9 +118,9 @@ def _save_json(self, file_name): yerr = np.array( [yerr[0][~np.isnan(efficiency)], yerr[1][~np.isnan(efficiency)]] ) - xerr = xerr[np.isfinite(efficiency)] - xbins = xbins[np.isfinite(efficiency)] - efficiency = efficiency[np.isfinite(efficiency)] + # xerr = xerr[np.isfinite(efficiency)] + # xbins = xbins[np.isfinite(efficiency)] + # efficiency = efficiency[np.isfinite(efficiency)] xerr = xerr.tolist() yerr = yerr.tolist() diff --git a/menu_tools/object_performance/tests/reference_data/ElectronsIsolation_Barrel_-999_V29.yaml b/menu_tools/object_performance/tests/reference_data/ElectronsIsolation_Barrel_-999_V29.yaml index d514ba61..d363c689 100644 --- a/menu_tools/object_performance/tests/reference_data/ElectronsIsolation_Barrel_-999_V29.yaml +++ b/menu_tools/object_performance/tests/reference_data/ElectronsIsolation_Barrel_-999_V29.yaml @@ -6,18 +6,7 @@ ElectronsIsolation_Barrel: iso_vs_efficiency: true match_test_to_ref: true reference_object: - part_e:inclusiveElectron: Pt - - # reference_object: "GenElectron:" - # cuts: - # event: - # - '{dr_0.3} < 0.15' - # - abs({eta}) < 1.479 - # object: - # - abs({eta}) < 1.479 - # label: Gen Electrons - # object: part_e - # x_arg: Pt + part_e:default: "Pt" sample: DYLL_M50 test_objects: tkElectron:NoIsoLowPt: trkiso diff --git a/menu_tools/object_performance/tests/reference_data/HT_50perc_350_V29.yaml b/menu_tools/object_performance/tests/reference_data/HT_50perc_350_V29.yaml index 224160bf..cd6f2336 100644 --- a/menu_tools/object_performance/tests/reference_data/HT_50perc_350_V29.yaml +++ b/menu_tools/object_performance/tests/reference_data/HT_50perc_350_V29.yaml @@ -5,14 +5,7 @@ HT_50perc: step: 20 version: V29 reference_object: - cuts: - object: - - abs({eta}) < 2.4 - - '{pt} > 30' - label: Gen HT - object: jet - x_arg: Pt - trafo: HT + jet:ht: "Pt" sample: TT scalings: method: naive diff --git a/menu_tools/object_performance/tests/reference_data/HT_90perc_350_V29.yaml b/menu_tools/object_performance/tests/reference_data/HT_90perc_350_V29.yaml index 969165bf..e5d45808 100644 --- a/menu_tools/object_performance/tests/reference_data/HT_90perc_350_V29.yaml +++ b/menu_tools/object_performance/tests/reference_data/HT_90perc_350_V29.yaml @@ -5,14 +5,7 @@ HT_90perc: step: 20 version: V29 reference_object: - cuts: - object: - - abs({eta}) < 2.4 - - '{pt} > 30' - label: Gen HT - object: jet - x_arg: Pt - trafo: HT + jet:ht: "Pt" sample: TT scalings: method: naive diff --git a/menu_tools/object_performance/tests/test_turnons_v29.py b/menu_tools/object_performance/tests/test_turnons_v29.py index 9bea1fea..24c00b55 100644 --- a/menu_tools/object_performance/tests/test_turnons_v29.py +++ b/menu_tools/object_performance/tests/test_turnons_v29.py @@ -12,9 +12,9 @@ testdata = [ - "HT_50perc_350_V29", + # "HT_50perc_350_V29", "HT_90perc_350_V29", - "ElectronsIsolation_Barrel_-999_V29", + # "ElectronsIsolation_Barrel_-999_V29", ] @@ -49,7 +49,9 @@ def test_matching_plots_reproduced(test_name): ) efficiencies_reference = np.array(val["efficiency"], dtype=np.float64) print(efficiencies_reference) + print(efficiencies_test) differences = efficiencies_test - efficiencies_reference + print(differences) assert not np.any(abs(differences) > 1e-4) else: assert val == test_result[key] diff --git a/menu_tools/object_performance/turnon_collection.py b/menu_tools/object_performance/turnon_collection.py index 47381c18..e85b7747 100644 --- a/menu_tools/object_performance/turnon_collection.py +++ b/menu_tools/object_performance/turnon_collection.py @@ -1,5 +1,4 @@ from typing import Any, Optional -import re import awkward as ak import numpy as np @@ -7,7 +6,11 @@ from menu_tools.object_performance.config import PerformancePlotConfig from menu_tools.utils import utils -from menu_tools.utils.objects import Object, compute_selection_mask_for_event_cuts, compute_selection_mask_for_object_cuts +from menu_tools.utils.objects import ( + Object, + compute_selection_mask_for_event_cuts, + compute_selection_mask_for_object_cuts, +) vector.register_awkward() @@ -51,7 +54,7 @@ def _load_array_from_parquet(self, obj: str): ) array = ak.from_parquet(fname) array_dict = {self._transform_key(key, obj): array[key] for key in array.fields} - if self.cfg_plot.reference_trafo and not obj.startswith("L1"): + if self.cfg_plot.reference_object.trafo and not obj.startswith("L1"): array = ak.Array(array_dict) else: array = ak.zip(array_dict) @@ -228,12 +231,6 @@ def _select_highest_pt_ref_object(self): sel_pt = ak.argmax(self.ak_arrays["ref"]["pt"], axis=-1, keepdims=True) self.ak_arrays["ref"] = self.ak_arrays["ref"][sel_pt] - def _apply_list_of_reference_cuts(self, cut_dict: Optional[dict[str, list[str]]]) -> None: - for cut in cut_list: - cut = re.sub(r"{([^&|]*)}", r"self.ak_arrays['ref']['\1']", cut) - sel = eval(cut) - self.ak_arrays["ref"] = self.ak_arrays["ref"][sel] - def _apply_reference_cuts(self) -> None: """Applies configured cuts on reference objects. @@ -246,20 +243,19 @@ def _apply_reference_cuts(self) -> None: # Apply object level cuts, i.e. removing objects from event, while # retaining the events. - sel = compute_selection_mask_for_object_cuts( - self.cfg_plot.reference_object, self.ak_arrays["ref"] - ) - self.ak_arrays["ref"] = self.ak_arrays["ref"][sel] + if self.cfg_plot.reference_object.cuts: + sel = compute_selection_mask_for_object_cuts( + self.cfg_plot.reference_object, self.ak_arrays["ref"] + ) + self.ak_arrays["ref"] = self.ak_arrays["ref"][sel] - # If spceified apply transformation + # If specified, apply transformation if self.cfg_plot.reference_object.trafo: # In this case each event is reduced to a single value already return None # Select highest pt object from each event and apply event level cuts. self._select_highest_pt_ref_object() - # ref_event_cuts = self.cfg_plot.reference_object.event_cuts - # self._apply_list_of_reference_cuts(ref_event_cuts) sel = compute_selection_mask_for_event_cuts( self.cfg_plot.reference_object, self.ak_arrays["ref"] ) @@ -273,7 +269,9 @@ def _apply_test_obj_cuts(self): for test_obj, _ in self.test_objects: if not test_obj.cuts: continue - sel = compute_selection_mask_for_object_cuts(test_obj, self.ak_arrays[str(test_obj)]) + sel = compute_selection_mask_for_object_cuts( + test_obj, self.ak_arrays[str(test_obj)] + ) self.ak_arrays[str(test_obj)] = self.ak_arrays[str(test_obj)][sel] def _skim_to_hists(self) -> None: diff --git a/menu_tools/utils/objects.py b/menu_tools/utils/objects.py index a9d3366f..983defbb 100644 --- a/menu_tools/utils/objects.py +++ b/menu_tools/utils/objects.py @@ -184,25 +184,27 @@ def __init__(self, object_key: str, version: str) -> None: @property def trafo(self) -> Optional[str]: - """Returns the trafo key of the (reference) object if it is defined (HT, MHT, etc). + """Returns the trafo key of the (reference) object + if it is defined (HT, MHT, etc). This is intended only for the *reference* object. """ try: - return self._nano_obj["trafo"] - except KeyError: - return self._nano_obj["transformation"] + return self._object_params["trafo"] except KeyError: + print("No transformation defined in reference object") return None - @property - def cuts(self) -> Optional[dict[str, list[str]]]: - """OBJECT level cuts! I.e. individual objects that don't fulfill the - criteria are removed from the events, but the events themselves are - retained. - """ + def _get_cuts(self, event_or_object: str) -> Optional[dict[str, list[str]]]: + assert event_or_object in [ + "event", + "object", + ], "Cuts are either event or object level" _cuts = {} if "cuts" in self._object_params.keys(): - _cuts = self._object_params["cuts"]["object"] + if event_or_object in self._object_params["cuts"].keys(): + _cuts = self._object_params["cuts"][event_or_object] + else: + return None if self.eta_range != "inclusive": # if a region other than inclusive is specified an eta cut eta_min = self.eta_ranges[self.eta_range][0] @@ -216,27 +218,21 @@ def cuts(self) -> Optional[dict[str, list[str]]]: _cuts["inclusive"] = [global_eta_cut] return _cuts + @property + def cuts(self) -> Optional[dict[str, list[str]]]: + """OBJECT level cuts! I.e. individual objects that don't fulfill the + criteria are removed from the events, but the events themselves are + retained. + """ + return self._get_cuts("object") + @property def event_cuts(self) -> Optional[dict[str, list[str]]]: """EVENT level cuts! I.e. individual objects that don't fulfill the criteria are removed from the events, but the events themselves are retained. """ - _cuts = {} - if "cuts" in self._object_params.keys(): - _cuts = self._object_params["cuts"]["event"] - if self.eta_range != "inclusive": - # if a region other than inclusive is specified an eta cut - eta_min = self.eta_ranges[self.eta_range][0] - eta_max = self.eta_ranges[self.eta_range][1] - global_eta_cut = ( - f"((abs({{eta}}) > {eta_min}) & (abs({{eta}}) < {eta_max}))" - ) - try: - _cuts["inclusive"].append(global_eta_cut) - except KeyError: - _cuts["inclusive"] = [global_eta_cut] - return _cuts + return self._get_cuts("event") def compute_selection_mask_for_cuts(