Logo

Python Intan

Docs Python License: MIT PyPI version

python-intan is a Python package for working with RHX Controller devices and EMG data acquired from Intan Technologies systems. It provides utilities for:

  • Reading .rhd and .dat data files

  • Preprocessing and feature extraction

  • Integration with external hardware for closed-loop applications

Whether you’re analyzing offline data or streaming real-time EMG from the RHX system, python-intan aims to make the workflow seamless and modular.


Contents


Contributions

We welcome contributions to the python-intan package! If you have ideas for new features, bug fixes, or improvements, please feel free to submit a pull request or open an issue. Have a look at our contribution guide for further guidance. Writing code isn’t the only way you can contribute:

  • review pull requests

  • develop tutorials, presentations, and other educational materials

  • help with outreach or onboarding new contributors

If you’re unsure where to start or how your skills fit in, reach out! You can ask on the forum or here, on GitHub, by leaving a comment on a relevant issue that is already open.

If you are new to contributing to open source, this guide helps explain why, what, and how to get involved.


Installation

Create a virtual environment using conda or venv:

conda create -n intan python=3.10
conda activate intan

or

python -m venv intan
source intan/bin/activate  # On Windows use: intan\Scripts\activate

(Optional) Enable CUDA support for GPU acceleration (if available):

conda install cudatoolkit cudnn=11

or

sudo apt-get install cuda
pip install tensorflow[and-cuda] nvidia-cudnn-cu12 # CUDA 12.5 latest pip option as of 5/13/25

This repo can be installed from PyPi using pip:

pip install python-intan

or clone & install the repository from GitHub for the latest features:

git clone https://github.com/Neuro-Mechatronics-Interfaces/python-intan.git
cd python-intan
pip install -e .

Getting Started

We can quickly load EMG signals from an Intan .rhd file.

import intan
result = intan.io.load_rhd_file() # Opens Popup window to select file, or pass filepath

.dat files are also supported

dat_folderpath = "path/to/your/dat/files"
result = intan.io.load_dat_file(dat_folderpath)

The result dictionary contains:

  • amplifier_data: Raw EMG data (shape: channels x samples)

  • amplifier_channels: Channel metadata (names, gain, etc.)

  • frequency_parameters: Sampling rate information for the amplifier, aux, and digital inputs

  • t_amplifier: Time vector for the amplifier data

  • board_adc_data: ADC data from the board

Loading multiple .rhd files with the option to concatenate can be done with:

result_list = intan.io.load_rhd_files(concatenate=True)

Some quick filtering to remove DC offset and noise:

fs = result['frequency_parameters']['amplifier_sample_rate']
emg = result['amplifier_data']  # Shape: (channels, samples)

notch_emg = intan.processing.notch_filter(emg, fs, f0=60) # 60Hz notch filter
filt_emg = intan.processing.filter_emg(notch_emg, 'bandpass', fs, lowcut=10, highcut=500) # 10-500Hz bandpass filter

We can visualize the raw EMG data using the plotting module. Let’s use a waterfall plot to look at the raw activity across a subset of channels:

t_s = result['t_amplifier']
chans = range(0, 64)  # Selecting channels to plot
intan.plotting.waterfall(filt_emg, chans, t_s, plot_title='Intan EMG data')

If there is a single channel of interest, we can plot it directly by name or index:

intan.plotting.plot_channel_by_name('A-005', result)  # By name (Be sure the channel name exists)
intan.plotting.plot_channel_by_index(8, result)  # By index

Some other processing features:

# Normalize the EMG data
norm_emg = intan.processing.normalize(filt_emg, method='zscore')  # Z-score normalization

# Downsample the EMG data
downsampled_emg = intan.processing.downsample(filt_emg, factor=2)  # Downsample by a factor of 2

# Rectify
rectified_emg = intan.processing.rectify(filt_emg)  # Rectify the EMG data

# Rolling RMS window
samples = int(0.1 * fs)  # 100ms window
rms_emg = intan.processing.window_rms(filt_emg, window_size=samples)  # 100ms RMS window

Project Structure

intan/
├── io/                 # Load and parse Intan .rhd or .rhs files
├── processing/         # Filtering, normalization, and segmentation
├── control/            # Real-time control scripts for robot arm or other peripherals
├── plotting/      # Plotting and GUI scripts

load_rhd_demo.py        # Quick-start script for plotting waveform data
requirements.txt
README.md

Future Improvements

  • [x] Real-time gesture decoding via TCP from RHX

  • [x] Serial control for wearable robotics (e.g. grippers, arms)

  • [x] CNN feature pipeline support

  • [ ] GUI for real-time signal monitoring

  • [ ] Public datasets with training/testing support

  • [ ] Cross-platform support for macOS/Linux (currently optimized for Windows)


Citation

This package can be cited as follows:

@software{Shulgach_Python_Intan_2025,
  author = {Shulgach, Jonathan, Murphy, Max and Foy, Adrian},
  title = {{Python Intan Package}},
  year = {2025},
  month = {05},
  version = {0.1.0},
  url = {https://github.com/Neuro-Mechatronics-Interfaces/python-intan},
  note = "{\tt jshulgac@andrew.cmu.edu}"
}

License

This project is licensed under the MIT License — see the License File for details.

Tutorials

Examples

API Documentation