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
3 changes: 2 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ ignore =
exclude=
.git,
venv,
tests/test_data,
test_data,
test_output,
16 changes: 4 additions & 12 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,13 @@ jobs:
- name: Check code style with flake8
if: ${{ matrix.python-version == env.python-latest }}
run: |
python -m flake8 pcpostprocess/*.py tests/*.py pcpostprocess/scripts/*.py

- name: Check import ordering with isort
if: ${{ matrix.python-version == env.python-latest }}
run: |
python -m isort --verbose --check-only --diff pcpostprocess tests setup.py
python -m flake8 pcpostprocess

- name: Extract test data
run: |
wget https://cardiac.nottingham.ac.uk/syncropatch_export/test_data.tar.xz -P tests/
tar xvf tests/test_data.tar.xz -C tests/

- name: Install TeX dependencies for run_herg_qc test
timeout-minutes: 5
run: sudo apt-get install dvipng texlive-latex-extra texlive-fonts-recommended cm-super -y
wget https://cardiac.nottingham.ac.uk/syncropatch_export/test_data.tar.xz
tar xvf test_data.tar.xz
rm test_data.tar.xz

- name: Run unit tests (without coverage testing)
if: ${{ success() && matrix.python-version != env.python-latest }}
Expand Down
28 changes: 24 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
# Autogenerated by setuptools-wcm
pcpostprocess/_version.py
/tests/test_data

# Tests and test data
.coverage
/test_data
/test_output
/output
*__pycache__*

# Compiled python
*.pyc
__pycache__

# Installation files
*.egg-info
*.DS_Store
.coverage

# Jupyter notebooks
.ipynb_checkpoints

# Virtual environments
venv
env

# DS Store
.DS_Store

# VS code config
.vscode
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ This page lists the main changes made to pcpostprocess in each release.
## Unreleased
- Added
- [#81](https://github.com/CardiacModelling/pcpostprocess/pull/81) Added docstrings to the `hERGQC` class.
- [#104](https://github.com/CardiacModelling/pcpostprocess/pull/104) Added a CHANGELOG.md and CONTRIBUTING.md
- [#104](https://github.com/CardiacModelling/pcpostprocess/pull/104) Added a CHANGELOG.md and CONTRIBUTING.md.
- Changed
- [#81](https://github.com/CardiacModelling/pcpostprocess/pull/81) Changed the constructor arguments for `hERGQC`.
- [#122](https://github.com/CardiacModelling/pcpostprocess/pull/122) `fit_linear_leak` no longer accepts an `output_dir` argument.
- Deprecated
- Removed
- [#81](https://github.com/CardiacModelling/pcpostprocess/pull/81) Removed `hERGQC.plot_dir`, `hERGQC.set_trace` and `hERGQC.set_debug`.
Expand Down
11 changes: 0 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,6 @@ In addition to the rules checked by flake8, we try to use single quotes (`'`) fo

Class, method, and argument names are in UK english.

### Import ordering

Import ordering is tested with [isort](https://pycqa.github.io/isort/index.html).

To run locally, use
```
isort --check-only --verbose ./pcpostprocess ./tests/
```

Isort is configured in [pyproject.toml](./pyproject.toml) under the section `tool.isort`.

## Documentation

Every method and every class should have a [docstring](https://www.python.org/dev/peps/pep-0257/) that describes in plain terms what it does, and what the expected input and output is.
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ To run the tests you must first download some test data.
Test data is available at [cardiac.nottingham.ac.uk/syncropatch\_export](https://cardiac.nottingham.ac.uk/syncropatch_export)

```sh
wget https://cardiac.nottingham.ac.uk/syncropatch_export/test_data.tar.xz -P tests/
tar xvf tests/test_data.tar.xz -C tests/
rm tests/test_data.tar.xz
wget https://cardiac.nottingham.ac.uk/syncropatch_export/test_data.tar.xz
tar xvf test_data.tar.xz
rm test_data.tar.xz
```

Then you can run the tests.
Expand Down
24 changes: 4 additions & 20 deletions pcpostprocess/directory_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,27 @@ def get_git_revision_hash():
Get the hash for the git commit currently being used.

@return The most recent commit hash or a suitable message

"""

return __commit_id__


def get_build_type():
if "dev" in __version__:
return "Develop"
else:
return "Release"
return 'Develop' if 'dev' in __version__ else 'Release'


def setup_output_directory(dirname: str = None, subdir_name: str = None):
def setup_output_directory(dirname: str):
"""
Create an output directory if one doesn't already exist. Place an info
file in this directory which lists the date/time created, the version of
pcpostprocess, the command-line arguments provided, and the most recent git
commit. The two parameters allow for a user specified top-level directory and
a script-defined name for a subdirectory.

@param Optional directory name
@param Optional subdirectory name
@param Directory name

@return The path to the created file directory (String)
"""

if dirname is None:
if subdir_name:
dirname = os.path.join("output", f"{subdir_name}")
else:
dirname = os.path.join("output", "output")

if subdir_name is not None:
dirname = os.path.join(dirname, subdir_name)
if not os.path.exists(dirname):
os.makedirs(dirname)
os.makedirs(dirname, exist_ok=True)

with open(os.path.join(dirname, "pcpostprocess_info.txt"), "w") as description_fout:
git_hash = get_git_revision_hash()
Expand Down
8 changes: 1 addition & 7 deletions pcpostprocess/hergQC.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,8 @@ def __init__(self, voltage, sampling_rate=5, removal_time=5, noise_len=200,
self.removal_time = removal_time
self.noise_len = int(noise_len)

# Passing in a plot dir enables debug mode
self._plot_dir = plot_dir
self.logger = logging.getLogger(__name__)
if self._plot_dir is not None:
self.logger.setLevel(logging.DEBUG)
# https://github.com/CardiacModelling/pcpostprocess/issues/42
self._plot_dir = plot_dir

# Define all thresholds

Expand Down Expand Up @@ -499,8 +494,7 @@ def qc6(self, recording1, win, label=None):
i, f = win
val = np.mean(recording1[i:f])
valc = self.negative_tolc * np.std(recording1[:self.noise_len])
if (val < valc) or not (np.isfinite(val)
and np.isfinite(valc)):
if (val < valc) or not (np.isfinite(val) and np.isfinite(valc)):
self.logger.debug(f'qc6_{label} val: {val}, valc: {valc}')
result = False
else:
Expand Down
4 changes: 0 additions & 4 deletions pcpostprocess/infer_reversal.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import logging
import os

import matplotlib.pyplot as plt
import numpy as np
Expand Down Expand Up @@ -65,9 +64,6 @@ def infer_reversal_potential(current, times, voltage_segments, voltages,

# Optional plot
if output_path is not None:
dirname = os.path.dirname(output_path)
if not os.path.exists(dirname):
os.makedirs(dirname)

fig = plt.figure(figsize=figsize)
ax = fig.subplots()
Expand Down
30 changes: 11 additions & 19 deletions pcpostprocess/leak_correct.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import os

#
# Leak correction methods
#
import numpy as np
from matplotlib import pyplot as plt

Expand Down Expand Up @@ -55,7 +55,7 @@ def get_leak_corrected(current, voltages, times, ramp_start_index,


def fit_linear_leak(current, voltage, times, ramp_start_index, ramp_end_index,
save_fname=None, output_dir=None, figsize=(5.54, 7)):
save_fname=None, figsize=(5.54, 7)):
"""
Fits linear leak to a leak ramp, returning

Expand All @@ -64,8 +64,6 @@ def fit_linear_leak(current, voltage, times, ramp_start_index, ramp_end_index,
@param ramp_start_index: the index of the observation where the leak ramp begins
@param ramp_end_index: the index of the observation where the leak ramp ends
@param save_fname: if set, a debugging figure will be made and stored with this name
@param output_dir: if ``save_fname`` is set, this directory will be used to store
the figure, and created if it does not exist
@param figsize: if ``save_fname`` is set, the figure size.

@return: the linear regression parameters obtained from fitting the leak
Expand Down Expand Up @@ -106,26 +104,26 @@ def fit_linear_leak(current, voltage, times, ramp_start_index, ramp_end_index,
time_range = (0, times.max() / 5)

#  Current vs time
ax1.set_title(r'\textbf{a}', loc='left', usetex=True)
ax1.set_title(r'\textbf{a}', loc='left')
ax1.set_xlabel(r'$t$ (ms)')
ax1.set_ylabel(r'$I_\mathrm{obs}$ (pA)')
ax1.set_xticklabels([])
ax1.set_xlim(*time_range)

# Voltage vs time
ax2.set_title(r'\textbf{b}', loc='left', usetex=True)
ax2.set_title(r'\textbf{b}', loc='left')
ax2.set_xlabel(r'$t$ (ms)')
ax2.set_ylabel(r'$V_\mathrm{cmd}$ (mV)')
ax2.set_xlim(*time_range)

# Current vs voltage
ax3.set_title(r'\textbf{c}', loc='left', usetex=True)
ax3.set_title(r'\textbf{c}', loc='left')
ax3.set_xlabel(r'$V_\mathrm{cmd}$ (mV)')
ax3.set_ylabel(r'$I_\mathrm{obs}$ (pA)')

ax4.set_xlabel(r'$t$ (ms)')
ax4.set_ylabel(r'current (pA)')
ax4.set_title(r'\textbf{d}', loc='left', usetex=True)
ax4.set_title(r'\textbf{d}', loc='left')

start_t = times[ramp_start_index]
end_t = times[ramp_end_index]
Expand All @@ -152,14 +150,8 @@ def fit_linear_leak(current, voltage, times, ramp_start_index, ramp_end_index,
alpha=0.5, label=r'$I_\mathrm{obs} - I_\mathrm{L}$')
ax4.legend(frameon=False)

if not os.path.exists(output_dir):
os.makedirs(output_dir)

if output_dir:
try:
fig.savefig(os.path.join(output_dir, save_fname))
plt.close(fig)
except Exception as exc:
logging.warning(str(exc))
if save_fname is not None:
fig.savefig(save_fname)
plt.close(fig)

return (b_0, b_1), I_leak
Loading