def gen_signal(self, n=None, w0=20, w1=20, m0=70, m1=85, p=.6, cons=False): if self.Ana is not None: return MCSignal.gen_sig_from_dist( self.Ana.draw_signal_distribution( show=False, prnt=False, evnt_corr=False), n=n) * (1.025 if cons else 1) g = concatenate([ normal(choose(m, 80), choose(w, 20), round(choose(n, self.N) * ip)) for w, ip, m in [(w0, p, m0), (w1, 1 - p, m1)] ]) return [gRandom.Landau(ig, ig / 8) for ig in g] # assuming R=FWHM/MPV=.5, FWHM=4*width
def draw_signal_distribution(self, data=None, cut=...): x = choose(data, self.get_data()[0])[cut] bins = self.Ana.Bins.get_pad_ph(2) if self.HasAna else None self.Draw.distribution(x, bins, x_range=[-50, 400], x_tit='Pulse Height [mV]', lm=.15, y_off=2)
def fit_ph(self, g, amin=-10, amax=35): a0, a1 = sorted([choose(amin, -amax), amax]) make_fit(g, lambda x, ph, off: ph / cos(deg2rad(x - off)), a0, a1, start_values=[mean(get_graph_y(g, err=False)), 0], par_names=['ph_{0}', 'a_{0}']).fit() format_statbox(g, fit=True, form='.0f') self.Draw.save_plots('PHAngleFit')
def gen_sig_from_dist(h, n=None, p_steps=100000): """interpolate the cdf in equal prob steps and sample it""" n = int(choose(n, 1e6)) x, y = get_hist_vecs(h, err=False) ints = cumsum(y) / h.GetEntries() p = linspace(0, 1, p_steps, endpoint=False) ip = array([where(ip >= ints)[0][-1] for ip in p]) fits = polyfit(x[:2], [ints[ip], ints[ip + 1]], deg=1) xp = append( (p - fits[1]) / fits[0] + (x[ip] - x[0] + (x[1] - x[0]) / 2), max(x)) return xp[randint(0, p.size, size=n)]
def draw(self, cut=None, bin_size=None, rel_time=False, **dkw): x, e = self.get_tree_vec( [self.get_t_var(), self.get_var()], choose(cut, self.Cut())) g = self.Draw.efficiency( x, e, self.Bins.get_time( choose( bin_size, 1000 if x.size // 20 < 1000 or x.size / 1000 < 20 else x.size // 20)), show=False) # min bin size of 1000 max 20 points fit, tit = FitRes(g.Fit('pol0', 'qs')), 'Hit Efficiency' self.Draw( g, **prep_kw(dkw, title=tit, **self.get_t_args(rel_time), y_range=[-5, 115], gridy=True, draw_opt='apz', stats=set_statbox(fit=True, form='.2f', center_y=True), file_name='HitEff')) return fit if fit.Parameter(0) is not None else 0
def sim_signal(self, res=.5, n=1e6, noise=None): m, p = [ get_2d_hist_vec(f(res, cut=self.Ana.Cut(), show=False), err=False).astype(t) for f, t in [(self.Ana.draw_signal_map, 'd'), (self.Ana.draw_hitmap, 'i')] ] m = m.repeat(array(round(p / sum(p) * n), 'i')) self.PBar.start(int(m.size)) mpv = -1.49e-01 + m * 7.35e-01 + m**2 * 5.77e-04 xi = mpv * 0.067142 noise = normal(0, choose(noise, self.Ana.Pedestal.get_mean().n), xi.size) ph = array([self._sim_signal(i, j) for i, j in array([mpv, xi]).T]) + noise return ph
def draw_vs_cuts(self, cuts=None, short=False, redo=False, **dkw): cuts = choose(cuts, self.Cut.get_consecutive(short)) self.PBar.start(len(cuts), counter=True) if redo or not file_exists( self.make_simple_pickle_path( suf=f'{[*cuts.values()][-1].GetName()}_{self.UseRhit}') ) else do_nothing() x, y = arange(len(cuts)), array( [self.get(cut, _redo=redo) for cut in cuts.values()]) return self.Draw.graph(x, y, title='Efficiency for Consecutive Cuts', y_tit='Efficiency [%]', **prep_kw(dkw, draw_opt='ap', gridy=True, x_range=[-1, len(y)], bin_labels=cuts.keys()))
def align(self, d=None, m=None, cut=None, pl=None, p=.05, i=0, imax=20, _redo=False, _save=False): if d is None: self.PBar.start(imax) sx, sy = self.plane(pl).PX, self.plane(pl).PY cut = self.Cut(cut) & self.Cut['res'] x, y = transform(*self.get_xy(local=True, cut=cut, pl=pl), sx, sy) if d is None else d[:2] # convert to mm tx, ty = transform( *self.get_txy(local=True, cut=cut, pl=pl, trans=False), sx, sy) if d is None else d[2:] d = self.rotate(x, y, *((tx, ty) if m is None else m_transform(m, *d[2:])), p=p) t = self.translate(*d[:4]) self.Rot.append(d[4]) self.Trans.append(t) m = choose(m, identity(3)) @ matrix(1, 1, *t, rx=d[4], order='str') self.PBar.update() if i < imax - 1: return self.align([x, y, tx, ty], m, p=p, i=i + 1, imax=imax, _redo=_redo, _save=_save) s = scale_matrix(sx, sy) return inv(s) @ m @ s
def get_raw_event(self, bin_width=None, start_event=0, end_event=None): end_event, bin_width = choose(end_event, self.NEvents), Bins.get_size(bin_width) return Bins.make(start_event, end_event, bin_width, last=end_event - 1 if end_event - start_event % bin_width > bin_width / 4 else None)
def remove_pickle(self, bin_size=None): remove_file(self.make_simple_pickle_path(suf=choose(bin_size, '')))
def get_size(bin_size=None): return choose(bin_size, Bins.Size)
def get_pad_ph(bin_width=None): return Bins.make(*Bins.PadPHRange, choose(bin_width, Bins.PadPHBinWidth))
def get_electrons(bin_width=None): return Bins.make(*Bins.PHRange, choose(bin_width, Bins.PHWidth))
def get_chi2(bin_size=None, chi_max=100): return Bins.make(0, chi_max, choose(bin_size, .1))
def get_global_y(res=None): wmax = Plane.WMax * .6 # to keep the aspect ratio return Bins.make(-wmax, wmax, choose(res, Plane.R0) * Plane.PY)
def gen_noise(self, n=None): return normal(self.Pedestal, self.Noise, choose(n, self.N))