15 The module contains basic functions for generation and analysis of SVD strip data.
18 This is a set of utility functions and constant declarations for simulation of SVD strip data
19 to use in training timing networks or for other purposes. These include wave functions (gamma,
20 cubic polynomial and beta-prime).
23 Just import the module to use it.
28 from scipy.stats
import norm, uniform
36 def wexp(t, tau=wexp_default_tau):
39 wexp(t, tau) = t/tau * exp(1-t/tau) if t > 0 else 0,
40 normalized to peak value 1.
41 t - nummpy vector of times
42 tau - (scalar) waveform decay time
43 return: numpy vector of wexp(t, tau) values at times t
46 return np.clip(z * np.exp(1.0 - z), 0.0, 100.0)
52 def w3(t, tau=w3_default_tau):
54 w3(t, tau) = 27/4 * t/tau * (1-t/tau)**2 if 0 < t < tau else 0,
55 normalized to peak value 1.
56 t - numpy vector of times
57 tau - (scalar) width of the distribution
58 return - numpy vector of w3(t,tau) values at times t
60 z = np.clip(t / tau, 0, 1)
61 return 27 / 4 * z * (z - 1) * (z - 1)
67 def betaprime_wave(t, tau=bp_default_tau):
68 ''' Beta-prime waveform
69 betaprime_wave(t, tau) = 149.012 * (t/tau)**2 * (1 + t/tau)**10 if t > 0 else 0
70 t - numpy vector of times
71 tau - (scalar) width of the distribution
72 return - numpy vector of betaprime_wave values of betaprime_wave at times t
74 z = np.clip(t / tau, 0, 1000)
75 return 149.012 * z**2 / (1 + z)**10
78 def test3(s, threshold):
79 '''Test for 3 consecutive non-zero APV samples
80 A six-tuple of APV25 samples is only accepted if it has 3 consecutive samples over threshold.
82 return - True if there are 3 consecutive samples over threshold, otherwise False.
84 cons_before = np.zeros(len(s))
86 cons_before[i:] += (s > threshold)[0:6 - i]
87 return np.max(cons_before) >= 3
91 This is the list of all configurations of over-the-threhsold samples that pass the 3-over-the-threshold-samples test.
117 def gen_signal(ampl, t0, tau, sigma=1, w=betaprime_wave, tau_sigma=0.0):
118 '''Generate random sample of 6 APV signals, properly censored.
119 The produced data are normalized to sigma = 1 and the given amplitude.
121 - real_amplitude = sigma * amlitude
122 - generate waveform, add noise, and convert to integer values
123 - divide signals by sigma
124 For large amplitudes, the function adds gaussian noise to generated waveform.
125 For amplitudes around and below the threshold, the function randomly selects a
126 subset of samples over threshold and generates over-threhold noises from left-censored
127 gaussian distributions.
130 tau - decay time or width of the waveform
131 sigma - nosie (default 1: we work with S/N rather than raw signals)
132 tau_sigma - width of tau jitter
135 gen_amplitude = sigma * ampl
137 gen_thr = int(sigma * threshold_cut + 1.0 - 1.0e-9) - 0.5
141 tau += np.random.randn() * tau_sigma
142 res0 = gen_amplitude * w(np.linspace(-dt - t0, 4 * dt - t0, 6, endpoint=
True), tau)
143 if test3(res0, threshold_cut * sigma):
144 res = (res0 + sigma * np.random.randn(6) + 0.5).astype(int)
146 while not test3(res, threshold_cut * sigma):
147 res = (res0 + sigma * np.random.randn(6) + 0.5).astype(int)
148 res[res < threshold_cut * sigma] = 0
151 p_over = 1.0 - norm.cdf((gen_thr - res0) / sigma)
153 pconfs = np.array([np.prod(p_over[conf])
for conf
in residual_configs])
154 pconfs /= np.sum(pconfs)
155 cconfs = np.cumsum(pconfs)
157 u_conf = uniform.rvs()
159 while u_conf > cconfs[i_conf]:
161 u_res = uniform.rvs(0, 1, len(residual_configs[i_conf]))
163 res[residual_configs[i_conf]] = res0[residual_configs[i_conf]] + \
164 sigma * norm.ppf(1 - u_res * p_over[residual_configs[i_conf]])
165 res = (res + 0.5).astype(int)
174 A simple class to encode and decode tau values for network training
175 based on amplitude and tau ranges.
191 encoder of tau values for network training
193 return (self.amp_min + self.
at_ratioat_ratio * (tau - self.tau_min))
197 decoder of tau values for network training
199 return (self.tau_min + 1.0 / self.
at_ratioat_ratio * (etau - self.amp_min))
204 This class generates a Pandas dataframe with a random sample of SVD strip signals with specified size and parameters.
206 1. We generate time bins from quantiles, do we want a regular grid?
207 2. Have to think of possible irregular grid.
210 def __init__(self, t0_bounds, tau_bounds, amplitude_bounds, sigma_bounds, tau_sigma, bin_size, wf=betaprime_wave):
212 The constructor takes the following parameters:
213 t0_bounds is a tuple, (t0_min, t0_max)
214 tau_bounds is a tuple (tau_min, tau_max)
215 amplitude_bounds is a tuple (amp_min, amp_max)
216 sigma_bounds is a tuple (sigma_min, sigma_max)
217 bin_size is the % fraction of t0_min, t0_max interval corresponding to a single output t0 bin.
221 self.t0_min, self.
t0_maxt0_max = t0_bounds
225 self.amp_min, self.
amp_maxamp_max = amplitude_bounds
239 Get t0 bounds of sampling space
241 return (self.t0_min, self.
t0_maxt0_max)
245 Get amplitude bounds of sampling space
247 return (self.amp_min, self.
amp_maxamp_max)
251 Get tau bounds of sampling space
257 Set width limits for the simulation.
265 Set width jitter for the simulation.
271 Get width jitter for the simulation.
279 return (self.sigma_min, self.
sigma_maxsigma_max)
283 Generate sample_size samples.
289 'test': np.random.uniform(size=self.
n_samplesn_samples),
290 't0': np.random.uniform(self.t0_min, self.
t0_maxt0_max, size=self.
n_samplesn_samples),
292 'sigma': np.random.uniform(self.sigma_min, self.
sigma_maxsigma_max, size=self.
n_samplesn_samples),
293 'amplitude': np.random.uniform(self.amp_min, self.
amp_maxamp_max, size=self.
n_samplesn_samples),
302 orderedcols = [
'test',
'amplitude',
't0',
'tau',
'sigma',
's1',
's2',
's3',
's4',
's5',
's6',
'normed_tau']
305 self.
stockdatastockdata[[
's' + str(i)
for i
in range(1, 7)]] = self.
stockdatastockdata.apply(
lambda row: pd.Series(
306 gen_signal(row.amplitude, row.t0, row.tau, row.sigma, tau_sigma=self.
tau_sigmatau_sigma, w=self.
wfwf)), axis=1)
314 abins = np.arange(self.amp_min, self.
amp_maxamp_max + 1, 1)
315 self.
stockdatastockdata[
'abin'] = np.digitize(self.
stockdatastockdata.amplitude, abins)
320 Get array of mean t0's for classifier bins
326 Get array of mean t0's for classifier bins
328 return pd.Series(self.
t0_binst0_bins)
335 Empirical ranges of raw waveform width values from February 2017 testbeam data.
336 These values are only used for scaling and not critical.
342 def tau_hao2real(hao_tau):
344 Convert Hao's raw tau (integral, in latency units) to correct betaprime scale. Includes scaling and fit adjustment.
346 return 3.93 / 0.50305 * hao_tau
351 if __name__ ==
'__main__':
352 print(
'Basic functions for simulation of SVD strip data.\nImport to use.')
def set_tau_sigma(self, tau_sigma)
def set_tau_bounds(self, tau_min, tau_max)
def __init__(self, t0_bounds, tau_bounds, amplitude_bounds, sigma_bounds, tau_sigma, bin_size, wf=betaprime_wave)
t0_bin_times
undocumented variable
t0_bins
undocumented variable
def get_sigma_bounds(self)
def generate(self, sample_size)
def __init__(self, amp_range, tau_range)