or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-data-structures.mddata-utilities.mdfile-io-support.mdindex.mdrawio-access.md

core-data-structures.mddocs/

0

# Core Data Structures

1

2

Fundamental data containers and objects for representing all types of electrophysiology data. Neo's hierarchical design organizes data into containers (Block, Segment, Group) that hold data objects (signals, spikes, events) with rich metadata and dimensional consistency.

3

4

## Capabilities

5

6

### Container Classes

7

8

Top-level organizational structures that group related electrophysiology data.

9

10

```python { .api }

11

class Block:

12

"""

13

Main container for entire experiments or recording sessions.

14

15

A Block represents the top level grouping of data and is not necessarily

16

temporally homogeneous, in contrast to Segment.

17

"""

18

def __init__(self, name=None, description=None, file_origin=None,

19

file_datetime=None, rec_datetime=None, index=None,

20

**annotations): ...

21

22

# Container relationships

23

segments: list[Segment] # Temporal divisions of the experiment

24

groups: list[Group] # Logical groupings across segments

25

26

# Methods

27

def filter(self, **kwargs): ... # Filter contained objects by properties

28

def merge(self, other): ... # Merge with another Block

29

30

class Segment:

31

"""

32

Container for temporally related data objects.

33

34

A Segment represents a time period within an experiment, typically

35

corresponding to a trial, stimulus presentation, or recording epoch.

36

"""

37

def __init__(self, name=None, description=None, **annotations): ...

38

39

# Data object containers

40

analogsignals: list[AnalogSignal] # Continuous signals

41

irregularlysampledsignals: list[IrregularlySampledSignal] # Non-uniform sampling

42

spiketrains: list[SpikeTrain] # Spike timing data

43

events: list[Event] # Point events

44

epochs: list[Epoch] # Time intervals

45

imagesequences: list[ImageSequence] # Image data sequences

46

47

# Methods

48

def filter(self, **kwargs): ... # Filter contained objects

49

t_start: pq.Quantity # Segment start time

50

t_stop: pq.Quantity # Segment stop time

51

52

class Group:

53

"""

54

Logical grouping container for related data objects.

55

56

Groups organize related objects across segments, typically representing

57

electrode arrays, tetrodes, or other logical recording arrangements.

58

"""

59

def __init__(self, name=None, description=None, **annotations): ...

60

61

# Data object containers (same as Segment)

62

analogsignals: list[AnalogSignal]

63

spiketrains: list[SpikeTrain]

64

events: list[Event]

65

epochs: list[Epoch]

66

```

67

68

### Signal Classes

69

70

Continuous data representations for analog recordings.

71

72

```python { .api }

73

class AnalogSignal:

74

"""

75

Regularly sampled continuous analog signals with physical units.

76

77

Represents multi-channel continuous data like LFP, EEG, voltage clamp

78

recordings, or any uniformly sampled analog measurements.

79

80

Note: The 'copy' parameter is deprecated and will be removed in Neo 0.15.0.

81

Only copy=None is accepted; any other value raises ValueError.

82

"""

83

def __init__(self, signal, units=None, dtype=None, copy=None,

84

t_start=0*pq.s, sampling_rate=None, sampling_period=None,

85

name=None, file_origin=None, description=None,

86

array_annotations=None, **annotations): ...

87

88

# Properties

89

shape: tuple # (n_samples, n_channels)

90

sampling_rate: pq.Quantity # Hz, kHz, etc.

91

sampling_period: pq.Quantity # s, ms, etc.

92

t_start: pq.Quantity # Start time

93

t_stop: pq.Quantity # End time

94

duration: pq.Quantity # Total duration

95

times: pq.Quantity # Time array for each sample

96

97

# Methods

98

def time_slice(self, t_start, t_stop): ... # Extract time window

99

def time_index(self, t): ... # Get array index for time

100

def time_shift(self, t_shift): ... # Shift signal to new start time

101

def downsample(self, downsampling_factor, **kwargs): ... # Downsample signal data

102

def resample(self, sample_count, **kwargs): ... # Resample to fixed sample count

103

def rectify(self, **kwargs): ... # Rectify by taking absolute value

104

def concatenate(self, *signals, overwrite=False, padding=False): ... # Concatenate signals

105

def splice(self, signal, copy=False): ... # Replace part of signal

106

def channel_index_to_channel_id(self, index): ... # Channel mapping

107

def merge(self, other): ... # Combine signals

108

109

class IrregularlySampledSignal:

110

"""

111

Irregularly sampled continuous analog signals.

112

113

For data with non-uniform sampling intervals, where each sample

114

has an associated timestamp.

115

"""

116

def __init__(self, times, signal, units=None, time_units=None,

117

dtype=None, copy=None, name=None, file_origin=None, description=None,

118

array_annotations=None, **annotations): ...

119

120

# Properties

121

times: pq.Quantity # Sample timestamps

122

shape: tuple # (n_samples, n_channels)

123

t_start: pq.Quantity # First timestamp

124

t_stop: pq.Quantity # Last timestamp

125

126

# Methods

127

def time_slice(self, t_start, t_stop): ...

128

def merge(self, other): ...

129

130

class ChannelView:

131

"""

132

View into specific channels of multi-channel signals.

133

134

Provides a way to work with subsets of channels from AnalogSignal

135

or IrregularlySampledSignal objects without copying data.

136

"""

137

def __init__(self, obj, index): ...

138

139

# Properties inherit from parent signal

140

# Methods delegate to parent signal

141

```

