Skip to content

Commit 0a0c1da

Browse files
authored
Merge pull request #127 from CardiacModelling/tidy-run-herg-qc
Tidy run herg qc, update README
2 parents cbf2fd5 + 06b15a0 commit 0a0c1da

4 files changed

Lines changed: 796 additions & 818 deletions

File tree

README.md

Lines changed: 89 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -46,73 +46,106 @@ python3 -m unittest
4646

4747
## Usage
4848

49-
### Running QC and post-processing
49+
We are working to make pcpostprocess a reusable tool for different types of data.
50+
At the moment, it is geared towards the specific use case detailed below.
5051

51-
Quality control (QC) may be run using the criteria outlined in [Rapid Characterization of hERG Channel Kinetics I](https://doi.org/10.1016/j.bpj.2019.07.029) and [Evaluating the predictive accuracy of ion channel models using data from multiple experimental designs](https://doi.org/10.1101/2024.08.16.608289). These criteria assume the use of the `staircase` protocol for quality control, which should be the first and last protocol performed. We also assume the presence of repeats after the addition of an IKr blocker (such as dofetilide).
52+
### Experimental data
5253

53-
Prior to performing QC and exporting, an `export_config.py` file should be added to the root of the data directory. This file (see `example_config.py`) contains a Python `dict` (`Q2S_DC`) specifying the filenames of the protocols used for QC, and names they should be outputted with, as well as a Python `dict` (`D2S`) listing the other protocols and names to be used for their output. Additionally, the `saveID` field specifies the name of the expeirment which appears in the output file names.
54+
- Syncropatch 384 ("DataControl 384") data
55+
- The full set of protocols is repeated after addition of a strong IKr blocker, e.g. E-4031
56+
- Each set of protocols starts and ends with a "staircase" protocol, leading to a total of 4 staircases:
57+
- Before and after all other protocols, before drug block
58+
- Before and after all other protocols, after drug block
5459

55-
```sh
56-
$ pcpostprocess run_herg_qc --help
60+
So a full set of experiments would go "staircase, other1, other2, ... staircase, drug addition & wash in, staircase, other1, other2, ..., staircase".
61+
62+
Each protocol
63+
- Starts with a leak estimation ramp
64+
- Followed by a step to 40mV and then to -120mV
65+
- Ends with a reversal potential step
66+
- Provides an estimate of Rseal, Rseries, and Cm
67+
68+
### Leak correction
69+
70+
- Leak correction is applied by estimating linear leak from the leak step.
71+
- Before and after drug traces are both corrected
72+
- The final signal is leak-corrected-before minus leak-corrected-after
73+
74+
### Quality control
75+
76+
Quality control is based on [Lei et al. (2019) Rapid Characterization of hERG Channel Kinetics I](https://doi.org/10.1016/j.bpj.2019.07.029) and [Shuttleworth et al. (2025) Evaluating the predictive accuracy of ion channel models using data from multiple experimental designs](https://doi.org/10.1098/rsta.2024.0211).
77+
78+
First, all four staircase protocols are checked in all wells using the Lei et al. criteria, along with new measures described in Shuttleworth et al.
79+
Any wells not rejected are then tested using a smaller set of (less protocol specific) criteria detailed in Shuttleworth et al.
80+
Only wells passing all tests on all protocols are retained.
81+
82+
### Writing an export_config.py
5783

58-
usage: pcpostprocess run_herg_qc [-h] [-c NO_CPUS]
59-
[--output_dir OUTPUT_DIR] [-w WELLS [WELLS ...]]
60-
[--protocols PROTOCOLS [PROTOCOLS ...]]
61-
[--reversal_spread_threshold REVERSAL_SPREAD_THRESHOLD] [--export_failed]
62-
[--selection_file SELECTION_FILE] [--subtracted_only]
63-
[--figsize FIGSIZE FIGSIZE]
64-
[--debug] [--log_level LOG_LEVEL] [--Erev EREV]
65-
data_directory
66-
67-
positional arguments:
68-
data_directory
69-
70-
options:
71-
-h, --help show this help message and exit
72-
-c NO_CPUS, --no_cpus NO_CPUS Number of workers to spawn in the multiprocessing pool (default: 1)
73-
--output_dir OUTPUT_DIR path where the output will be saved
74-
-w WELLS [WELLS ...], --wells WELLS [WELLS ...] wells to include (default: all)
75-
--protocols PROTOCOLS [PROTOCOLS ...] protocols to include (default: all)
76-
--reversal_spread_threshold REVERSAL_SPREAD_THRESHOLD The maximum spread in reversal potential (across sweeps) allowed for QC
77-
--export_failed Flag specifying whether to produce full output for those wells failing QC (default: false)
78-
--selection_file SELECTION_FILE File listing wells to be included
79-
--figsize FIGSIZE FIGSIZE
80-
--debug
81-
--log_level LOG_LEVEL
82-
--Erev EREV The reversal potential during the experiment
84+
Prior to performing QC and exporting, an `export_config.py` file should be added to the root of the data directory.
85+
An example file is available [here](./example_config.py).
86+
This should contain three entries:
87+
88+
1. A `saveID` variable, providing a name to use in exported data.
89+
2. A dictionary variable `Q2S_DC` indicating the name of the staircase protocol, and mapping it onto an more user-friendly name used in export.
90+
3. A dictionary variable `D2S` indicating names of other protocols to export, again mapping onto names for export.
91+
92+
For example, in the test data (see "Getting Started") above, we have six subdirectories:
93+
- `staircaseramp (2)_2kHz_15.01.07`, staircase run as first protocol before E-4031
94+
- `StaircaseInStaircaseramp (2)_2kHz_15.01.51`, non-QC protocol
95+
- `staircaseramp (2)_2kHz_15.06.53`, staircase run as last protocol before E-4031
96+
- `staircaseramp (2)_2kHz_15.11.33`, staircase run as first protocol after E-4031 addition
97+
- `StaircaseInStaircaseramp (2)_2kHz_15.12.17`, non-QC protocol
98+
- `staircaseramp (2)_2kHz_15.17.19`, staircase run as final protocol
99+
100+
Here each directory name is a protocol name followed by a timestamp.
101+
Corresponding dictionaries could be `Q2S_DC = {'staircaseramp (2)_2kHz': 'staircase'}` (indicating the staircase protocol) and `D2S = {'StaircaseInStaircaseramp (2)_2kHz': 'sis'}`.
102+
The saveID could be any string, but in our example we use `saveID = '13112023_MW2'`
103+
104+
### Running
105+
106+
To run, we call `run_herg_qc` with:
107+
```sh
108+
pcpostprocess run_herg_qc test_data/13112023_MW2_FF -o output --output_traces -w A01 A02 A03
83109
```
110+
Here:
111+
- `test_data/13112023_MW2_FF` is the path to the test data,
112+
- `-o output` tells the script to store all results in the folder `output`
113+
- `--output_traces` tells the script to export the data (instead of running QC only), and
84114

85-
### Exporting Summary
115+
The last part, `-w A01 A02 A03`, tells the script to only check the first three wells.
116+
This speeds things up for testing, but would be omitted in normal use.
86117

87-
The `summarise_herg_export` command produces additionally output after `run_herg_qc` has been run.
118+
To see the full set of options, use
88119

89120
```sh
90-
$ pcpostprocess summarise_herg_export --help
91-
92-
usage: pcpostprocess summarise_herg_export [-h] [--cpus CPUS]
93-
[--wells WELLS [WELLS ...]] [--output OUTPUT]
94-
[--protocols PROTOCOLS [PROTOCOLS ...]] [-r REVERSAL]
95-
[--experiment_name EXPERIMENT_NAME]
96-
[--figsize FIGSIZE FIGSIZE] [--output_all]
97-
[--log_level LOG_LEVEL]
98-
data_dir qc_estimates_file
99-
100-
positional arguments:
101-
data_dir path to the directory containing the run_herg_qc results
102-
103-
options:
104-
-h, --help show this help message and exit
105-
--cpus CPUS, -c CPUS
106-
--wells WELLS [WELLS ...], -w WELLS [WELLS ...] wells to include in the output (default: all)
107-
--output OUTPUT, -o OUTPUT path where the output will be saved
108-
--protocols PROTOCOLS [PROTOCOLS ...] protocols to include (default: all)
109-
-r REVERSAL, --reversal REVERSAL the reversal potential during the experiment
110-
--experiment_name EXPERIMENT_NAME
111-
--figsize FIGSIZE FIGSIZE
112-
--output_all Flag specifying whether to output all plots (default: false)
113-
--log_level LOG_LEVEL
121+
$ pcpostprocess run_herg_qc --help
114122
```
115123

124+
### Interpreting the output
125+
126+
After running the command above on the test data provided, the directory `output` will contain the subdirectories:
127+
128+
- `-120mV time constant` Plots illustrating the fits performed when estimating time constants. These are output but not used in QC.
129+
- `leak_correction` Plots illustrating the _linear_ leak correction process in all wells passing staircase QC.
130+
- `qc3-bookend` Plots illustrating the "QC3 bookend" criterion used in Shuttleworth et al.
131+
- `reversal_plots` Plots illustrating the reversal potential estimation
132+
- `subtraction_plots` Plots illustrating the drug subtracted trace leak removal.
133+
- `traces` The exported traces (times, voltages, currents)
134+
135+
and the files:
136+
137+
- `chrono.txt` Lists the order in which protocols were run. For the staircase, the repeat at the end of the sequence is indicated by an added `_2`.
138+
- `passed_wells.txt` Lists the wells that **passed all QC**.
139+
- `pcpostprocess_info.txt` Information on the run that generated this output (date, time, command used etc.)
140+
- `QC-13112023_MW2.csv` A CSV representation of the pass/fail results for each individual criterion
141+
- `QC-13112023_MW2.json` A JSON representation of the same
142+
- `qc_table.tex` A table in Tex format with the above.
143+
- `qc_vals_df.csv` Numerical values used in the final QC.
144+
- `selected-13112023_MW2.txt` **Preliminary QC selection** based on staircase protocol 1 (before other protocols) and 2 (after other protocols)
145+
- `selected-13112023_MW2-staircaseramp.txt` Preliminary selection based on staircase 1
146+
- `selected-13112023_MW2-staircaseramp_2.txt` Preliminary selection based on staircase 2
147+
- `subtraction_qc.csv` Numerical values used in the final QC and leak subtraction.
148+
116149
## Contributing
117150

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

pcpostprocess/leak_correct.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,26 +104,26 @@ def fit_linear_leak(current, voltage, times, ramp_start_index, ramp_end_index,
104104
time_range = (0, times.max() / 5)
105105

106106
#  Current vs time
107-
ax1.set_title(r'\textbf{a}', loc='left')
107+
ax1.set_title('a', loc='left')
108108
ax1.set_xlabel(r'$t$ (ms)')
109109
ax1.set_ylabel(r'$I_\mathrm{obs}$ (pA)')
110110
ax1.set_xticklabels([])
111111
ax1.set_xlim(*time_range)
112112

113113
# Voltage vs time
114-
ax2.set_title(r'\textbf{b}', loc='left')
114+
ax2.set_title('b', loc='left')
115115
ax2.set_xlabel(r'$t$ (ms)')
116116
ax2.set_ylabel(r'$V_\mathrm{cmd}$ (mV)')
117117
ax2.set_xlim(*time_range)
118118

119119
# Current vs voltage
120-
ax3.set_title(r'\textbf{c}', loc='left')
120+
ax3.set_title('c', loc='left')
121121
ax3.set_xlabel(r'$V_\mathrm{cmd}$ (mV)')
122122
ax3.set_ylabel(r'$I_\mathrm{obs}$ (pA)')
123123

124124
ax4.set_xlabel(r'$t$ (ms)')
125125
ax4.set_ylabel(r'current (pA)')
126-
ax4.set_title(r'\textbf{d}', loc='left')
126+
ax4.set_title('d', loc='left')
127127

128128
start_t = times[ramp_start_index]
129129
end_t = times[ramp_end_index]

0 commit comments

Comments
 (0)