Code Monkey home page Code Monkey logo

repose's Introduction

Utility for processing raw Holter data V1.2

*** NOT FOR MEDICAL DIAGNOSTIC OR OTHER CLINICAL USE ***

Project Title

Repose: A utility for processing raw Holter monitor data

Description

Repose is software for converting raw sensor data from a 'Holter' cardiac monitor to useable body position, heart rate and respiration rate data (saved in .xlsx format). It will be useful for groups and individuals conducting physiological research that requires these variables to be recorded from a convenient portable device. Since EDF files are not human readable, an EDF reading utility is normally used to view, edit and export signals (in CSV or EXCEL format for example). This utility allows body position (e.g. supine, tilted, left/right side, prone etc.) and angles (tilt and rotation) to be calculated from a Bittium Faros 90, Faros 180 or Faros 360 Holter monitor, although it could be easily adapted for use with other brands.

Technology stack

Repose is written in Python 3.X and probably works best running on a desktop IDE (such as Spyder or Pycharm).

Dependencies

The following Python libraries should be installed prior to use:

  • pyedflib
  • datetime
  • scipy.signal
  • pandas
  • numpy
  • enum
  • os

Usage

The input file(s) should be in EDF format with at least the following data types:

  • ECG
  • Accelerometer_X
  • Accelerometer_Y
  • Accelerometer_Z

Other data types will be ignored. Any sampling rate (at least 12.5 Hz) is supported but we recommend 100 Hz for accelerometer and 250 Hz for ECG.

The output file (in Excel format) outputs data nominally at 1 Hz (one row per sample but this can be changed) with the following column headings:

  • Timestamp (format: YYYY-MM-DD HH-MM-SS)
  • RR (respiratory rate BPM)
  • HR (heart rate BPM)
  • Pos_Index (0 - 5)
  • Position (supine, prone, tilt, sitting, left_side, right_side)
  • Tilt (angle of the Holter body from horizontal: 0˚ - supine -> +90˚ - sitting)
  • Rotation (angle of rotation of the body: +180˚ - supine -> left side -> 0˚ - prone -> right side -> -180˚

Configuration/settings

The following variables can be changed (see asterisks(*) in the main loop):

  • filename of directory containing EDF files.
  • Averaging window length for heart rate and resp. rate (defaults = 15s, 25s respectively)
  • Calculation frequency ('calc every') for heart rate and resp. rate (defaults = 5s, 5s respectively)
  • Output frequency (i.e. how often a row of the .xls spreadsheet is written). Uses pandas frequency notation e.g. ('S' = every 1 second, try '0.1S', '10S' etc.)

Getting Started

  • Download the .py file to a local folder.
  • In a python IDE or text editor: edit line 172 so that the 'pathname' variable points to the pathname of a folder containing EDF files.
  • Running the program will sequentially read all files in the folder (e.g. 01-01-20.EDF)
  • For each EDF file in the folder, an excel file will be written to the folder using the same base filename with a .xlsx extension (e.g. 01-01-20.xlsx)
  • Note that large EDF files may take some time to process, e.g. processing a 24 hour EDF file will take approximately 40 minutes to complete (depending on local resources).

Known issues

Heart rate estimation uses a very lightweight algorithm that is not robust when heavy movement artifact is present on the ECG signal. Respiratory rate is similarly susceptible to motion artifact. Derivation of respiratory rate from acceleometer signals is not a tried and tested method in any case. If you want robust RR, try using a respiratory belt or other monitoring device. The accuracy nor the reliability have not been thoroughly tested or validated at any scale so treat results with caution.

repose's People

Contributors

justinphillips105 avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

repose's Issues

Parsing EDF error

Opening an issue and trying to fix error as I go along:

This is run in a venv with python: Python 3.10.5
File magic: 10-15-00.EDF: Biosig/EDF: European Data format

$ python repose.py

Reading: /Users/steve/Downloads/edf/10-15-00.EDF
Traceback (most recent call last):
  File "/Users/steve/Downloads/edf/repose.py", line 217, in <module>
    main()
  File "/Users/steve/Downloads/edf/repose.py", line 188, in main
    ecg, acc, sample_rate = get_data(pathname, filename)
  File "/Users/steve/Downloads/edf/repose.py", line 49, in get_data
    ecg_timestamp = [start_date +
  File "/Users/steve/Downloads/edf/repose.py", line 50, in <listcomp>
    datetime.timedelta(microseconds=1./sample_rate['ECG']*n*1e6)
KeyError: 'ECG'

Trying with repose_v1.2.py:

$ python repose_v1.2.py
Reading: /Users/steve/Downloads/edf/10-15-00.EDF
Sample rates: {'ECG_1': 250.0, 'ECG_2': 250.0, 'ECG_3': 250.0, 'Accelerometer_X': 25.0, 'Accelerometer_Y': 25.0, 'Accelerometer_Z': 25.0, 'Marker': 1.0, 'HRV': 5.0}
Recording start: Fri Dec 23 10:15:00 2022
Recording end:   Sat Dec 24 11:44:36 2022
Working...  *** WORKING VERSION ***
/Users/steve/Downloads/edf/repose_v1.2.py:118: FutureWarning: pad is deprecated and will be removed in a future version. Use ffill instead.
  hr = hr.resample('S').pad()
Traceback (most recent call last):
  File "/Users/steve/Downloads/edf/repose_v1.2.py", line 229, in <module>
    main()
  File "/Users/steve/Downloads/edf/repose_v1.2.py", line 205, in main
    rr = calculate_rr(acc, sample_rate, window_length=120, calc_every=5) # <- *
  File "/Users/steve/Downloads/edf/repose_v1.2.py", line 141, in calculate_rr
    for i in range(0, len(acc_tot)-rr_win,
TypeError: 'numpy.float64' object cannot be interpreted as an integer

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.