Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
cee26d1
Save plot during test. Use different data. Remove unnecessary variable
Oct 29, 2025
60e779b
Fix test leak plot output
Oct 29, 2025
0a25314
Use after-drug data for test_subtraction_plot
Oct 29, 2025
5a01d93
Remove unused import
Oct 29, 2025
d99d15d
Plot corrected trace with solid line not dashed - fixes legend
Oct 29, 2025
9d98f80
Merge pull request #85 from CardiacModelling/fix_test_sub_plots
Oct 29, 2025
4d676f8
Fix gleak, Eleak calculation in subtraction plot
Oct 30, 2025
65eb28d
Fix Eleak, gleak calculation in do_subtraction_plot
Oct 30, 2025
3eba019
Remove unused variables
Oct 30, 2025
9a3cd9e
Merge branch 'main' into js_fix_subtraction_plots
Oct 30, 2025
df7deb7
Correct labelling of gleak and Eleak
Oct 30, 2025
e634398
Merge pull request #86 from CardiacModelling/js_fix_subtraction_plots
Oct 30, 2025
a72885d
Make default plotsize bigger
frankiepe Oct 30, 2025
dd14ca4
Merge pull request #87 from CardiacModelling/bigger_plots
mirams Oct 30, 2025
31a1e5a
Whitespace fix
Oct 30, 2025
2367770
Show more detail, smaller V
mirams Oct 30, 2025
2183087
Linting
mirams Oct 30, 2025
c122fab
Tidy up
mirams Oct 30, 2025
8a889ab
Tidy Vcmd fontsize in panel a
mirams Oct 30, 2025
a870c4b
Use the correctly indexed current sweep for leak correction
frankiepe Oct 30, 2025
dd0b547
Merge pull request #88 from CardiacModelling/subtraction_enhancements
frankiepe Oct 30, 2025
114e168
Merge branch 'main' into leak_correct_bugfix
frankiepe Oct 30, 2025
af48221
Merge pull request #89 from CardiacModelling/leak_correct_bugfix
frankiepe Oct 30, 2025
069431e
Simplify subtraction plot code
Oct 30, 2025
ae6e5db
Fix formatting
Oct 30, 2025
f70fa00
Remove unused vars
Oct 30, 2025
d201ffc
Make default plotsize bigger
frankiepe Oct 30, 2025
9373331
Show more detail, smaller V
Oct 30, 2025
581c5e1
Linting
mirams Oct 30, 2025
3b1cf89
Tidy up
Oct 30, 2025
f90bb19
Tidy Vcmd fontsize in panel a
mirams Oct 30, 2025
3cbc1e4
Simplify subtraction plot code
Oct 30, 2025
7e7f075
Merge branch 'main' into js_fix_subtraction_plots
Oct 30, 2025
6d6cc25
Fix whitespace
Oct 30, 2025
ef66860
Update subtraction_plots.py
joeyshuttleworth Oct 30, 2025
da7935a
Fix selecting wrong current
Oct 30, 2025
d0bc8c1
Fix bug in legend plot
mirams Oct 30, 2025
c397bff
Merge pull request #91 from CardiacModelling/js_fix_subtraction_plots
joeyshuttleworth Oct 31, 2025
d3b2dd8
Add directory builder and use it in tests/scripts
Oct 31, 2025
275346e
Lint and isort
Oct 31, 2025
1f86df8
Add missing file. Add docstring
Oct 31, 2025
790cfc2
Lint, isort
Oct 31, 2025
7a6ad49
Fix linting
Nov 3, 2025
5f5aef4
Fix git hash function
Nov 3, 2025
b31161b
Tidy up output directories
Nov 3, 2025
c749bb0
Remove unnecessary vars
Nov 3, 2025
2558e1f
Fix indent
Nov 3, 2025
71d018e
Fix output_dir bug
Nov 3, 2025
44a7da6
Fix global variable bug
Nov 3, 2025
58ab7a8
Fix error
Nov 3, 2025
b97c22b
Use git diff-index to check for uncommitted changes for info file
Nov 3, 2025
5ff90fd
Add additional checks and tests for directory_builder
Nov 3, 2025
6dc978b
Lint
Nov 3, 2025
be9630e
Modify setup to auto generate version variables
Nov 4, 2025
ec6093e
Isort
Nov 4, 2025
2258c22
Fix imports
Nov 4, 2025
f5a58ae
Tell isort to skip _version.py
Nov 4, 2025
495502b
Include setuptools_scm dependency
joeyshuttleworth Nov 4, 2025
0a11089
Use D2SQC values to get protocol names
Nov 4, 2025
e377e35
Fix pyproject.toml syntax
Nov 5, 2025
c3bb3bc
Uncouple tests from directory_builder
Nov 5, 2025
e8164d9
Fix typo
Nov 5, 2025
ab5112c
Fix testing again
Nov 5, 2025
3ef4b0b
Merge pull request #92 from CardiacModelling/js_new_directory_builder
MichaelClerx Nov 5, 2025
6e118d9
Update ramp bound function and docstring
Nov 6, 2025
df4dd88
Fix infer reversal
Nov 6, 2025
cfabef3
Add test for reversal inference
Nov 6, 2025
7380b62
Fix test output folders
Nov 6, 2025
2f3913a
Update ramp bound function and docstring
Nov 6, 2025
87e3313
Fix infer reversal
Nov 6, 2025
e26b206
Add test for reversal inference
Nov 6, 2025
63fcb98
Fix test infer reversal
Nov 6, 2025
7f919d5
Merge branch 'js_fix_infer_reversal' of github.com:CardiacModelling/p…
Nov 6, 2025
ccae122
Update test
Nov 6, 2025
93d4ca4
Update test
Nov 6, 2025
72cd27a
Modify test
Nov 6, 2025
3053872
Merge pull request #100 from CardiacModelling/js_fix_infer_reversal
joeyshuttleworth Nov 7, 2025
e298a70
Merge branch 'main' into js_fix_passed_wells
joeyshuttleworth Nov 7, 2025
0f31894
Merge pull request #93 from CardiacModelling/js_fix_passed_wells
joeyshuttleworth Nov 7, 2025
7e827d8
Fix QC bug
Nov 7, 2025
87cad31
Merge branch 'js_fix_passed_wells'
Nov 7, 2025
9af8af1
Revert "Account for "QC_R_leftover" in passed_wells"
joeyshuttleworth Nov 7, 2025
e5ec8a1
Fix QC.R_leftover bug
Nov 7, 2025
46c738d
Merge pull request #102 from CardiacModelling/revert-93-js_fix_passed…
MichaelClerx Nov 11, 2025
26a436b
Removed unused init file
MichaelClerx Nov 11, 2025
d7ba22e
Removed wrong comment in github workflow
MichaelClerx Nov 11, 2025
62a0bd5
Merge pull request #103 from CardiacModelling/last-old-version
MichaelClerx Nov 11, 2025
29fd77b
Adding changelog and contributing.md
MichaelClerx Nov 11, 2025
653d749
Updated changelog and readme
MichaelClerx Nov 11, 2025
83265eb
Updated year in license file
MichaelClerx Nov 11, 2025
bd46b8f
Fixed links in CONTRIBUTING.md
MichaelClerx Nov 11, 2025
ac6a3b8
Updated CONTRIBUTING.md
MichaelClerx Nov 11, 2025
bbd5b0a
Updated links in CONTRIBUTING.md
MichaelClerx Nov 11, 2025
ede1f78
Fixed link to license file in readme
MichaelClerx Nov 11, 2025
33196f1
Fixed link to license file in readme, again
MichaelClerx Nov 11, 2025
ad464de
Trying out short links in contributing.md
MichaelClerx Nov 11, 2025
3226510
Updated links in CONTRIBUTING.md
MichaelClerx Nov 11, 2025
eeb6f11
Merge pull request #104 from CardiacModelling/contrib-changelog
MichaelClerx Nov 11, 2025
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
4 changes: 2 additions & 2 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
python-version: ['3.10', 3.11, 3.12, 3.13, 3.14]

steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down Expand Up @@ -53,6 +53,6 @@ jobs:

- uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
token: ${{ secrets.CODECOV_TOKEN }}
if: success() && matrix.python-version == 3.14

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pcpostprocess/_version.py
/tests/test_data
/test_output
*__pycache__*
*.egg-info
*.DS_Store
.coverage
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Changelog

This page lists the main changes made to pcpostprocess in each release.

## Unreleased
- Added
- [#104](https://github.com/CardiacModelling/pcpostprocess/pull/104) Added a CHANGELOG.md and CONTRIBUTING.md
- Changed
- Deprecated
- Removed
- Fixed

## [0.2.0] - 2025-11-11
First official release.

188 changes: 188 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Contributing to pcpostprocess

Contributions to pcpostprocess are always welcome!

We use [GIT](https://en.wikipedia.org/wiki/Git) and [GitHub](https://en.wikipedia.org/wiki/GitHub) to coordinate our work.
When making changes, we try to follow the procedure below.

1. **Discuss proposed changes before starting any work.**
Before coding, always create an [issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/learning-about-issues/about-issues) and disucss the proposed work.
Something similar may already exist, be under development, or have been proposed and rejected - so this can save valuable time.

2. **Always work on branches**.
Once the idea has been agreed upon, start coding in a new _branch_.
If you're in the CardiacModelling team, you can create a [branch](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository) directly in the main pcpostprocess repository.
For outside contributions, you'll first need to [create a fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo).

There are no rules for branch names, but try to make them relate to the issue, e.g. by including the issue number.

Commit your changes to your branch with useful, descriptive commit messages that will still make sense in years to come.

3. **Conform to style guidelines, and document every class, method, and argument.**
For more information, see below.

**Note: as of 2025-11-11, we are still in the process of making `pcpostprocess` confirm to this rule.**

4. **Test locally, and ensure 100% test coverage**
For more information, see below.

**Note: as of 2025-11-11, we are stillin the process of making `pcpostprocess` confirm to this rule.**

4. **Discuss code in a PR**
When your code is finished, or warrants discussion, create a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) (PR).
In your branch, update the [Changelog](./CHANGELOG.md) with a link to this PR and a concise summary of the changes.
Finally, request a review of the code.

## Project structure

`pcpostprocess` is written in [Python 3](https://en.wikipedia.org/wiki/Python_(programming_language)), but at the moment has a few **non-python dependencies** i.e. latex.

## Developer installation

**TODO: Once there is a "user" way to install, move the git clone etc. information here [#105](https://github.com/CardiacModelling/pcpostprocess/issues/105).**

```
pip install -e .[test]
```

## Style guidelines

Style checking is done with [flake8](http://flake8.pycqa.org/en/latest/).

To run locally, use
```
$ flake8
```

Until Flake8 configuration supports [pyproject.toml](https://github.com/PyCQA/flake8/issues/234), it will be configured through [.flake8](./.flake8) ([syntax](http://flake8.pycqa.org/en/latest/user/configuration.html)).

In addition to the rules checked by flake8, we try to use single quotes (`'`) for strings, rather than double quotes (`"`) (but `"""` for docstrings).

### Spelling

**TODO WE SHOULD MAYBE DISCUSS WHICH ENGLISH TO USE? [#106](https://github.com/CardiacModelling/pcpostprocess/issues/106)**

### 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.

Each docstring should start with a one-line explanation.
If more explanation is needed, this one-liner is followed by a blank line and more information in the following paragraphs.

**TODO: READTHEDOCS [#60](https://github.com/CardiacModelling/pcpostprocess/issues/60)**

**TODO: SYNTAX, RUNNING LOCALLY, ETC**

**TODO: EXAMPLES**

```
cd doc
make clean
make html
```

[reStructuredText](http://docutils.sourceforge.net/docs/user/rst/quickref.html)
[Sphinx](http://www.sphinx-doc.org/en/stable/)

## Testing

To run all unit tests, locally:

```
$ python3 -m unittest
```

To run a single test, use
```
$ python3 -m unittest TestClass.test_method
```

### Unit tests

Testing is done with [unittest](https://docs.python.org/3/library/unittest.html).

Each method in `pcpostprocess` should have a unit test.

Tests should always aim to compare generated output with reference values, instead of just checking no errors are generated.

### Coverage

Coverage is checked with [coverage](https://coverage.readthedocs.io/en/latest/).

To run locally, use
```
coverage run -m unittest
```
and, if the tests pass, view the report with
```
coverage report
```

### Github actions

Whenever changes are made to a branch with an open pull request, tests will be run using GitHub actions.

These are configured in a single workflow **TODO THIS IS BEING UPDATED ATM**

Coverage testing is run, and sent to [codecov.io](https://docs.codecov.io/docs) to generate [online reports](https://app.codecov.io/github/CardiacModelling/pcpostprocess).

## Logging changes

Each PR should add a line (or occasionally multiple lines) to [CHANGELOG.md](./CHANGELOG.md).
This should be a very concise summary of the work done, and link to the PR itself for further info.
Changes are classified as `Added`, `Changed`, `Deprecated`, `Removed`, or `Fixed`.

For example, the first entry in our Changelog was:
```
- Added
- [#104](https://github.com/CardiacModelling/pcpostprocess/pull/104) Added a CHANGELOG.md and CONTRIBUTING.md
```

## Packaging

This project uses a minimal [`setup.py`](./setup.py), and instead uses [pyproject.toml](./pyproject.toml).

### Versioning

Version numbers are not set in the code, but derived from git tags, using [setuptools-scm](https://setuptools-scm.readthedocs.io/en/latest/).
This is run every time setuptools is run, e.g. with
```
pip install -e .[test]
```

Versions numbers take the form `X.Y.Z` where X, Y, and Z are "major", "minor", and "revision" numbers.
Changes to the public interface should be reflected in an updated minor version.
Small changes should be indicated with revisions.
These numbers don't stop at 9, so e.g. 1.11.12 is a viable number.

**The version number is only changed when a new release is made**

### Releases

Releases, like other changes, are made on a branch, using the following procedure:

1. Create a new branch.
2. Update the changelog, replacing the "Unreleased" header with a version number and date, e.g. `## [0.2.0] - 2025-11-11`.
3. Commit the change.
4. Add a tag using e.g. `git tag v0.2.0`, and push it with `git push --tags`.
5. Update the changelog, adding a new "Unreleased" header with empty categories.
6. Merge the PR.
7. [Add a new release](https://github.com/CardiacModelling/pcpostprocess/releases) in GitHub, using the tag you created, and copy in the changes from the changelog.

**TODO: THERE IS NO PACKAGING ON PYPI ATM [#105](https://github.com/CardiacModelling/pcpostprocess/issues/105)**

### Licensing

Licensing information is provided in a separate [LICENSE](./LICENSE) file.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2024, University of Nottingham
Copyright (c) 2024-2025, University of Nottingham

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,11 @@ options:
--log_level LOG_LEVEL
```

## Contributing

Although `pcpostprocess` is still early in its development, we have set up guidelines for user contributions in [CONTRIBUTING.md](./CONTRIBUTING.md).

## Licensing

For licensing information, see the [LICENSE](./LICENSE) file.

Empty file removed __init__.py
Empty file.
12 changes: 6 additions & 6 deletions pcpostprocess/detect_ramp_bounds.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import numpy as np


def detect_ramp_bounds(times, voltage_sections, ramp_no=0):
def detect_ramp_bounds(times, voltage_sections, ramp_index=0):
"""
Extract the the times at the start and end of the nth ramp in the protocol.
Extract the timepoint indices at the start and end of the nth ramp in the protocol.

@param times: np.array containing the time at which each sample was taken
@param voltage_sections 2d np.array where each row describes a segment of the protocol: (tstart, tend, vstart, end)
@param ramp_no: the index of the ramp to select. Defaults to 0 - the first ramp
@param ramp_index: the index of the ramp to select. Defaults to 0 - the first ramp

@returns tstart, tend: the start and end times for the ramp_no+1^nth ramp
@returns istart, iend: the start and end timepoint indices for the specified ramp
"""

ramps = [(tstart, tend, vstart, vend) for tstart, tend, vstart, vend
in voltage_sections if vstart != vend]
try:
ramp = ramps[ramp_no]
ramp = ramps[ramp_index]
except IndexError:
print(f"Requested {ramp_no+1}th ramp (ramp_no={ramp_no}),"
print(f"Requested {ramp_index+1}th ramp (ramp_index={ramp_index}),"
" but there are only {len(ramps)} ramps")

tstart, tend = ramp[:2]
Expand Down
63 changes: 63 additions & 0 deletions pcpostprocess/directory_builder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import datetime
import os
import sys

from ._version import __commit_id__, __version__


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"


def setup_output_directory(dirname: str = None, subdir_name: str = None):
"""
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

@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)

with open(os.path.join(dirname, "pcpostprocess_info.txt"), "w") as description_fout:
git_hash = get_git_revision_hash()
datetimestr = str(datetime.datetime.now())
description_fout.write("pcpostprocess output "
"https://github.com/CardiacModelling/pcpostprocess\n")
description_fout.write(f"Date: {datetimestr}\n")
description_fout.write(f"Version: {__version__}\n")
description_fout.write(f"Build type: {get_build_type()}\n")
description_fout.write(f"Commit: {git_hash}\n")
command = " ".join(sys.argv)
description_fout.write(f"Command: {command}\n")
return dirname

5 changes: 1 addition & 4 deletions pcpostprocess/infer_reversal.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ def infer_reversal_potential(current, times, voltage_segments, voltages,
"""

# Get ramp bounds, assuming final ramp is the reversal ramp
tstart, tend = detect_ramp_bounds(times, voltage_segments, -1)

istart = np.argmax(times > tstart)
iend = np.argmax(times > tend)
istart, iend = detect_ramp_bounds(times, voltage_segments, -1)

current = current[istart:iend]
voltages = voltages[istart:iend]
Expand Down
2 changes: 1 addition & 1 deletion pcpostprocess/leak_correct.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def fit_linear_leak(current, voltage, times, ramp_start_index, ramp_end_index,
ax4.plot(times, I_obs, label=r'$I_\mathrm{obs}$')
ax4.plot(times, I_leak, linestyle='--', label=r'$I_\mathrm{L}$')
ax4.plot(times, I_obs - I_leak,
linestyle='--', alpha=0.5, label=r'$I_\mathrm{obs} - I_\mathrm{L}$')
alpha=0.5, label=r'$I_\mathrm{obs} - I_\mathrm{L}$')
ax4.legend(frameon=False)

if not os.path.exists(output_dir):
Expand Down
Loading