Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/docs-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ jobs:

env:
OS: ubuntu-latest
PYTHON-VERSION: "3.9"
PYTHON-VERSION: "3.13"

runs-on: ubuntu-latest

steps:

- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.9"
python-version: "3.13"

- name: Install Pandoc
run: sudo apt-get install pandoc
Expand All @@ -40,7 +40,7 @@ jobs:
run: python -m pip install --upgrade pip

- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Get pip cache location
id: pip-cache
Expand All @@ -57,10 +57,10 @@ jobs:
print(f'text={now.year}/{now.month}-part{1 + now.day // 8}')" >> $GITHUB_OUTPUT

- name: Load pip cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: doctests-${{ runner.os }}-Python3.9-${{ steps.date.outputs.text }}-pip-${{ hashFiles('**/setup.py', './.github/workflows/unit-tests.yml') }}
key: doctests-${{ runner.os }}-Python3.13-${{ steps.date.outputs.text }}-pip-${{ hashFiles('**/setup.py', './.github/workflows/unit-tests.yml') }}

- name: Install spellcheck library
run: sudo apt-get install libenchant-2-2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-to-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@master

- name: Set up Python 3.9
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.9

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']

env:
OS: ${{ matrix.os }}
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ cython_debug/
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
.vscode/*

# Generated files
.idea/**/contentModel.xml
Expand Down Expand Up @@ -244,3 +245,6 @@ fabric.properties

# Test files
*_scratch.ipynb

# Backup files
*.bak
4 changes: 2 additions & 2 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ version: 2

# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
os: ubuntu-24.04
tools:
python: "3.8"
python: "3.13"

# Build documentation in the docs/ directory with Sphinx
sphinx:
Expand Down
30 changes: 25 additions & 5 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,35 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
#

import pkg_resources
import codecs
import os.path
import sys

# go up a dir and include that guy =
p = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.insert(0, p)

import endaq

# -- Project information -----------------------------------------------------

def get_version(rel_path):
""" Read the version number directly from the source. """
with codecs.open(rel_path, 'r') as fp:
for line in fp:
if line.startswith('__version__'):
delim = '"' if '"' in line else "'"
return line.split(delim)[1]
else:
raise RuntimeError("Unable to find version string.")


project = 'enDAQ'
copyright = '2021, Mide Technology Corp.'
author = ''

# The full version, including alpha/beta/rc tags
release = pkg_resources.get_distribution("endaq").version
release = get_version(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'endaq', '__init__.py')))

# The short X.Y version
version = '.'.join(release.split(".")[:2])

Expand All @@ -44,6 +61,7 @@
'sphinx.ext.ifconfig',
'sphinx.ext.githubpages',
'sphinx_plotly_directive',
'sphinxcontrib.spelling',
'nbsphinx',
]

Expand All @@ -64,7 +82,7 @@
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
language = 'en'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
Expand Down Expand Up @@ -100,7 +118,9 @@
"github_url": "https://github.com/MideTechnology/endaq-python",
"twitter_url": "https://twitter.com/enDAQ_sensors",
"collapse_navigation": True,
"google_analytics_id": "G-E9QXH4H5LP",
"analytics": {
"google_analytics_id": "G-E9QXH4H5LP",
}
}

# Add any paths that contain custom static files (such as style sheets) here,
Expand Down
62 changes: 62 additions & 0 deletions docs/endaq/ide_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,68 @@ parameters:

doc3 = get_doc("tests/test.ide", start="5s", end="10s")

Accessing measurement data in a Dataset/IDE file
------------------------------------------------
An enDAQ device consists of many different sensors, and enDAQ devices record their measurement data into separate
Channels that correspond to the sensor taking the measurement. This is done because each Channel samples at a different
rate, so while Channel 59 (the Control Pad Pressure/Temperature/Humidity sensor) samples at 10 Hz, Channel 8 (the main
analog accelerometer channel) may sample at 20000 Hz. Channels themselves consist of different subchannels, which may be
different axes (X, Y, Z) or completely different measurements like temperature and pressure. All subchannels in a
channel are sampled at approximately the same time.

The Channel data are stored in the ``channels`` property of a Dataset, which is returned from the :py:func:`~endaq.ide.get_doc() function. The easiest way to access this is to convert it to a
Pandas DataFrame using :py:func:`~endaq.ide.to_pandas(doc)`. Visit `our internal documentation <https://docs.endaq.com/en/latest/webinars/Webinar_Introduction_NumPy_and_Pandas.html#Pandas>`_
for some quick tips on Pandas, or go `straight to the source <https://pandas.pydata.org/docs/>`_.

