From 748f74b19096f78ad463e9e2f1ebd8ead3c75569 Mon Sep 17 00:00:00 2001 From: Stefano Moia Date: Thu, 11 Mar 2021 23:32:38 +0100 Subject: [PATCH 1/2] Remove scripts and cli and dependencies for those --- peakdet/cli/__init__.py | 0 peakdet/cli/run.py | 233 ---------------------------------------- scripts/environment.yml | 15 --- scripts/hrv_pipeline | 125 --------------------- setup.cfg | 4 +- 5 files changed, 1 insertion(+), 376 deletions(-) delete mode 100644 peakdet/cli/__init__.py delete mode 100644 peakdet/cli/run.py delete mode 100644 scripts/environment.yml delete mode 100644 scripts/hrv_pipeline diff --git a/peakdet/cli/__init__.py b/peakdet/cli/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/peakdet/cli/run.py b/peakdet/cli/run.py deleted file mode 100644 index 72fc06b..0000000 --- a/peakdet/cli/run.py +++ /dev/null @@ -1,233 +0,0 @@ -# -*- coding: utf-8 -*- -import glob -import os -import sys -import warnings -import matplotlib -matplotlib.use('WXAgg') -from gooey import Gooey, GooeyParser -import peakdet - -TARGET = 'pythonw' if sys.platform == 'darwin' else 'python' -TARGET += ' -u ' + os.path.abspath(__file__) - -LOADERS = dict( - rtpeaks=peakdet.load_rtpeaks, - MRI=peakdet.load_physio -) - -MODALITIES = dict( - ECG=([5., 15.], 'bandpass'), - PPG=(2, 'lowpass'), - RESP=([0.05, 0.5], 'bandpass') -) - -ATTR_CONV = { - 'Average NN intervals': 'avgnn', - 'Root mean square of successive differences': 'rmssd', - 'Standard deviation of NN intervals': 'sdnn', - 'Standard deviation of successive differences': 'sdsd', - 'Number of successive differences >50 ms': 'nn50', - 'Percent of successive differences >50 ms': 'pnn50', - 'Number of successive differences >20 ms': 'nn20', - 'Percent of successive differences >20 ms': 'pnn20', - 'High frequency HRV hfHRV': 'hf', - 'Log of high frequency HRV, log(hfHRV)': 'hf_log', - 'Low frequency HRV, lfHRV': 'lf', - 'Log of low frequency HRV, log(lfHRV)': 'lf_log', - 'Very low frequency HRV, vlfHRV': 'vlf', - 'Log of very low frequency HRV, log(vlfHRV)': 'vlf_log', - 'Ratio of lfHRV : hfHRV': 'lftohf', - 'Peak frequency of hfHRV': 'hf_peak', - 'Peak frequency of lfHRV': 'lf_peak' -} - - -@Gooey(program_name='Physio pipeline', - program_description='Physiological processing pipeline', - default_size=(800, 600), - target=TARGET) -def get_parser(): - """ Parser for GUI and command-line arguments """ - parser = GooeyParser() - parser.add_argument('file_template', metavar='Filename template', - widget='FileChooser', - help='Select a representative file and replace all ' - 'subject-specific information with a "?" symbol.' - '\nFor example, subject_001_data.txt should ' - 'become subject_???_data.txt and will expand to ' - 'match\nsubject_001_data.txt, subject_002_data.' - 'txt, ..., subject_999_data.txt.') - - inp_group = parser.add_argument_group('Inputs', 'Options to specify ' - 'format of input files') - inp_group.add_argument('--modality', metavar='Modality', default='ECG', - choices=list(MODALITIES.keys()), - help='Modality of input data.') - inp_group.add_argument('--fs', metavar='Sampling rate', default=1000.0, - type=float, - help='Sampling rate of input data.') - inp_group.add_argument('--source', metavar='Source', default='rtpeaks', - choices=list(LOADERS.keys()), - help='Program used to collect the data.') - inp_group.add_argument('--channel', metavar='Channel', default=1, type=int, - help='Which channel of data to read from data ' - 'files.\nOnly applies if "Source" is set to ' - 'rtpeaks.') - - out_group = parser.add_argument_group('Outputs', 'Options to specify ' - 'format of output files') - out_group.add_argument('-o', '--output', metavar='Filename', - default='peakdet.csv', - help='Output filename for generated measurements.') - out_group.add_argument('-m', '--measurements', metavar='Measurements', - nargs='+', widget='Listbox', - choices=list(ATTR_CONV.keys()), - default=['Average NN intervals', - 'Standard deviation of NN intervals'], - help='Desired physiological measurements.\nChoose ' - 'multiple with shift+click or ctrl+click.') - out_group.add_argument('-s', '--savehistory', metavar='Save history', - action='store_true', - help='Whether to save history of data processing ' - 'for each file.') - - edit_group = parser.add_argument_group('Workflow arguments (optional!)', - 'Options to specify modifications ' - 'to workflow') - edit_group.add_argument('-n', '--noedit', metavar='Editing', - action='store_true', - help='Turn off interactive editing.') - edit_group.add_argument('-t', '--thresh', metavar='Threshold', default=0.2, - type=float, - help='Threshold for peak detection algorithm.') - - return parser - - -def workflow(*, file_template, modality, fs, source='MRI', channel=1, - output='peakdet.csv', savehistory=True, noedit=False, thresh=0.2, - measurements=ATTR_CONV.keys()): - """ - Basic workflow for physiological data - - Parameters - ---------- - file_template : str - Template filename for data inputs - modality : {'ECG', 'PPG', 'RESP'} - Currently support data modalities - fs : float - Sampling rate of input data - source : {'rtpeaks', 'MRI'}, optional - How data were acquired. Default: 'MRI' - channel : int, optional - Which channel of data to analyze; only applies if source is 'rtpeaks'. - Default: 1 - output : str, optional - Desired output filename. Default: 'peakdet.csv' - savehistory : bool, optional - Whether to save editing history of each file with - ``peakdet.save_history``. History will be used if this workflow is - run again on the samed data files. Default: True - noedit : bool, optional - Whether to disable interactive editing of physio data. Default: False - thresh : [0, 1] float, optional - Threshold for peak detection. Default: 0.2 - measurements : list, optional - Which HRV-related measurements to save from data. See ``peakdet.HRV`` - for available measurements. Default: all available measurements. - """ - - # output file - print('OUTPUT FILE:\t\t{}\n'.format(output)) - # grab files from file template - print('FILE TEMPLATE:\t{}\n'.format(file_template)) - files = glob.glob(file_template, recursive=True) - - # convert measurements to peakdet.HRV attribute friendly names - try: - print('REQUESTED MEASUREMENTS: {}\n'.format(', '.join(measurements))) - except TypeError: - raise TypeError('It looks like you didn\'t select any of the options ' - 'specifying desired output measurements. Please ' - 'select at least one measurement and try again.') - measurements = [ATTR_CONV[attr] for attr in measurements] - - # get appropriate loader - load_func = LOADERS[source] - - # check if output file exists -- if so, ensure headers will match - head = 'filename,' + ','.join(measurements) - if os.path.exists(output): - with open(output, 'r') as src: - eheader = src.readlines()[0] - # if existing output file does not have same measurements are those - # requested on command line, warn and use existing measurements so - # as not to totally fork up existing file - if eheader != head: - warnings.warn('Desired output file already exists and requested ' - 'measurements do not match with measurements in ' - 'existing output file. Using the pre-existing ' - 'measurements, instead.') - measurements = [f.strip() for f in eheader.split(',')[1:]] - head = '' - # if output file doesn't exist, nbd - else: - head += '\n' - - with open(output, 'a+') as dest: - dest.write(head) - # iterate through all files and do peak detection with manual editing - for fname in files: - fname = os.path.relpath(fname) - print('Currently processing {}'.format(fname)) - - # if we want to save history, this is the output name it would take - outname = os.path.join(os.path.dirname(fname), - '.' + os.path.basename(fname) + '.json') - - # let's check if history already exists and load that file, if so - if os.path.exists(outname): - data = peakdet.load_history(outname) - else: - # load data with appropriate function, depending on source - if source == 'rtpeaks': - data = load_func(fname, fs=fs, channel=channel) - else: - data = load_func(fname, fs=fs) - - # filter - flims, method = MODALITIES[modality] - data = peakdet.filter_physio(data, cutoffs=flims, - method=method) - - # perform peak detection - data = peakdet.peakfind_physio(data, thresh=thresh) - - # edit peaks, if desired (HIGHLY RECOMMENDED) - # we'll do this even if we loaded from history - # just to give another chance to check things over - if not noedit: - data = peakdet.edit_physio(data) - - # save back out to history, if desired - if savehistory: - peakdet.save_history(outname, data) - - # keep requested outputs - hrv = peakdet.HRV(data) - outputs = ['{:.5f}'.format(getattr(hrv, attr, '')) - for attr in measurements] - - # save as we go so that interruptions don't screw everything up - dest.write(','.join([fname] + outputs) + '\n') - - -def main(): - opts = get_parser().parse_args() - workflow(**vars(opts)) - - -if __name__ == '__main__': - main() diff --git a/scripts/environment.yml b/scripts/environment.yml deleted file mode 100644 index 888e116..0000000 --- a/scripts/environment.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: peakdet -channels: - - conda-forge -dependencies: - - python=3.6 - - matplotlib - - numpy - - pillow - - pip - - psutil - - scipy - - wxpython - - pip: - - git+https://github.com/chriskiehl/Gooey.git#egg=gooey - - git+https://github.com/physiopy/peakdet.git#egg=peakdet diff --git a/scripts/hrv_pipeline b/scripts/hrv_pipeline deleted file mode 100644 index 57c7045..0000000 --- a/scripts/hrv_pipeline +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env bash - -function Usage { - cat << USAGE - -Description: - - hrv_pipeline runs a simple peak detection workflow using the peakdet - package (see https://github.com/physiopy/peakdet). It accepts raw - physiological files and outputs a summary file with requested HRV - measurements. - - The first time this script is run, it will check for a conda installation - and install it if doesn't already exist. It will also create a peakdet - environment for use. This may take some time, but will only need to be done - once. Thereafter, you can use hrv_pipeline -u to upgrade the pipeline. - -Optional arguments: - - -i ONLY install the pipeline. This should only be done once; after - that point this should have no effect. Calling this program - without specifying this option will also install the pipeline. - -u Upgrade the pipeline. You probably only need to do this once in - a blue moon. - -USAGE - return 0 -} - -function check_conda_install() { - # check for existence of conda.sh file and source if it exists - # if it doesn't, assume miniconda isn't installed and go for gold - condash="${HOME}/miniconda3/etc/profile.d/conda.sh" - if [ -f "${condash}" ]; then - source ${condash} - else - echo 'Installing miniconda3. This should only happen once but might take a while.' - # download miniconda installer - miniconda_installer=${PWD}/miniconda.sh - curl -sSL --retry 5 -o ${miniconda_installer} ${URL} - /bin/bash ${miniconda_installer} -b -p ${HOME}/miniconda3 - rm -f ${miniconda_installer} - # source conda.sh - source ${condash} - # set some conda config defaults - conda config --system --prepend channels conda-forge - conda config --system --set auto_update_conda false - conda config --system --set show_channel_urls true - fi -} - -function check_peakdet_env() { - # see if peakdet env exists - if [ -z "$( conda env list | grep peakdet )" ]; then - echo 'Creating peakdet environment. This should only happen once but might take a while' - env_file=https://raw.githubusercontent.com/physiopy/peakdet/master/scripts/environment.yml - curl -sSL --retry 5 -o ${PWD}/env.yml ${env_file} - conda env create -q -f ${PWD}/env.yml - rm -f ${PWD}/env.yml - else - conda activate peakdet - fi - - if [ "$INSTALL_ONLY" -eq 1 ]; then - conda deactivate - fi -} - -# check command line options -UPDATE=0 -INSTALL_ONLY=0 -while getopts "hui" OPT; do - case $OPT in - h) - Usage >&2 - exit 0 - ;; - i) - INSTALL_ONLY=1 - ;; - u) - UPDATE=1 - ;; - esac -done - -# get OS specifics -if [ "$( uname )" == "Darwin" ]; then - # Gooey requires framework build on Macs - COMMAND="pythonw ${HOME}/miniconda3/envs/peakdet/lib/python3.6/site-packages/peakdet/cli/run.py" - URL='https://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-x86_64.sh' -else - COMMAND="python ${HOME}/miniconda3/envs/peakdet/lib/python3.6/site-packages/peakdet/cli/run.py" - URL='https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh' -fi - -# if we're just updating -if [ "$UPDATE" -eq 1 ]; then - check_conda_install - check_peakdet_env - echo 'Updating peakdet for hrv_pipeline' - pip install -U --no-deps --no-cache-dir https://github.com/physiopy/peakdet/tarball/master -# if we're just installing -elif [ "$INSTALL_ONLY" -eq 1 ]; then - check_conda_install - check_peakdet_env -# "normal" run-through -else - check_conda_install - check_peakdet_env - if [ ! -f "${COMMAND#* }" ]; then - cat << REINSTALL -Peakdet appears to have been improperly installed. Please remove the peakdet -environment in conda by typing: - - source ${HOME}/miniconda3/etc/profile.d/conda.sh - conda remove -y -n peakdet --all - -and running this script again. -REINSTALL - exit 1 - else - ${COMMAND} - fi -fi diff --git a/setup.cfg b/setup.cfg index 76c09b1..2fe3e98 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,14 +24,12 @@ provides = [options] python_requires = >=3.6.1 install_requires = - Gooey matplotlib >=3.1.1, !=3.3.0rc1 numpy >=1.9.3, !=*rc* pillow psutil PyYAML >=5.1, !=*rc* scipy - wxpython tests_require = pytest >=5.3 pytest-cov @@ -44,7 +42,7 @@ include_package_data = True duecredit = duecredit doc = - pandas + pandas sphinx >=2.0 sphinx-argparse sphinx_rtd_theme From 4b1cb20e1a58ee429e2d6c106521257f9f4958d1 Mon Sep 17 00:00:00 2001 From: Stefano Moia Date: Mon, 15 Mar 2021 16:14:39 +0100 Subject: [PATCH 2/2] Remove more CLI stuff --- setup.cfg | 4 ---- 1 file changed, 4 deletions(-) diff --git a/setup.cfg b/setup.cfg index 5af1f23..ea137df 100644 --- a/setup.cfg +++ b/setup.cfg @@ -73,14 +73,10 @@ max-line-length = 99 per-file-ignores = */__init__.py:F401 -[coverage:run] -omit = peakdet/cli/* - [tool:pytest] doctest_optionflags = NORMALIZE_WHITESPACE xfail_strict = true addopts = -rx -norecursedirs = peakdet/cli [versioneer] VCS = git