Coverage for orcasong/plotting/binning.py: 0%
66 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-10-03 18:23 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2024-10-03 18:23 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
4import numpy as np
5import km3pipe as kp
6import matplotlib.pyplot as plt
8import orcasong.modules as modules
10__author__ = "Stefan Reck"
13class TimePlotter:
14 """
15 For plotting the time distribution of hits, in a histogram,
16 and finding a good binning.
18 The plot will have some bins attached in both directions for
19 better overview.
21 Attributes:
22 -----------
23 files : list
24 The .h5 files to read hits from.
25 do_mc_hits : bool
26 Read mchits instead of hits.
27 det_file : str, optional
28 Path to a .detx detector geometry file, which can be used to
29 calibrate the hits.
30 center_time : bool
31 Subtract time of first triggered hit from all hit times. Will
32 also be done for McHits if they are in the blob [default: True].
33 add_t0 : bool
34 If true, add t0 to the time of hits. If using a det_file,
35 this will already have been done automatically [default: False].
36 inactive_du : int, optional
37 Dont plot hits from this du.
39 """
41 def __init__(
42 self,
43 files,
44 do_mchits=False,
45 det_file=None,
46 center_time=True,
47 add_t0=False,
48 subtract_t0_mchits=False,
49 inactive_du=None,
50 ):
51 if isinstance(files, str):
52 self.files = [files]
53 else:
54 self.files = files
55 self.do_mchits = do_mchits
56 self.det_file = det_file
57 self.add_t0 = add_t0
58 self.subtract_t0_mchits = subtract_t0_mchits
59 self.center_time = center_time
60 self.inactive_du = inactive_du
62 self.data = np.array([])
63 for file in self.files:
64 self._read(file, self.det_file)
66 def hist(self, bins=50, padding=0.5, **kwargs):
67 """
68 Plot the hits as a histogram.
70 Parameters
71 ----------
72 bins : int or np.array
73 Number of bins, or bin edges. If bin edges are given, some
74 bins are attached left and right (next to red vertical lines)
75 for better overview.
76 padding : float
77 Fraction of total number of bins to attach left and right
78 in the plot.
80 """
81 plt.grid(True, zorder=-10)
82 plt.xlabel("time")
83 if self.do_mchits:
84 plt.ylabel("mchits / bin")
85 else:
86 plt.ylabel("hits / bin")
87 if isinstance(bins, int):
88 plt.hist(self.data, bins=bins, zorder=10, **kwargs)
89 else:
90 self.print_binstats(bins)
91 plt.hist(
92 self.data, bins=_get_padded_bins(bins, padding), zorder=10, **kwargs
93 )
94 for bin_line_x in (bins[0], bins[-1]):
95 plt.axvline(x=bin_line_x, color="firebrick", linestyle="--", zorder=20)
97 def print_binstats(self, bin_edges):
98 print(f"Cutoff left: {np.mean(self.data < bin_edges[0]):.2%}")
99 print(f"Cutoff right: {np.mean(self.data > bin_edges[-1]):.2%}")
100 print(f"Avg. time per bin: {np.mean(np.diff(bin_edges)):.2f}")
102 def _read(self, file, det_file=None):
103 if det_file is not None:
104 cal = modules.DetApplier(det_file=det_file)
105 else:
106 cal = None
107 if self.center_time or self.add_t0:
108 time_pp = modules.TimePreproc(
109 add_t0=self.add_t0,
110 center_time=self.center_time,
111 subtract_t0_mchits=self.subtract_t0_mchits,
112 )
113 else:
114 time_pp = None
116 pump = kp.io.hdf5.HDF5Pump(filename=file)
117 for i, blob in enumerate(pump):
118 if i % 1000 == 0:
119 print("Blob {}".format(i))
120 if cal is not None:
121 blob = cal.process(blob)
122 if time_pp is not None:
123 blob = time_pp.process(blob)
124 self.data = np.concatenate([self.data, self._get_data_one_event(blob)])
125 pump.close()
127 def _get_data_one_event(self, blob):
128 if self.do_mchits:
129 fld = "McHits"
130 else:
131 fld = "Hits"
132 blob_data = blob[fld]["time"]
134 if self.inactive_du is not None:
135 dus = blob[fld]["du"]
136 blob_data = blob_data[dus != self.inactive_du]
137 return blob_data
140def _get_padded_bins(bin_edges, padding):
141 """Add fraction of total # of bins, with same width."""
142 bin_width = bin_edges[1] - bin_edges[0]
143 n_bins = len(bin_edges) - 1
144 bins_to_add = np.ceil(padding * n_bins)
145 return np.linspace(
146 bin_edges[0] - bins_to_add * bin_width,
147 bin_edges[-1] + bins_to_add * bin_width,
148 int(n_bins + 2 * bins_to_add + 1),
149 )