ionique.core
Overview
The core module provides the hierarchical segment tree structure used throughout
ionique. It defines classes for representing segments of ionic current data in a
tree hierarchy, where each segment can contain child segments at different “ranks”
(e.g., file → voltage step → event).
Key Concepts
Segments represent portions of ionic current traces with start/end indices.
Ranks define hierarchy levels. Common ranks include:
"file"- The top-level segment containing the entire trace"vstep"- Voltage step segments within a file"event"- Individual events detected within voltage steps
Parsing subdivides a segment into children at a new rank using parser objects.
Feature lookup traverses up the tree to find attributes (e.g., sampling_freq).
Classes
AbstractSegmentTree
The base class providing tree structure and traversal methods. Not typically instantiated directly.
from ionique.core import AbstractSegmentTree
# Tree traversal methods
segment.traverse_to_rank("event") # Get all segments at rank "event"
segment.climb_to_rank("file") # Go up to find the file-level segment
segment.get_feature("sampling_freq") # Look up feature in self or ancestors
MetaSegment
A lightweight segment storing only metadata (start, end, statistics) without holding the actual current array. Used for memory-efficient storage of parsed results.
Basic Usage:
from ionique.core import MetaSegment
# Create a metadata segment
seg = MetaSegment(
start=1000,
end=2000,
rank="event",
unique_features={"amplitude": 0.5, "dwell_time": 0.01}
)
# Access properties
print(seg.n) # Length: 1000
print(seg.start) # 1000
print(seg.end) # 2000
Accessing Current Data:
MetaSegment can retrieve current data by climbing to the file-level parent:
# If seg has a parent chain leading to a file with current data:
current_slice = seg.current # Returns current[1000:2000] from file
print(seg.mean) # Computes np.mean(current_slice)
print(seg.std) # Computes np.std(current_slice)
Serialization:
# Convert to JSON
json_str = seg.to_json()
print(json_str)
# {
# "mean": 1.234,
# "std": 0.056,
# "start": 1000,
# "end": 2000,
# "name": "MetaSegment"
# }
# Convert to dictionary
seg.to_dict()
Segment
A full segment holding the actual current data as a NumPy array. Use this when you need direct access to the raw signal values.
Basic Usage:
import numpy as np
from ionique.core import Segment
# Create sample current data
current = np.random.randn(1000) * 0.1 + 1.5 # ~1.5 nA with noise
# Create a segment
seg = Segment(
current=current,
start=0,
end=1000,
rank="event"
)
# Access statistics (computed on-the-fly)
print(f"Mean: {seg.mean:.3f}")
print(f"Std: {seg.std:.3f}")
print(f"Min: {seg.min:.3f}")
print(f"Max: {seg.max:.3f}")
print(f"Length: {seg.n}")
Converting to MetaSegment:
To save memory after extracting statistics:
# Convert to lightweight MetaSegment (deletes current array)
seg.to_meta()
# seg is now a MetaSegment with cached mean, std, min, max
Working with the Tree Structure
Adding Children:
from ionique.core import MetaSegment
# Create parent segment
parent = MetaSegment(start=0, end=10000, rank="vstep")
# Create child segments
event1 = MetaSegment(start=100, end=500, rank="event", parent=parent)
event2 = MetaSegment(start=600, end=900, rank="event", parent=parent)
# Add children to parent
parent.add_children([event1, event2])
# Children are automatically sorted by start position
print(len(parent.children)) # 2
Traversing the Tree:
# Get all segments at a specific rank
all_events = parent.traverse_to_rank("event")
# Climb up to find ancestor at a rank
file_seg = event1.climb_to_rank("file")
# Get summary of ranks and counts
summary = parent.summary()
# {"vstep": 1, "event": 2}
Looking Up Features:
Features are looked up in the segment first, then in ancestors:
# Set a feature at file level
file_seg.unique_features["sampling_freq"] = 100000
# Child segments can access it
event = file_seg.children[0].children[0] # Some nested event
freq = event.get_feature("sampling_freq") # Returns 100000
Parsing Segments
Use the parse() method to subdivide segments using parser objects:
from ionique.parsers import SpikeParser
# Create a parser
parser = SpikeParser(
prominence=0.15,
distance=100,
width=(10, 10000)
)
# Parse events within each voltage step
file_segment.parse(
parser=parser,
newrank="event",
at_child_rank="vstep" # Parse at vstep level, not file level
)
# Access detected events
events = file_segment.traverse_to_rank("event")
print(f"Detected {len(events)} events")
Note
Segments store references to data arrays, not copies. Modifying the underlying array affects all segments referencing it.
Warning
The current property on MetaSegment requires a valid parent chain
up to a file-level segment. It returns None if the chain is broken.
API Reference
loose adaptation from “core.py” by Jacob Scheriber https://github.com/jmschrei/PyPore – Original License included in “PYPORE_LICENSE.txt”.
This holds the core data types which may be abstracted in many different applications. This module defines a tree-based framework for representing, parsing, and annotating segments of ionic current data.
- class ionique.core.AbstractSegmentTree
Bases:
objectClass for managing hierarchical segments.
This class supports a tree structure where each segment can contain multiple child segments, enabling recursive parsing and analysis of nested data. It provides utilities to manage relationships between segments, apply parsers, and extract subsegments by rank.
- parent
Parent segment in the tree, or None if this is the root.
- Type:
AbstractSegmentTree or None
- children
List of child segments belonging to this node.
- Type:
- add_children(children: list[AnySegment]) None
Add multiple children if: 1. Child position is the within parent’s segment. 2. The length of the child’s segment is > 0 3. There is no overlap between consecutive children
Or add children with no check
- clear_children()
Clear the list of children
- climb_to_rank(rank: str) AnySegment | None
Traverse upward through the tree to find the nearest ancestor with the given rank.
- Parameters:
rank (str) – The rank label to search for.
- Returns:
The nearest ancestor (or self) that has the specified rank, or None if no such segment exists in the chain.
- Return type:
AbstractSegmentTree or None
- get_feature(name: str)
Get a named feature from the current segment or the nearest ancestor that has it.
- get_top_parent() AnySegment
Recursively traverse upward and return the topmost parent node.
- Returns:
The root ancestor of this segment.
- Return type:
- property n: int
Get the length of the segment.
- Returns:
Number of samples in the segment (
end - start).- Return type:
- parse(parser, newrank: str, at_child_rank: str | None = None, **kwargs) bool
Parse the segment data into child segments with a new rank.
Parses the data in the segment or at a particular rank of child segments into children segments with a new rank.
- Parameters:
parser (Parser) – A parser object with a parse method and required input attributes.
newrank (str) – Rank to assign to the newly created child segments.
at_child_rank (str or None, optional) – Determines whether to traverse the children tree down to a given rank. Defaults to None.
**kwargs – Additional arguments to pass to the parser.
- Returns:
True if parsing was successful, otherwise raises an exception.
- Return type:
- property relative_end: int
Get the end position relative to the parent segment.
- Returns:
End index offset from the parent’s start, or the absolute end if there is no parent.
- Return type:
- property relative_slice: ndarray
Compute the numpy slice object spanning this segment’s relative start to relative end.
- Returns:
A
numpy.s_slice object for the range[relative_start:relative_end].- Return type:
- property relative_start: int
Get the start position relative to the parent segment.
- Returns:
Start index offset from the parent’s start, or the absolute start if there is no parent.
- Return type:
- property slice: ndarray
Compute the numpy slice object spanning this segment’s start to end.
- Returns:
A
numpy.s_slice object for the range[start:end].- Return type:
- summary()
Provide a summary of existing ranks and the count of elements at each rank.
- Returns:
Mapping of rank label to count of segments at that rank, ordered from root toward children.
- Return type:
- class ionique.core.MetaSegment(start: int, end: int, parent: AnySegment | None = None, rank: str | None = None, unique_features: dict | None = {}, **kwargs)
Bases:
AbstractSegmentTreeLightweight segment node storing only position and metadata, without raw signal data.
All information about a segment can be loaded without requiring the underlying array of ionic current values.
- Parameters:
start (int) – Start index of the segment.
end (int) – End index of the segment.
parent (AbstractSegmentTree or None, optional) – Parent segment in the tree. Defaults to None.
rank (str or None, optional) – Rank identifier for this segment. Defaults to None.
unique_features (dict or None, optional) – Dictionary of metadata features associated with this segment. Defaults to an empty dict.
**kwargs – Additional keyword arguments (currently unused).
- __init__(start: int, end: int, parent: AnySegment | None = None, rank: str | None = None, unique_features: dict | None = {}, **kwargs)
Initialize the MetaSegment with positional and metadata information.
- property current
Get the ionic current data for this segment by slicing the parent file’s array.
- Returns:
Current values from the root file segment sliced to this segment’s start/end range, or None if the file rank cannot be reached.
- Return type:
numpy.ndarray or None
- delete()
Delete itself. There are no arrays with which to delete references for.
- property duration: float
Get the duration of the segment in time units.
- Returns:
Time elapsed from the first to the last sample of the segment.
- Return type:
- classmethod from_json(filename=None, in_json=None)
Read in a metasegment from a JSON and return a metasegment object. Either pass in a file which has a segment stored, or an actual JSON object.
- property max
Calculate the maximum value of the current array.
- Returns:
Maximum value of the current array.
- Return type:
- property mean
Calculate the mean of the current array.
- Returns:
Mean value of the current array.
- Return type:
- property min
Calculate the minimum value of the current array.
- Returns:
Minimum value of the current array.
- Return type:
- property std
Calculate the standard deviation of the current array.
- Returns:
Standard deviation of the current array.
- Return type:
- property time
Get the time array for this segment sliced from the root file segment.
- Returns:
Time values from the root file segment sliced to this segment’s range.
- Return type:
- to_dict()
Return a dict representation of the metadata, usually used prior to converting the dict to a JSON.
- to_json(filename=None)
Return a JSON representation of this, by reporting the important metadata.
- to_meta()
Kept to allow for error handling, but since it’s already a metasegment it won’t actually do anything.
- unique_features
- class ionique.core.Segment(current, **kwargs)
Bases:
AbstractSegmentTreeA data-containing segment of ionic current with computed statistics.
The ionic current is expected to be passed as a numpy array of floats. Metadata methods (mean, std, min, max) are decorated as properties to reduce overall computational time, making them calculated on the fly rather than during analysis.
- Parameters:
current (numpy.ndarray) – Numpy array of ionic current data points.
**kwargs – Additional attributes such as
start,end,rank, etc. Cannot override statistical measurements.
- __init__(current, **kwargs)
Initialize the segment with an ionic current array and optional metadata.
- delete()
Deleting this segment requires deleting its reference to the ionic current array, and then deleting itself.
- classmethod from_json(filename=None, json=None)
Read in a segment from a JSON and return a metasegment object. Either pass in a file which has a segment stored, or an actual JSON object.
- property max
Calculate the maximum value of the current array.
- Returns:
Maximum value of the current array.
- Return type:
- property mean
Calculate the mean of the current array.
- Returns:
Mean value of the current array.
- Return type:
- property min
Calculate the minimum value of the current array.
- Returns:
Minimum value of the current array.
- Return type:
- property n
Get the number of elements in the current array.
- Returns:
Number of elements in the current array.
- Return type:
- scale(sampling_freq)
Rescale all of the values to go from samples to seconds.
- property std
Calculate the standard deviation of the current array.
- Returns:
Standard deviation of the current array.
- Return type:
- to_dict()
Return a dict representation of the metadata, usually used prior to converting the dict to a JSON.
- to_json(filename=None)
Return a JSON representation of this, by reporting the important metadata.
- to_meta()
Convert from a segment to a ‘metasegment’, which stores only metadata about the segment and not the full array of ionic current.