[ ]:
!pip install -q git+https://github.com/MideTechnology/endaq-python.git@development
exit() #forces a restart, it will make Colab crash - that is okay! just go on to run all the cells below
#Note that this is only needed in colab and not if running locally
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
|████████████████████████████████| 63 kB 1.1 MB/s
|████████████████████████████████| 93 kB 879 kB/s
|████████████████████████████████| 38.1 MB 1.3 MB/s
|████████████████████████████████| 83 kB 1.2 MB/s
Building wheel for endaq (PEP 517) ... done
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
google-colab 1.0.0 requires requests~=2.23.0, but you have requests 2.27.1 which is incompatible.
datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.
albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.2.9 which is incompatible.
Quick Start Guide¶
Introduction¶
This example script will use the enDAQ Python library to do the following:
Load open-source libraries
Load data directly from an IDE file recorded from an enDAQ sensor
Provide meta data about the sensor which recorded the data
Summary the contents of the file as a table of all sensor channels
Summarize all data in a dashboard
Get the accelerometer data
Apply a high pass filter
Plot the full time history
Plot the time history around the peak
Plot the time history in a specific time range
Shock & Vibration Analysis
Linear PSD
Octave spaced PSD
FFT
Shock response spectrum
Load Libraries¶
[ ]:
import endaq
endaq.plot.utilities.set_theme('endaq_light')
import plotly.express as px
import pandas as pd
import numpy as np
import scipy
Load Data¶
Using the endaq.ide.get_doc function, load in the contents of an IDE file. Note that this doesn’t load all data into memory yet.
[ ]:
doc = endaq.ide.get_doc('https://info.endaq.com/hubfs/data/Mining-Hammer/LOC__3__DAQ41551_11_01_02.ide')
Display meta data¶
[ ]:
print(f"Serial Number: {doc.recorderInfo['RecorderSerial']}")
print(f"Part Number: {doc.recorderInfo['PartNumber']}")
print(f"Recording Finished at {pd.to_datetime(doc.lastUtcTime,unit='s')}")
Serial Number: 9680
Part Number: S3-E2000D40
Recording Finished at 2021-03-25 03:32:32
Table of file contents¶
This uses the function endaq.ide.get_channel_table.
[ ]:
endaq.ide.get_channel_table(doc)
channel | name | type | units | start | end | duration | samples | rate | |
---|---|---|---|---|---|---|---|---|---|
0 | 8.0 | X (2000g) | Acceleration | g | 34:01.0868 | 34:15.0561 | 00:13.0693 | 273867 | 20000.07 Hz |
1 | 8.1 | Y (2000g) | Acceleration | g | 34:01.0868 | 34:15.0561 | 00:13.0693 | 273867 | 20000.07 Hz |
2 | 8.2 | Z (2000g) | Acceleration | g | 34:01.0868 | 34:15.0561 | 00:13.0693 | 273867 | 20000.07 Hz |
3 | 80.0 | X (40g) | Acceleration | g | 34:01.0717 | 34:15.0531 | 00:13.0814 | 55510 | 4018.33 Hz |
4 | 80.1 | Y (40g) | Acceleration | g | 34:01.0717 | 34:15.0531 | 00:13.0814 | 55510 | 4018.33 Hz |
5 | 80.2 | Z (40g) | Acceleration | g | 34:01.0717 | 34:15.0531 | 00:13.0814 | 55510 | 4018.33 Hz |
6 | 36.0 | Pressure/Temperature:00 | Pressure | Pa | 33:47.0105 | 34:12.0130 | 00:25.0025 | 26 | 1.04 Hz |
7 | 36.1 | Pressure/Temperature:01 | Temperature | °C | 33:47.0105 | 34:12.0130 | 00:25.0025 | 26 | 1.04 Hz |
8 | 47.0 | X | Rotation | dps | 34:00.0947 | 34:14.0633 | 00:13.0685 | 2765 | 202.04 Hz |
9 | 47.1 | Y | Rotation | dps | 34:00.0947 | 34:14.0633 | 00:13.0685 | 2765 | 202.04 Hz |
10 | 47.2 | Z | Rotation | dps | 34:00.0947 | 34:14.0633 | 00:13.0685 | 2765 | 202.04 Hz |
Dashboard of all data¶
Note this requires first loading in all data into memory. Then it will display bars of all data plotted from min to max.
[ ]:
channel_dict = {doc.channels[ch].name: endaq.ide.to_pandas(doc.channels[ch]) for ch in doc.channels}
fig = endaq.plot.dashboards.rolling_enveloped_dashboard(channel_dict, plot_as_bars=True, num_rows=1, num_cols=None)
fig.show()
Get accelerometer data¶
[ ]:
accel = endaq.ide.get_primary_sensor_data(doc=doc,measurement_type='accel',time_mode='seconds')
accel
X (2000g) | Y (2000g) | Z (2000g) | |
---|---|---|---|
timestamp | |||
2041.868560 | -24.046861 | 14.828584 | -9.588154 |
2041.868610 | -7.205801 | 14.828584 | -11.630245 |
2041.868660 | 14.496595 | 19.594306 | 20.532687 |
2041.868710 | 55.123480 | 13.240010 | 77.541059 |
2041.868760 | 83.944262 | 1.766976 | 84.518203 |
... | ... | ... | ... |
2055.561659 | 50.956620 | 13.946043 | 5.387179 |
2055.561709 | 62.068247 | 14.828584 | 7.939793 |
2055.561759 | 40.713089 | 14.828584 | 5.217005 |
2055.561809 | 2.864111 | 6.709206 | 3.855611 |
2055.561859 | -21.616192 | -9.176533 | 3.004740 |
273867 rows × 3 columns
Apply High Pass Filter¶
Filter away the DC offset, there are more filtering options at endaq.calc.filters.
[ ]:
accel = endaq.calc.filters.butterworth(accel,low_cutoff=1)
Plot Full Time History¶
endaq.plot.rolling_min_max_envelope() will reduce a large time history into a bar chart that plots from the min to the max so that it appears identical to the full time history plot yet is fast to generate and responsive.
[ ]:
fig_full_accel = endaq.plot.rolling_min_max_envelope(
accel,
desired_num_points=1000,
plot_as_bars=True,
opacity=0.7
).update_layout(
yaxis_title_text='Acceleration (g)',
xaxis_title_text='Time (s)',
title_text='Full Time History of Acceleration Data'
)
fig_full_accel.show()
Plot Time History Around Peak¶
endaq.plot.around_peak() finds and plots around the maximum value.
[ ]:
fig_peak = endaq.plot.around_peak(accel, num=1000).update_layout(
yaxis_title_text='Acceleration (g)',
xaxis_title_text='Time (s)',
title_text='Time History Around Peak',
legend_title_text=''
)
fig_peak.show()
Time History at Specific Time¶
[ ]:
fig_time = px.line(accel[2044.6:2044.7]).update_layout(
yaxis_title_text='Acceleration (g)',
xaxis_title_text='Time (s)',
title_text='Time History at Specific Time',
legend_title_text=''
)
fig_time.show()
Analysis¶
Linear PSD¶
Calculate the PSD using endaq.calc.psd.welch()
[ ]:
#Calculate PSD
psd = endaq.calc.psd.welch(accel, bin_width=2)
fig_psd = px.line(
psd,
log_x=True,
log_y=True
).update_layout(
xaxis_title='Frequency (Hz)',
yaxis_title='Acceleration (g^2/Hz)',
title_text='PSD with 2 Hz Bin Width',
legend_title_text=''
)
fig_psd.show()
Octave PSD¶
Now convert to octave using endaq.calc.psd.to_octave()
[ ]:
#Calculate PSD with a finer bin width to convert to octave
psd = endaq.calc.psd.welch(accel, bin_width=0.1)
#Convert to Octave
oct_psd = endaq.calc.psd.to_octave(psd,octave_bins=6)
fig_psd_oct = px.line(
oct_psd,
log_x=True,
log_y=True
).update_layout(
xaxis_title='Frequency (Hz)',
yaxis_title='Acceleration (g^2/Hz)',
title_text='1/6 Octave PSD',
legend_title_text=''
)
fig_psd_oct.show()
/usr/local/lib/python3.7/dist-packages/endaq/calc/psd.py:172: RuntimeWarning:
empty frequency bins in re-binned PSD; original PSD's frequency spacing is too coarse
FFT¶
See endaq.calc.fft for a full list of FFT functions.
[ ]:
#Calculate FFT
fft = endaq.calc.fft.rfft(accel[2044.6:2044.7])
#Plot
fig_fft = px.line(fft).update_layout(
xaxis_title='Frequency (Hz)',
yaxis_title='Acceleration (g)',
title_text='FFT of Time Range 2044.6 to 2044.7 Seconds',
legend_title_text=''
)
fig_fft.show()
Shock Response Spectrum¶
This uses endaq.calc.utils.logfreqs() to define log spaced frequencies to use, then passes those to endaq.calc.shock.shock_spectrum() along with the time history data to compute the shock spectrum.
[ ]:
#Calculate for reduced time series
accel_zoomed = accel[2044.6:2044.7]
#Define frequencies to calculate responses at
freqs = endaq.calc.utils.logfreqs(accel_zoomed, bins_per_octave=12, init_freq=0.5)
#Calculate pseudo velocity shock spectrum
pvss = endaq.calc.shock.shock_spectrum(accel_zoomed, freqs=freqs, damp=0.05, mode='pvss')
#Convert to in/s (currently in g/s)
pvss = pvss * 9.81 * 39.37
#Plot
fig_pvss = px.line(
pvss,
log_x=True,
log_y=True
).update_layout(
xaxis_title='Natural Frequency (Hz)',
yaxis_title='Peak Pseudo Velocity (in/s)',
legend_title_text='',
title_text='Psuedo Velocity Shock Spectrum'
)
fig_pvss.show()
/usr/local/lib/python3.7/dist-packages/endaq/calc/utils.py:61: RuntimeWarning:
the data's duration is too short to accurately represent an initial frequency of 0.500 Hz