.. code:: python3

import endaq.ide
# Read in a doc
doc2 = endaq.ide.get_doc("https://drive.google.com/file/d/1t3JqbZGhuZbIK9agH24YZIdVE26-NOF5/view?usp=sharing")
# List the available Channels
print(f"{doc2.channels=}")
# Convert the Control Pad Pressure/Temperature/Humidity Channel (Channel 59) to a Pandas DataFrame
control_pad_data = endaq.ide.to_pandas(doc2.channels[59])
# Print the subchannel names
print(f"{control_pad_data.columns=}")
# Print the max and min temperatures seen
print(f"Max Temp={control_pad_data['Control Pad Temperature'].max()}, Min Temp={control_pad_data['Control Pad Temperature'].min()}")

The output of the above code is:

.. code-block::

doc2.channels={32: <Channel 32 '16g DC Acceleration': Acceleration (g)>, 80: <Channel 80 '8g DC Acceleration': Acceleration (g)>, 36: <Channel 36 'Pressure/Temperature': Pressure (Pa), Temperature (°C)>, 70: <Channel 70 'Relative Orientation': Quaternion (q)>, 59: <Channel 59 'Control Pad Pressure/Temperature/Humidity': Pressure (Pa), Temperature (°C)>, 76: <Channel 76 'Light Sensor': Light (Ill), Light (Index)>}
control_pad_data.columns=Index(['Control Pad Pressure', 'Control Pad Temperature'], dtype='object')
Max Temp=24.899999618530273, Min Temp=24.260000228881836

Note that by default, :py:func:`~endaq.ide.to_pandas(doc)` uses ``datetime`` for the index format, meaning the
measurements are accessed based on the absolute time they were recorded. Users often prefer to access the data using
``timedelta``, the amount of time since the recording started. Using this, to get the duration of the Control Pad data
and the average of the first 5 seconds, we could use:

.. code:: python3

import endaq.ide
import pandas as pd
# Read in a doc
doc2 = endaq.ide.get_doc("https://drive.google.com/file/d/1t3JqbZGhuZbIK9agH24YZIdVE26-NOF5/view?usp=sharing")
# Convert the Control Pad Pressure/Temperature/Humidity Channel (Channel 59) to a Pandas DataFrame
control_pad_data = endaq.ide.to_pandas(doc2.channels[59], time_mode='timedelta')
# Print the time duration
print(f"Duration={control_pad_data.index[-1]-control_pad_data.index[0]}")
# Print the mean of the first 5 seconds
print(f"{control_pad_data[pd.Timedelta(seconds=0):pd.Timedelta(seconds=5)].mean()}")

The output of the above code is:

.. code-block::

Duration=0 days 00:00:17.931518
Control Pad Pressure 101728.414991
Control Pad Temperature 24.607073
dtype: float64

Summarizing IDE files: :py:func:`endaq.ide.get_channel_table()`
---------------------------------------------------------------

Expand Down
19 changes: 10 additions & 9 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
Sphinx>=5.0.2
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
Sphinx>=8.1.3
sphinxcontrib-applehelp==2.0.0
sphinxcontrib-devhelp==2.0.0
sphinxcontrib-htmlhelp==2.1.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
sphinxcontrib-spelling==8.0.1

pydata-sphinx-theme==0.7.1
pydata-sphinx-theme==0.16.1
sphinx-plotly-directive==0.1.3
nbsphinx==0.8.8
ipython==8.10
nbsphinx==0.9.7
ipython==9.2.0
19 changes: 19 additions & 0 deletions docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,29 @@ sinusoids
centric

enDAQ
Mide
NumPy
SciPy
Pandas
Plotly
Matplotlib
Colab
Jupyter
Seaborn
Tukey
Chebyshev
Butterworth
Fourier
Heatmaps
ide
calc
endaq
accel
str
psd
pkl
kth
GetDataBuilder

