Coverage for src/driada/experiment/synthetic/core.py: 65.00%
40 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-25 15:40 +0300
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-25 15:40 +0300
1"""
2Core utilities for synthetic data generation.
4This module contains the fundamental utilities used across all synthetic data
5generation functions, including firing rate validation and calcium signal generation.
6"""
8import numpy as np
9import warnings
10from ..exp_base import *
11from ...information.info_base import TimeSeries, MultiTimeSeries, aggregate_multiple_ts
14def validate_peak_rate(peak_rate, context=""):
15 """
16 Validate that peak firing rate is within physiologically realistic range.
18 Parameters
19 ----------
20 peak_rate : float
21 Peak firing rate in Hz.
22 context : str, optional
23 Context string for more informative warning message.
25 Notes
26 -----
27 Typical firing rates for neurons:
28 - Cortical pyramidal cells: 0.1-2 Hz (sparse firing)
29 - Hippocampal place cells: 0.5-5 Hz (with brief peaks up to 20 Hz)
30 - Fast-spiking interneurons: 5-50 Hz
32 For calcium imaging with GCaMP indicators:
33 - Decay time ~1-2 seconds limits temporal resolution
34 - Firing rates >2 Hz can cause signal saturation
35 - Realistic modeling should use rates in 0.1-2 Hz range
36 """
37 if peak_rate > 2.0:
38 warning_msg = (
39 f"peak_rate={peak_rate:.1f} Hz exceeds recommended maximum of 2.0 Hz "
40 f"for calcium imaging. "
41 f"High firing rates can cause calcium signal saturation due to slow "
42 f"indicator dynamics (decay time ~2s). Consider using peak_rate <= 2.0 Hz "
43 f"for more realistic calcium traces."
44 )
45 if context:
46 warning_msg = f"{context}: {warning_msg}"
47 warnings.warn(warning_msg, UserWarning, stacklevel=2)
50def generate_pseudo_calcium_signal(events=None,
51 duration=600,
52 sampling_rate=20.0,
53 event_rate=0.2,
54 amplitude_range=(0.5,2),
55 decay_time=2,
56 noise_std=0.1):
58 """
59 Generate a pseudo-calcium imaging signal with noise.
61 Parameters:
62 - duration: Total duration of the signal in seconds.
63 - sampling_rate: Sampling rate in Hz.
64 - event_rate: Average rate of calcium events per second.
65 - amplitude_range: Tuple of (min, max) for the amplitude of calcium events.
66 - decay_time: Time constant for the decay of calcium events in seconds.
67 - noise_std: Standard deviation of the Gaussian noise to be added.
69 Returns:
70 - signal: Numpy array representing the pseudo-calcium signal.
71 """
73 if events is None:
74 # Calculate number of samples
75 num_samples = int(duration * sampling_rate)
77 # Generate calcium events
78 num_events = np.random.poisson(event_rate * duration)
79 event_times = np.random.uniform(0, duration, num_events)
80 event_amplitudes = np.random.uniform(amplitude_range[0], amplitude_range[1], num_events)
82 else:
83 num_samples = len(events)
84 event_times = np.where(events>0)[0]
85 # Use amplitude_range to modulate event amplitudes instead of using binary values
86 if len(event_times) > 0:
87 event_amplitudes = np.random.uniform(amplitude_range[0], amplitude_range[1], len(event_times))
88 else:
89 event_amplitudes = np.array([])
91 # Initialize the signal with zeros
92 signal = np.zeros(num_samples)
94 # Add calcium events to the signal
95 for t, a in zip(event_times, event_amplitudes):
96 if events is None:
97 event_index = int(t * sampling_rate)
98 else:
99 event_index = int(t)
101 decay = np.exp(-np.arange(num_samples - event_index) / (decay_time * sampling_rate))
102 signal[event_index:] += a * decay
104 # Add Gaussian noise
105 noise = np.random.normal(0, noise_std, num_samples)
106 signal += noise
108 return signal
111def generate_pseudo_calcium_multisignal(n,
112 events=None,
113 duration=600,
114 sampling_rate=20,
115 event_rate=0.2,
116 amplitude_range=(0.5,2),
117 decay_time=2,
118 noise_std=0.1):
119 """
120 Generate multiple pseudo calcium signals.
122 Parameters
123 ----------
124 n : int
125 Number of neurons.
126 events : ndarray, optional
127 Event array (n_neurons x n_timepoints).
128 duration : float
129 Duration in seconds.
130 sampling_rate : float
131 Sampling rate in Hz.
132 event_rate : float
133 Average rate of calcium events per second.
134 amplitude_range : tuple
135 (min, max) for the amplitude of calcium events.
136 decay_time : float
137 Time constant for the decay of calcium events in seconds.
138 noise_std : float
139 Standard deviation of the Gaussian noise.
141 Returns
142 -------
143 ndarray
144 Calcium signals (n_neurons x n_timepoints).
145 """
146 sigs = []
147 for i in range(n):
148 local_events = None
149 if events is not None:
150 local_events = events[i, :]
152 sig = generate_pseudo_calcium_signal(events=local_events,
153 duration=duration,
154 sampling_rate=sampling_rate,
155 event_rate=event_rate,
156 amplitude_range=amplitude_range,
157 decay_time=decay_time,
158 noise_std=noise_std)
159 sigs.append(sig)
161 return np.vstack(sigs)