Skip to content

Commit feab0f2

Browse files
authored
Merge pull request #38 from newville/master
add Python version of data processing
2 parents b086568 + 15cd8a9 commit feab0f2

File tree

4 files changed

+71
-8
lines changed

4 files changed

+71
-8
lines changed
117 KB
Loading

docs/source/Py_HDF5_time_plot.png

377 KB
Loading

docs/source/process_hdf5.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import numpy as np
2+
import h5py
3+
4+
# Windows/MacOS: pip install wxmplot
5+
# Linux: canda install -c conda-forge wxpython && pip install wxmplot
6+
from wxmplot.interactive import plot
7+
8+
h5root = h5py.File('quadem_HDF5_001.h5')
9+
data = h5root['/entry/data/data'][()]
10+
ny, nx, nchans = data.shape # = (200, 2000, 11)
11+
npts = ny*nx
12+
data.shape = (npts, 11)
13+
sum_all = data[:, 6]
14+
15+
sample_time = 50e-6
16+
time = np.arange(npts)*sample_time
17+
18+
# Plot the first 0.5 second of data
19+
p1 = plot(time[:10000], sum_all[:10000],
20+
xlabel='Time (s)', ylabel='Sum of all diodes (nA)', title='Time Series')
21+
p1.save_figure('Py_HDF5_time_plot.png')
22+
23+
# Compute the FFT: note that for numpy.fft, the normalization is set with
24+
# 'norm', which can be one of 'backward', 'forward, or 'ortho'.
25+
# 'backward' is the NumPy default, 'forward' matches the IDL default.
26+
f = np.fft.fft(sum_all, norm='forward')
27+
# or one of:
28+
# f = np.fft.fft(sum_all) / npts
29+
# f = np.fft.fft(sum_all, norm='ortho') / np.sqrt(npts)
30+
31+
# Take the absolute value, first half of array
32+
nfft = npts//2
33+
f_abs = abs(f)[:nfft]
34+
35+
# Set the DC offset to 0
36+
f_abs[0] = 0
37+
38+
# Compute the frequency axis.
39+
# Note: The sampling rate is 20 kHz so the Nyquist frequency is 10 kHz
40+
freq = np.arange(nfft)/(nfft*2*sample_time)
41+
# or
42+
# freq = np.fft.fftfreq(npts, sample_time)
43+
44+
# Plot the power spectrum out to 1 kHz
45+
p2 = plot(freq[:20000], f_abs[:20000], ymin=0.01, ymax=100, ylog_scale=True,
46+
xlabel='Frequency (Hz)', ylabel=r'SumAll Intensity', color='red',
47+
title='Power Spectrum', win=2)
48+
49+
p2.save_figure('Py_HDF5_frequency_plot.png')

docs/source/streaming.rst

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@ Callbacks on address 11 contain all the data items, and the NDArray
1212
dimensions are [11, NumAverage_RBV] for each NDArray callback.
1313

1414
This is the medm screen for the HDF5 plugin used with the TetrAMM.
15-
The TetrAMM is configured with ValuesPerRead=5, so it is sending data at 20 kHz.
15+
The TetrAMM is configured with ValuesPerRead=5, so it is sending data at 20 kHz.
1616
AveragingTime is set to 0.1 seconds, so NumAverage_RBV is 2000.
1717

1818
.. figure:: HDF5_stream.png
1919
:align: center
2020

2121
|
2222
23-
The Array address in the plugin is set to 11, so it is receiving all 11 data items.
23+
The Array address in the plugin is set to 11, so it is receiving all 11 data items.
2424
FileWriteMode is set to Stream, so it will stream the NDArrays to the HDF5 file
25-
as they arrive. NumCapture is set to 200, so it will collect 200 arrays, each with
25+
as they arrive. NumCapture is set to 200, so it will collect 200 arrays, each with
2626
0.1 second of data giving a total of 20 seconds saved to disk.
2727
Pressing the Start button starts the streaming.
2828

@@ -52,7 +52,7 @@ This is the result of the Linux h5dump --contents on that file
5252
}
5353
}
5454

55-
The streamed data is in dataset /entry/data/data.
55+
The streamed data is in dataset /entry/data/data.
5656
This is the output of h5dump --header, looking at just that dataset.
5757
::
5858

@@ -87,11 +87,11 @@ In HDF5 convention the last array index is the fastest varying.
8787

8888
Saving all 11 data items is somewhat wastefull, since everything else can be calculated from just
8989
the 4 currents, which are the first 4 items in the arrays.
90-
We can save disk space by only saving the currents by using an ROI plugin between the
90+
We can save disk space by only saving the currents by using an ROI plugin between the
9191
quadEM driver and the HDF5 plugin.
9292

9393
This is the medm screen for an ROI plugin which gets its data on address 11 from the TetrAMM port.
94-
It is configured with a start of 0 and size of 4 on the first array dimension, and so will
94+
It is configured with a start of 0 and size of 4 on the first array dimension, and so will
9595
select only the 4 currents. The second dimension is set to auto size = Yes, so it will automatically
9696
select all elements in the second dimension, even if NumAverage_RBV changes.
9797

@@ -161,16 +161,30 @@ This is the output when the program is compiled and run:
161161
IDL> .go
162162
DATA DOUBLE = Array[11, 2000, 200]
163163
164-
This is the time-series plot. The data are highly periodic because the photodiodes were illuminated
164+
This is the time-series plot. The data are highly periodic because the photodiodes were illuminated
165165
by fluorescent lights.
166166

167167
.. figure:: IDL_HDF5_time_plot.png
168168
:align: center
169169

170-
|
171170

172171
This is the frequency plot. The peaks are almost exclusively 60 Hz and its odd and even harmonics.
173172
The odd harmonics are ~10-100 times less than 60 Hz, and the even harmonics are ~100-1000 times less than 60 Hz.
174173

175174
.. figure:: IDL_HDF5_frequency_plot.png
176175
:align: center
176+
177+
178+
Using Python, the data processing would be nearly identical, but with a few differences due to array and FFT conventions:
179+
180+
.. literalinclude:: process_hdf5.py
181+
182+
This will make a time-series plot of:
183+
184+
.. figure:: Py_HDF5_time_plot.png
185+
:align: center
186+
187+
and a frequency plot of:
188+
189+
.. figure:: Py_HDF5_frequency_plot.png
190+
:align: center

0 commit comments

Comments
 (0)