14The module contains basic functions for generation and analysis of SVD strip data.
17This is a set of utility functions and constant declarations for simulation of SVD strip data
18to use in training timing networks or for other purposes. These include wave functions (gamma,
19cubic polynomial and beta-prime).
22Just import the module to use it.
27from scipy.stats
import norm, uniform
35def wexp(t, tau=wexp_default_tau):
38 wexp(t, tau) = t/tau * exp(1-t/tau) if t > 0
else 0,
39 normalized to peak value 1.
40 t - nummpy vector of times
41 tau - (scalar) waveform decay time
42 return: numpy vector of wexp(t, tau) values at times t
45 return np.clip(z * np.exp(1.0 - z), 0.0, 100.0)
51def w3(t, tau=w3_default_tau):
53 w3(t, tau) = 27/4 * t/tau * (1-t/tau)**2 if 0 < t < tau
else 0,
54 normalized to peak value 1.
55 t - numpy vector of times
56 tau - (scalar) width of the distribution
57 return - numpy vector of w3(t,tau) values at times t
59 z = np.clip(t / tau, 0, 1)
60 return 27 / 4 * z * (z - 1) * (z - 1)
66def betaprime_wave(t, tau=bp_default_tau):
67 ''' Beta-prime waveform
68 betaprime_wave(t, tau) = 149.012 * (t/tau)**2 * (1 + t/tau)**10 if t > 0
else 0
69 t - numpy vector of times
70 tau - (scalar) width of the distribution
71 return - numpy vector of betaprime_wave values of betaprime_wave at times t
73 z = np.clip(t / tau, 0, 1000)
74 return 149.012 * z**2 / (1 + z)**10
77def test3(s, threshold):
78 '''Test for 3 consecutive non-zero APV samples
79 A six-tuple of APV25 samples is only accepted
if it has 3 consecutive samples over threshold.
81 return -
True if there are 3 consecutive samples over threshold, otherwise
False.
83 cons_before = np.zeros(len(s))
85 cons_before[i:] += (s > threshold)[0:6 - i]
86 return np.max(cons_before) >= 3
90This is the list of all configurations of over-the-threhsold samples that pass the 3-over-the-threshold-samples test.
116def gen_signal(ampl, t0, tau, sigma=1, w=betaprime_wave, tau_sigma=0.0):
117 '''Generate random sample of 6 APV signals, properly censored.
118 The produced data are normalized to sigma = 1 and the given amplitude.
120 - real_amplitude = sigma * amlitude
121 - generate waveform, add noise,
and convert to integer values
122 - divide signals by sigma
123 For large amplitudes, the function adds gaussian noise to generated waveform.
124 For amplitudes around
and below the threshold, the function randomly selects a
125 subset of samples over threshold
and generates over-threhold noises
from left-censored
126 gaussian distributions.
129 tau - decay time
or width of the waveform
130 sigma - nosie (default 1: we work
with S/N rather than raw signals)
131 tau_sigma - width of tau jitter
134 gen_amplitude = sigma * ampl
136 gen_thr = int(sigma * threshold_cut + 1.0 - 1.0e-9) - 0.5
140 tau += np.random.randn() * tau_sigma
141 res0 = gen_amplitude * w(np.linspace(-dt - t0, 4 * dt - t0, 6, endpoint=
True), tau)
142 if test3(res0, threshold_cut * sigma):
143 res = (res0 + sigma * np.random.randn(6) + 0.5).astype(int)
145 while not test3(res, threshold_cut * sigma):
146 res = (res0 + sigma * np.random.randn(6) + 0.5).astype(int)
147 res[res < threshold_cut * sigma] = 0
150 p_over = 1.0 - norm.cdf((gen_thr - res0) / sigma)
152 pconfs = np.array([np.prod(p_over[conf])
for conf
in residual_configs])
153 pconfs /= np.sum(pconfs)
154 cconfs = np.cumsum(pconfs)
156 u_conf = uniform.rvs()
158 while u_conf > cconfs[i_conf]:
160 u_res = uniform.rvs(0, 1, len(residual_configs[i_conf]))
162 res[residual_configs[i_conf]] = res0[residual_configs[i_conf]] + \
163 sigma * norm.ppf(1 - u_res * p_over[residual_configs[i_conf]])
164 res = (res + 0.5).astype(int)
174 based on amplitude
and tau ranges.
190 encoder of tau values for network training
192 return (self.amp_min + self.
at_ratio * (tau - self.tau_min))
196 decoder of tau values for network training
198 return (self.tau_min + 1.0 / self.
at_ratio * (etau - self.amp_min))
203 This class generates a Pandas dataframe with a random sample of SVD strip
signals with specified size and parameters.
205 1. We generate time bins
from quantiles, do we want a regular grid?
206 2. Have to think of possible irregular grid.
209 def __init__(self, t0_bounds, tau_bounds, amplitude_bounds, sigma_bounds, tau_sigma, bin_size, wf=betaprime_wave):
211 The constructor takes the following parameters:
212 t0_bounds is a tuple, (t0_min, t0_max)
213 tau_bounds
is a tuple (tau_min, tau_max)
214 amplitude_bounds
is a tuple (amp_min, amp_max)
215 sigma_bounds
is a tuple (sigma_min, sigma_max)
216 bin_size
is the % fraction of t0_min, t0_max interval corresponding to a single output t0 bin.
238 Get t0 bounds of sampling space
240 return (self.t0_min, self.
t0_max)
244 Get amplitude bounds of sampling space
246 return (self.amp_min, self.
amp_max)
250 Get tau bounds of sampling space
256 Set width limits for the simulation.
264 Set width jitter for the simulation.
270 Get width jitter for the simulation.
282 Generate sample_size samples.
288 'test': np.random.uniform(size=self.
n_samples),
289 't0': np.random.uniform(self.t0_min, self.
t0_max, size=self.
n_samples),
292 'amplitude': np.random.uniform(self.amp_min, self.
amp_max, size=self.
n_samples),
301 orderedcols = [
'test',
'amplitude',
't0',
'tau',
'sigma',
's1',
's2',
's3',
's4',
's5',
's6',
'normed_tau']
304 self.
stockdata[[
's' + str(i)
for i
in range(1, 7)]] = self.
stockdata.apply(
lambda row: pd.Series(
305 gen_signal(row.amplitude, row.t0, row.tau, row.sigma, tau_sigma=self.
tau_sigma, w=self.
wf)), axis=1)
313 abins = np.arange(self.amp_min, self.
amp_max + 1, 1)
319 Get array of mean t0's for classifier bins
325 Get array of mean t0's for classifier bins
334Empirical ranges of raw waveform width values from February 2017 testbeam data.
335These values are only used for scaling and not critical.
341def tau_hao2real(hao_tau):
343 Convert Hao's raw tau (integral, in latency units) to correct betaprime scale. Includes scaling and fit adjustment.
345 return 3.93 / 0.50305 * hao_tau
350if __name__ ==
'__main__':
351 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)