basename
pathname
Expand All @@ -24,6 +39,7 @@ subchannel
subchannels
DataFrame
dataframe
dataframes
ndarray
dropdown
iterable
Expand All @@ -36,10 +52,13 @@ periodogram
periodograms
spectrogram
spectrograms
spectrums
resample
resampled
resampling
SNE
integrations
quaternion
quaternions
Welch
kurtosis
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"## Introduction\n",
"This notebook serves as an introduction to Python for a mechanical engineer looking to plot and analyze some acceleration data in a CSV file. Being a Colab, this tool can freely be used without installing anything.\n",
"\n",
"For more information on making the swith to Python see [enDAQ's blog, Why and How to Get Started in Python for a MATLAB User](https://blog.endaq.com/why-and-how-to-get-started-in-python-for-a-matlab-user).\n",
"For more information on making the switch to Python see [enDAQ's blog, Why and How to Get Started in Python for a MATLAB User](https://blog.endaq.com/why-and-how-to-get-started-in-python-for-a-matlab-user).\n",
"\n",
"This is part of our webinar series on Python for Mechanical Engineers:\n",
"\n",
Expand Down Expand Up @@ -1493,7 +1493,7 @@
},
"source": [
"### FFT from PSD\n",
"Here we can use the output of a PSD and convet it to a typical DFT. This has the benefit of allowing you to explicitely define the frequency bin width."
"Here we can use the output of a PSD and convert it to a typical DFT. This has the benefit of allowing you to explicitly define the frequency bin width."
]
},
{
Expand Down Expand Up @@ -1887,4 +1887,4 @@
},
"nbformat": 4,
"nbformat_minor": 4
}
}
6 changes: 3 additions & 3 deletions docs/webinars/Webinar_Introduction_NumPy_and_Pandas.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"\n",
"1. [Get Started with Python](https://colab.research.google.com/drive/1_pcGtgJleapV9tz5WfuRuqfWryjqhPHy#scrollTo=ikUJITDDIp19)\n",
" * Blog: [Get Started with Python: Why and How Mechanical Engineers Should Make the Switch](https://blog.endaq.com/get-started-with-python-why-how-mechanical-engineers-should-make-the-switch)\n",
"2. **Introduction to Numpy & Pandas**\n",
"2. **Introduction to NumPy & Pandas**\n",
" * [Watch Recording of This](https://info.endaq.com/pandas-and-numpy-for-data-analysis-webinar)\n",
"3. [Introduction to Plotly](https://colab.research.google.com/drive/1pag2pKQQW5amWgRykAH8uMAPqHA2yUfU?usp=sharing)\n",
"4. [Introduction of the enDAQ Library](https://colab.research.google.com/drive/1WAtQ8JJC_ny0fki7eUABACMA-isZzKB6)\n",
Expand Down Expand Up @@ -505,7 +505,7 @@
"id": "cv0nw1SnLb5x"
},
"source": [
"Logspace is the equivalent of rasing a base by a linspaced array."
"Logspace is the equivalent of raising a base by a linspaced array."
]
},
{
Expand Down Expand Up @@ -7821,7 +7821,7 @@
"source": [
"### Installation\n",
"\n",
"The code is live on [GitHub](https://github.com/MideTechnology/endaq-python), [PyPI](https://pypi.org/project/endaq/), and cleaner documentation is in process that will eventually live on a subdomain of endaq.com.\n",
"The code is live on [GitHub](https://github.com/MideTechnology/endaq-python), [PyPI](https://pypi.org/project/endaq/), and cleaner documentation lives at [docs.endaq.com](https://docs.endaq.com/en/latest/).\n",
"\n",
"It can easily be installed with pip."
]
Expand Down
4 changes: 2 additions & 2 deletions docs/webinars/Webinar_Introduction_Plotly.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@
},
"source": [
"### [ggplot](https://plotnine.readthedocs.io/en/stable/)\n",
"Introduces a \"grammer of graphics\" logic to plotting data which allows explicit mapping of data to the visual representation. This is something plotly express excels at."
"Introduces a \"grammar of graphics\" logic to plotting data which allows explicit mapping of data to the visual representation. This is something plotly express excels at."
]
},
{
Expand Down Expand Up @@ -1304,7 +1304,7 @@
"id": "u_pZeZ5An8PG"
},
"source": [
"Now let's get crazy and customize all the \"common\" settings. But note that there are a LOT of different parameters that can be explicitely defined. Remember, Plotly has very thorough documentation, so check it out!\n",
"Now let's get crazy and customize all the \"common\" settings. But note that there are a LOT of different parameters that can be explicitly defined. Remember, Plotly has very thorough documentation, so check it out!\n",
"* [Figure Layout](https://plotly.com/python/reference/layout/)\n",
"* [X Axis](https://plotly.com/python/reference/layout/xaxis/)\n",
"* [Y Axis](https://plotly.com/python/reference/layout/yaxis/)\n",
Expand Down
Loading