142

143

### Event and Timing Classes

144

145

Discrete event data and time interval representations.

146

147

```python { .api }

148

class Event:

149

"""

150

Time-stamped discrete events with labels and annotations.

151

152

Represents point events like stimulus onsets, behavioral markers,

153

or detected events with associated metadata.

154

"""

155

def __init__(self, times, labels=None, units=None, name=None,

156

description=None, **annotations): ...

157

158

# Properties

159

times: pq.Quantity # Event timestamps

160

labels: np.ndarray # String labels for each event

161

size: int # Number of events

162

163

# Methods

164

def time_slice(self, t_start, t_stop): ...

165

def merge(self, other): ...

166

167

class Epoch:

168

"""

169

Time intervals with duration and labels.

170

171

Represents periods of time like stimulus presentations, behavioral

172

states, or analysis windows with start times and durations.

173

"""

174

def __init__(self, times, durations, labels=None, units=None,

175

name=None, description=None, **annotations): ...

176

177

# Properties

178

times: pq.Quantity # Start times

179

durations: pq.Quantity # Duration of each epoch

180

labels: np.ndarray # String labels

181

size: int # Number of epochs

182

183

# Methods

184

def time_slice(self, t_start, t_stop): ...

185

def merge(self, other): ...

186

```

187

188

### Spike Data Classes

189

190

Specialized containers for action potential timing data.

191

192

```python { .api }

193

class SpikeTrain:

194

"""

195

Sequence of action potential timestamps with metadata.

196

197

Represents spike timing data from single units or multi-unit

198

activity with support for waveforms and spike classifications.

199

"""

200

def __init__(self, times, t_stop, units=None, dtype=None, copy=None,

201

sampling_rate=1.0*pq.Hz, t_start=0.0*pq.s, waveforms=None,

202

left_sweep=None, name=None, file_origin=None, description=None,

203

array_annotations=None, **annotations): ...

204

205

# Properties

206

times: pq.Quantity # Spike timestamps

207

t_start: pq.Quantum # Recording start time

208

t_stop: pq.Quantity # Recording stop time

209

duration: pq.Quantity # Total recording duration

210

size: int # Number of spikes

211

waveforms: pq.Quantity # Spike waveform data (optional)

212

sampling_rate: pq.Quantity # Waveform sampling rate

213

left_sweep: pq.Quantity # Pre-spike waveform duration

214

215

# Methods

216

def time_slice(self, t_start, t_stop): ... # Extract time window

217

def merge(self, other): ... # Combine spike trains

218

def isi(self): ... # Inter-spike intervals

219

def cv(self): ... # Coefficient of variation

220

```

221

222

### Image and ROI Classes

223

224

Support for image sequences and regions of interest.

225

226

```python { .api }

227

class ImageSequence:

228

"""

229

Sequences of 2D images with timing information.

230

231

For optical imaging data, calcium imaging, or other image-based

232

measurements with temporal sequences.

233

"""

234

def __init__(self, image_data, units=None, dtype=None, copy=True,

235

t_start=0*pq.s, sampling_rate=None, sampling_period=None,

236

spatial_scale=None, name=None, description=None,

237

**annotations): ...

238

239

# Properties

240

shape: tuple # (n_frames, height, width, [channels])

241

sampling_rate: pq.Quantity # Frame rate

242

spatial_scale: pq.Quantity # Spatial resolution

243

times: pq.Quantity # Frame timestamps

244

245

# Methods

246

def time_slice(self, t_start, t_stop): ...

247

248

class RectangularRegionOfInterest:

249

"""Rectangular region of interest definition."""

250

def __init__(self, x, y, width, height, **annotations): ...

251

252

class CircularRegionOfInterest:

253

"""Circular region of interest definition."""

254

def __init__(self, x, y, radius, **annotations): ...

255

256

class PolygonRegionOfInterest:

257

"""Polygon-shaped region of interest definition."""

258

def __init__(self, x, y, **annotations): ...

259

```

