Python library for reading electrophysiology data from Axon Binary Format (ABF) files
—
Specialized analysis modules for action potential detection, membrane test analysis, and sweep-level measurements. These tools are located in the pyabf.tools subpackage and must be imported explicitly.
Functions for detecting and analyzing action potentials in electrophysiology recordings.
from pyabf.tools import ap
def ap_points_currentSweep(
abf,
dVthresholdPos: float = 15,
betweenSec1: Union[float, None] = None,
betweenSec2: Union[float, None] = None
) -> List[int]:
"""
Find action potential peak indices in the current sweep.
Parameters:
- abf: ABF object with active sweep set
- dVthresholdPos: Positive threshold for AP detection (mV/ms)
- betweenSec1: Start time for analysis window (seconds)
- betweenSec2: End time for analysis window (seconds)
Returns:
List of data point indices where action potentials occur
Note: Call abf.setSweep() before using this function
"""
def ap_freq_per_sweep(abf, singleEpoch: bool = False) -> List[List[float]]:
"""
Calculate action potential frequency for each sweep.
Parameters:
- abf: ABF object
- singleEpoch: If True, analyze only first epoch of each sweep
Returns:
List containing [frequencies_in_bin, frequencies_first] - two lists of frequencies
"""
def extract_first_ap(abf, paddingMsec: float = 50) -> Union[np.ndarray, None]:
"""
Extract the first action potential with surrounding data.
Parameters:
- abf: ABF object with active sweep set
- paddingMsec: Padding around AP in milliseconds
Returns:
numpy array containing voltage data around the first AP, or None if no AP found
"""Class for analyzing membrane properties from voltage clamp recordings.
from pyabf.tools import memtest
class Memtest:
def __init__(self, abf: ABF, channel: int = 0):
"""
Initialize membrane test analysis.
Parameters:
- abf: ABF object containing membrane test data
- channel: Channel number to analyze
Note: ABF should contain voltage clamp recordings with
hyperpolarizing voltage steps for membrane property analysis
"""
@property
def summary(self) -> str:
"""
Generate summary of membrane test results.
Returns:
Multi-line string with membrane resistance, capacitance,
and time constant measurements
"""
def __repr__(self) -> str:
"""
String representation showing basic membrane properties.
Returns:
Formatted string with key membrane test parameters
"""
# Additional measurement properties on Memtest instances:
Ra: SweepMeasurement
"""Access resistance measurements. Use Ra.values for list of values (MOhm)."""
Rm: SweepMeasurement
"""Membrane resistance measurements. Use Rm.values for list of values (MOhm)."""
Cm: SweepMeasurement
"""Membrane capacitance measurements. Use Cm.values for list of values (pF)."""
tau: SweepMeasurement
"""Time constant measurements. Use tau.values for list of values (ms)."""Low-level mathematical functions for membrane property calculations.
from pyabf.tools import memtestMath
def currentSweepRamp(abf) -> Union[np.ndarray, float]:
"""
Calculate capacitance from a voltage clamp ramp.
Parameters:
- abf: ABF object with active sweep set
Returns:
Capacitance value or np.nan if calculation fails
Note: Expects a downward ramp followed by an upward ramp
"""
def currentSweepStep(abf) -> List[float]:
"""
Extract membrane test values from a step protocol.
Parameters:
- abf: ABF object with active sweep set
Returns:
List containing [Ih, Rm, Ra, Cm] where:
- Ih: Holding current (pA)
- Rm: Membrane resistance (MOhm)
- Ra: Access resistance (MOhm)
- Cm: Membrane capacitance (pF)
"""Functions for creating synthetic electrophysiology signals.
from pyabf.tools import generate
def generate_exp(
tauMs: int = 100,
rateHz: int = 20000,
filterHz: int = 2000
) -> np.ndarray:
"""
Generate exponential decay signal similar to EPSC/IPSC.
Parameters:
- tauMs: Time constant in milliseconds
- rateHz: Sample rate in Hz
- filterHz: Filter cutoff frequency in Hz
Returns:
numpy array with exponential decay waveform
"""
def generate_alpha(tauMs: int = 100, rateHz: int = 20000) -> np.ndarray:
"""
Generate alpha function signal similar to EPSP/IPSP.
Parameters:
- tauMs: Time constant in milliseconds
- rateHz: Sample rate in Hz
Returns:
numpy array with alpha function waveform
"""
class SynthSweep:
def __init__(
self,
sampleRate: int = 20000,
sweepLengthSec: int = 5,
voltageClamp: bool = True
):
"""
Create synthetic electrophysiology sweep with events and noise.
Parameters:
- sampleRate: Sample rate in Hz
- sweepLengthSec: Sweep duration in seconds
- voltageClamp: True for voltage clamp, False for current clamp
"""
def addOffset(self, offset: float) -> None:
"""Add DC offset to the sweep."""
def addNoise(self, magnitude: float = 3) -> None:
"""Add random noise to the sweep."""
def addEvent(
self,
timeSec: float = 1.23,
magnitude: float = 20,
tauMs: float = 100,
excitatory: bool = True
) -> None:
"""Add single synaptic event at specified time."""
def addEvents(
self,
frequencyHz: float,
maxMagnitude: float = 10,
tauMs: float = 100,
excitatory: bool = True,
AP: bool = False
) -> None:
"""Add multiple events with specified frequency."""Functions for displaying and formatting ABF header information.
from pyabf.tools import abfHeaderDisplay
def standardNumpyText(data) -> str:
"""
Convert numpy array to standard string representation.
Parameters:
- data: numpy array or list
Returns:
String representation regardless of numpy version
"""
def abfInfoPage(abf) -> InfoPage:
"""
Create comprehensive information page for ABF object.
Parameters:
- abf: ABF object
Returns:
InfoPage object with methods for displaying ABF information
"""
class InfoPage:
def __init__(self, title: str = "PageTitle"):
"""
Container for displaying object information in multiple formats.
Parameters:
- title: Page title for display
"""
def addSection(self, name: str) -> None:
"""Add a new section to the information page."""
def addThing(self, name: str, value=None) -> None:
"""Add an item to the current section."""
def generateHTML(self, saveAs: Union[str, bool] = False) -> str:
"""Generate HTML representation of the information."""
def generateMarkdown(self, saveAs: Union[str, bool] = False) -> str:
"""Generate markdown representation of the information."""
def launchTempWebpage(self) -> None:
"""Launch information page in web browser."""Functions for analyzing data at the sweep level across multiple recordings.
from pyabf.tools import sweep
def getMeanSweep(abf, baseline: Union[float, None] = None) -> np.ndarray:
"""
Calculate mean sweep across all sweeps in the file.
Parameters:
- abf: ABF object
- baseline: Baseline value to subtract (if None, uses first 10% of sweep)
Returns:
numpy array representing the mean sweep data
"""
class SweepMeasurement:
def __init__(self, sweepCount: int, name: str, abbreviation: str, units: str):
"""
Container for sweep-level measurements.
Parameters:
- sweepCount: Number of sweeps
- name: Full name of the measurement
- abbreviation: Short abbreviation
- units: Units of measurement
"""
@property
def valuesReal(self) -> List[float]:
"""Real (non-NaN) measurement values."""
@property
def mean(self) -> float:
"""Mean of all real values."""
@property
def stdev(self) -> float:
"""Standard deviation of all real values."""
@property
def stdErr(self) -> float:
"""Standard error of the mean."""import pyabf
from pyabf.tools import ap, memtest, sweep
# Load ABF file
abf = pyabf.ABF("current_clamp_recording.abf")
# Action potential analysis
abf.setSweep(0)
ap_indices = ap.ap_points_currentSweep(abf, dVthresholdPos=20)
print(f"Found {len(ap_indices)} action potentials in sweep 0")
# Extract first AP
if ap_indices:
ap_voltage = ap.extract_first_ap(abf, paddingMsec=100)
if ap_voltage is not None:
print(f"Extracted AP with {len(ap_voltage)} data points")
# AP frequency analysis across all sweeps
freq_data = ap.ap_freq_per_sweep(abf)
frequencies_in_bin, frequencies_first = freq_data
print(f"AP frequencies in bin: {frequencies_in_bin}")
# Membrane test analysis (for voltage clamp data)
vc_abf = pyabf.ABF("voltage_clamp_memtest.abf")
mt = memtest.Memtest(vc_abf, channel=0)
print(mt.summary)
# Access individual membrane properties using .values
print(f"Access resistance: {mt.Ra.values[0]:.1f} MOhm")
print(f"Membrane resistance: {mt.Rm.values[0]:.1f} MOhm")
print(f"Membrane capacitance: {mt.Cm.values[0]:.1f} pF")
print(f"Tau: {mt.tau.values[0]:.2f} ms")
# Sweep-level analysis
mean_sweep = sweep.getMeanSweep(abf)
print(f"Mean sweep shape: {mean_sweep.shape}")
# Custom sweep measurements
measurement = sweep.SweepMeasurement(
sweepCount=abf.sweepCount,
name="Peak Voltage",
abbreviation="Vpeak",
units="mV"
)import pyabf
from pyabf.tools import ap
import numpy as np
# Load current clamp recording
abf = pyabf.ABF("current_clamp.abf")
# Analyze each sweep for action potentials
results = []
for sweep_num in range(abf.sweepCount):
abf.setSweep(sweep_num)
# Find APs in this sweep
ap_indices = ap.ap_points_currentSweep(abf)
ap_count = len(ap_indices)
# Calculate AP frequency if multiple APs found
if ap_count > 1:
sweep_duration = abf.sweepX[-1] - abf.sweepX[0]
frequency = (ap_count - 1) / sweep_duration
else:
frequency = 0
results.append({
'sweep': sweep_num,
'ap_count': ap_count,
'frequency': frequency
})
print("AP Analysis Results:")
for result in results:
print(f"Sweep {result['sweep']}: {result['ap_count']} APs, "
f"{result['frequency']:.1f} Hz")import pyabf
from pyabf.tools import memtest
# Load voltage clamp recording with membrane test
abf = pyabf.ABF("voltage_clamp.abf")
# Perform membrane test analysis
mt = memtest.Memtest(abf, channel=0)
# Display comprehensive results
print("Membrane Test Results")
print("=" * 40)
print(mt.summary)
# Track membrane properties over time
if len(mt.Ra.values) > 1:
print(f"\nAccess resistance trend:")
for i, ra in enumerate(mt.Ra.values):
print(f" Sweep {i}: {ra:.1f} MOhm")Install with Tessl CLI
npx tessl i tessl/pypi-pyabf