-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fwhm, rise/fall time #2151
base: main
Are you sure you want to change the base?
fwhm, rise/fall time #2151
Changes from all commits
6553dc2
b87ed27
5bc56b5
e0ad2bf
6d954a6
dced424
10fd48e
15dbaa1
412c866
fbd875c
492c6ee
e0db767
fd8dc17
6296a74
47f68ca
e0a932b
347d6ce
24b3fad
2e06677
4aa35ba
5897140
5887196
d9bbc7e
fe29167
f63f5fa
680985b
40adf94
3c29eac
766d061
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -351,6 +351,118 @@ | |
return correction | ||
|
||
|
||
@guvectorize( | ||
[ | ||
(float32[:], float32[:], float32[:], float32[:]), | ||
(float64[:], float32[:], float32[:], float32[:]), | ||
], | ||
"(s)->(),(),()", | ||
nopython=True, | ||
cache=True, | ||
) | ||
def time_parameters(waveform, fwhm_arr, rise_time_arr, fall_time_arr): | ||
""" | ||
Calculates the full width at half maximum (FWHM) of R1 already calibrated waveforms. | ||
The rise and fall time of these waveforms is also computed at 90% and 10% of the peak. | ||
|
||
Parameters | ||
---------- | ||
waveforms : ndarray | ||
r1 waveforms stored in a numpy array. | ||
Shape: (n_pix, n_samples) | ||
|
||
Returns | ||
------- | ||
fwhm_arr : list of floats | ||
Full width half maximum of pulse in units of time | ||
Shape : (n_pix) | ||
rise_time_arr : list of floats | ||
Rise time of the pulse in units of time | ||
Shape : (n_pix) | ||
fall_time_arr : list of floats | ||
Fall time of the pulse in units of time | ||
Shape : (n_pix) | ||
|
||
""" | ||
peak_index = np.argmax(waveform) | ||
amplitude = np.max(waveform) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is wasteful, you don't need to find the maximum again, just do |
||
n_samples = np.shape(waveform)[-1] | ||
|
||
# Initialize in case of dividing by zero | ||
rt_90 = np.nan | ||
rt_10 = np.nan | ||
ft_90 = np.nan | ||
ft_10 = np.nan | ||
fwhm_left = np.nan | ||
fwhm_right = np.nan | ||
|
||
half_amplitude = amplitude / 2 | ||
ampl_10percent = 0.1 * amplitude | ||
ampl_90percent = 0.9 * amplitude | ||
|
||
for ti in range(peak_index, n_samples - 1): | ||
tj = ti + 1 | ||
yi = waveform[ti] | ||
yj = waveform[tj] | ||
if (yj - yi) != 0: | ||
if yi >= half_amplitude >= yj: | ||
fwhm_right = ti + (half_amplitude - yi) / (yj - yi) | ||
if yi >= ampl_90percent >= yj: | ||
ft_90 = ti + (ampl_90percent - yi) / (yj - yi) | ||
if yi >= ampl_10percent >= yj: | ||
ft_10 = ti + (ampl_10percent - yi) / (yj - yi) | ||
|
||
for ti in range(peak_index, 0, -1): | ||
tj = ti - 1 | ||
yi = waveform[ti] | ||
yj = waveform[tj] | ||
if (yj - yi) != 0: | ||
if yi >= half_amplitude >= yj: | ||
fwhm_left = ti - (half_amplitude - yi) / (yj - yi) | ||
if yi >= ampl_90percent >= yj: | ||
rt_90 = ti - (ampl_90percent - yi) / (yj - yi) | ||
if yi >= ampl_10percent >= yj: | ||
rt_10 = ti - (ampl_10percent - yi) / (yj - yi) | ||
|
||
fwhm = 0.0 | ||
if None not in (fwhm_right, fwhm_left): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You initialize these two with I think you can just subtract the two anyways, and the result will be nan if either is nan. Check if there is a warning and maybe silence it in case we don't want to have a warning like "invalid valid encountered in subtract". |
||
fwhm = fwhm_right - fwhm_left | ||
|
||
rise_time = 0.0 | ||
if None not in (rt_90, rt_10): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above with the other if |
||
rise_time = rt_90 - rt_10 | ||
|
||
fall_time = 0.0 | ||
if None not in (ft_90, ft_10): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above with the other if |
||
fall_time = ft_10 - ft_90 | ||
|
||
fwhm_arr[0] = fwhm | ||
rise_time_arr[0] = rise_time | ||
fall_time_arr[0] = fall_time | ||
|
||
|
||
def time_over_threshold(waveforms, thr): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically, this is "samples above threshold", for "time over threshold you would have to divide by the sampling frequency. |
||
""" | ||
Calculates the time over threshold (TOT) of waveforms. This is the width of the pulse above | ||
a threshold above the baseline of the waveform. | ||
|
||
Parameters | ||
---------- | ||
waveforms : ndarray | ||
r1 waveforms stored in a numpy array. | ||
thr: float | ||
Threshold above baseline | ||
|
||
Returns | ||
------- | ||
time_over_thr : list of int | ||
Number of samples with amplitude > thr | ||
Shape : (n_pix) | ||
|
||
""" | ||
return np.count_nonzero(waveforms > thr, axis=-1) | ||
|
||
|
||
class ImageExtractor(TelescopeComponent): | ||
def __init__(self, subarray, config=None, parent=None, **kwargs): | ||
""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add time parameters (FWHM, rise and fall time, and time over threshold) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this new method is missing in
__all__
at the top.