260

261

### Filter Classes

262

263

Query and filtering system for data objects.

264

265

```python { .api }

266

class FilterCondition:

267

"""Abstract base class for filter conditions."""

268

269

class Equals:

270

"""Equality filter condition for data properties."""

271

def __init__(self, value): ...

272

273

class IsNot:

274

"""Inequality filter condition."""

275

def __init__(self, value): ...

276

277

class LessThan:

278

"""Less-than filter condition."""

279

def __init__(self, value): ...

280

281

class GreaterThan:

282

"""Greater-than filter condition."""

283

def __init__(self, value): ...

284

285

class IsIn:

286

"""Membership test filter condition."""

287

def __init__(self, values): ...

288

289

class InRange:

290

"""Range-based filter condition."""

291

def __init__(self, min_val, max_val): ...

292

```

293

294

## Usage Examples

295

296

### Creating and Organizing Data

297

298

```python

299

import neo

300

import numpy as np

301

import quantities as pq

302

303

# Create hierarchical structure

304

block = neo.Block(name="Experiment 1", experimenter="Dr. Smith")

305

segment = neo.Segment(name="Trial 1", trial_id=1)

306

block.segments.append(segment)

307

308

# Add continuous signals

309

signal_data = np.random.randn(1000, 4) * pq.mV

310

analog_signal = neo.AnalogSignal(

311

signal_data,

312

sampling_rate=1*pq.kHz,

313

t_start=0*pq.s,

314

name="LFP",

315

channel_names=['Ch1', 'Ch2', 'Ch3', 'Ch4']

316

)

317

segment.analogsignals.append(analog_signal)

318

319

# Add spike data

320

spike_times = np.array([0.1, 0.3, 0.7, 1.2]) * pq.s

321

spike_train = neo.SpikeTrain(

322

spike_times,

323

t_start=0*pq.s,

324

t_stop=2*pq.s,

325

name="Unit 1"

326

)

327

segment.spiketrains.append(spike_train)

328

329

# Add events

330

event_times = np.array([0.5, 1.0, 1.5]) * pq.s

331

events = neo.Event(

332

event_times,

333

labels=['stimulus_on', 'response', 'stimulus_off']

334

)

335

segment.events.append(events)

336

```

337

338

### Working with Signal Data

339

340

```python

341

# Time slicing

342

signal_slice = analog_signal.time_slice(0.1*pq.s, 0.5*pq.s)

343

344

# Channel selection

345

channel_view = neo.ChannelView(analog_signal, [0, 2]) # Channels 1 and 3

346

347

# Access properties

348

print(f"Shape: {analog_signal.shape}")

349

print(f"Sampling rate: {analog_signal.sampling_rate}")

350

print(f"Duration: {analog_signal.duration}")

351

print(f"Times shape: {analog_signal.times.shape}")

352

```

353

354

### Filtering and Queries

355

356

```python

357

from neo.core.filters import Equals, GreaterThan

358

359

# Filter spike trains by name

360

unit1_trains = segment.filter(name=Equals("Unit 1"), objects="SpikeTrain")

361

362

# Filter events by time

363

late_events = segment.filter(times=GreaterThan(1.0*pq.s), objects="Event")

364

365

# Complex filtering

366

fast_spikes = segment.filter(

367

name=Equals("Unit 1"),

368

size=GreaterThan(10),

369

objects="SpikeTrain"

370

)

371

```

372

373

## Types

374

375

```python { .api }

376

# Base quantity types from quantities package

377

Signal = np.ndarray * pq.Quantity # Multidimensional array with units

378

Time = pq.Quantity # Time values (s, ms, μs, etc.)

379

Rate = pq.Quantity # Frequencies (Hz, kHz, MHz, etc.)

380

Voltage = pq.Quantity # Electrical potential (V, mV, μV, etc.)

381

382

# Container types

383

BlockList = list[Block] # List of Block objects

384

SegmentList = list[Segment] # List of Segment objects

385

GroupList = list[Group] # List of Group objects

386

387

# Data object types

388

AnalogSignalList = list[AnalogSignal] # List of AnalogSignal objects

389

SpikeTrainList = list[SpikeTrain] # List of SpikeTrain objects

390

EventList = list[Event] # List of Event objects

391

EpochList = list[Epoch] # List of Epoch objects

392

393

# Metadata types

394

Annotations = dict[str, Any] # Arbitrary key-value metadata

395

ChannelNames = list[str] # Channel identification strings

396

Labels = np.ndarray # String labels for events/epochs

397

```