Signal processing
Every channel is one food electrode ("cup") of one fly; with two substrates, a fly has two consecutive channels (odd = substrate 1, even = substrate 2). The capacitance is sampled at 100 Hz (1 sample = 10 ms); sample numbers in Python files are 0-based (MATLAB's minus 1).
Trimmed recording
The recorded samples of the channel, at most 360000 (a shorter recording is not padded: its analysis ends with the recording, and a Data checks warning says so), minus 4 samples at the start and 5 at the end (MATLAB test(5:end-5)). USB dropouts (frames in which every channel is 5000, written by FlyPad Acquisition) hold the channel's last real value, so they contain no events (events are sample numbers of the detrended trace: raw frame = sample + 53, 4 trimmed + 49 detrend samples; an event whose start lies in a dropout is dropped). A channel with ≥ 50% zero samples (of those recorded) is treated as unconnected and yields no events.
InterpretationLength of the analysed recording; the trimming only removes edge artefacts.
Code:
core/pipeline.py::run_pipeline, core/data_loader.py::check_connectivity · fingerprint 1cd813e2c909Median-filtered signal
Median over 6 samples x(k-3..k+2), zero-padded; the median of an even count is the mean of the two middle values (MATLAB medfilt1(x, 6)). Computed exactly in integers.
InterpretationRemoves single-sample spikes while keeping the sharp steps of proboscis contacts.
Code:
core/signal_processing.py::median_filter_x2 · fingerprint d8be006f0b38Detrended trace R
Median-filtered signal minus its 50-sample moving average (MATLAB convn 'same'), then trimmed by 49 samples at the start and 50 at the end. Computed exactly in integers (100 × R); MATLAB's floating-point rounding is reproduced only where values tie exactly (it decides which of equal samples is taken).
InterpretationRemoves slow drift (evaporation, temperature). Side effect: every step leaves small 'echoes' (1/50 of its size) 25 samples before and after it – the reason for detection V2 (see Sips).
Code:
core/signal_processing.py::detrend, core/signal_processing.py::window_sum, core/signal_processing.py::matlab_detrended · fingerprint 3bace2a170c0Activity (RMS) mask
RMS of R over 300 samples (MATLAB fastrms, centred) above the RMS threshold (1.0 counts). V2 (default) raises the threshold to 1.5 × the RMS of the quietest 10% of the recording when that is higher, so noise alone can never make the whole recording 'active'.
InterpretationMarks periods of physical interaction with the food electrode (legs, proboscis). Basis of activity bouts and of the noise level used for sip detection.
Code:
core/signal_processing.py::activity_mask · fingerprint 2862c63f0530Sips
A sip is one proboscis contact with the food: a fast rise of the capacitance followed by a fast fall. Two detection versions exist (menu Sip detection, setup wizard): V1 – MATLAB (identical to the MATLAB analysis) and V2 – current version (default). Compare results only within one version.
Sip onset / offset
Derivative D of R. Noise thresholds = largest positive / negative D outside activity (R set to 0 during activity). Samples of D beyond them are kept; among those, only peaks survive (MATLAB findpeaks: plateau = first sample, neighbours within 7 samples of a larger peak removed). From each positive peak (onset) the offset is the first negative peak within 100 samples with D ≤ -0.5 × the onset peak, at least 4 samples later (MATLAB counts the onset sample itself). The search then continues after the offset. V2 also requires the onset peak ≥ 0.5 × |offset peak|, i.e. rise and fall of similar size.
InterpretationOnset = steepest point of the rise, offset = steepest point of the fall (resolution 10 ms). V1 takes a detrending echo just before a sip as its onset for ≈12% of sips (onset ≈100 ms early) and pairs echoes into spurious sips (≈10%; 2016-03-21 sample data); V2 does not. Synthetic ground truth, V2: ≥ 98% of sips found at the right onset, durations within 10 ms. Limits: sips shorter than ≈30 ms and slow, staircase rises (≈0.7% of sips) can be missed; very noisy recordings (step < ≈5 × noise SD) lose sips.
Where: Events: onsets, offsets
Code:
core/sip_detection.py::detect_sips, core/sip_detection.py::_matlab_findpeaks · fingerprint 7dab289a3e51Sip duration
offset – onset (samples / 100).
InterpretationContact time of one sip; typical 0.1-0.2 s. Longer sips can mean more ingestion per sip or slower engorgement.
Code:
core/sip_detection.py::detect_sips · fingerprint 3bad3cba97d8Inter-sip interval (IFI / ISI)
Onset of a sip – offset of the previous sip.
InterpretationPause between contacts. Within feeding bursts it reflects the rhythm of the feeding motor program (≈0.05-0.1 s); longer values mark pauses between bursts.
Code:
core/sip_detection.py::detect_sips · fingerprint 3bad3cba97d8In-burst / isolated sips
A sip whose onset lies between the first and last sip onset of a feeding burst is 'in burst', all others are 'isolated'; durations are kept for both groups.
InterpretationSeparates rhythmic feeding from single probing contacts.
Code:
core/post_processing.py::_classify_sips · fingerprint 7533b7f2b4eaActivity bouts
An activity bout is a continuous period in which the activity mask is on: the fly interacts with the food electrode (feeding or not).
Activity bout onset / offset / duration
Onset = last inactive sample before the mask turns on, offset = last active sample (MATLAB find(diff(mask) > 0 / < 0)); duration = offset – onset. Bouts cut off by the start or end of the recording are dropped (MATLAB kept one in a special case, with a negative duration; fixed).
InterpretationPeriods of engagement with the food. Long bouts = sustained feeding or grooming at the cup; many short bouts = sampling/exploration.
Code:
core/signal_processing.py::detect_activity_bouts · fingerprint c71bc6f2f762Activity bout IBI
Onset of a bout – offset of the previous bout.
InterpretationTime away from this food electrode between visits.
Code:
analysis/statistics.py::median_bout_ibi, export/extra_outputs.py::rms_events_ibi · fingerprint 35411d59b9aaActive samples
All samples where the activity mask is on (also those of dropped edge bouts).
InterpretationBasis of the cumulative activity time courses.
Code:
core/signal_processing.py::detect_activity_bouts · fingerprint c71bc6f2f762Feeding bursts
A feeding burst is a train of sips with regular, short intervals: bouts of rhythmic feeding.
Feeding burst
Consecutive sips are grouped while each inter-sip interval is ≤ 2 × the fly's most frequent interval (mode of its IFIs; the smallest value on ties); a group of ≥ 3 sips is a burst. Onset = onset of its first sip, offset = onset of its last sip (MATLAB GET_FEEDING_BURSTS).
InterpretationPeriods of uninterrupted feeding at the frequency of the feeding central pattern generator (CPG), with at least 3 sips. The threshold adapts to each fly's own rhythm.
Code:
core/burst_detection.py::detect_feeding_bursts, core/post_processing.py::_detect_all_bursts · fingerprint 3927a72d5a21Burst duration / sips per burst / burst IBI
Duration = last sip onset – first sip onset; number of sips in the burst; IBI = next burst onset – this burst's offset.
InterpretationBurst duration and size = persistence of a feeding episode; burst IBI = pause between episodes.
Code:
core/burst_detection.py::detect_feeding_bursts · fingerprint ba07a94537f1Bursts per activity bout
Bursts whose onset lies within the bout (onset..offset inclusive).
InterpretationHow much of a visit is spent feeding rhythmically; 0 = a visit without feeding.
Code:
core/post_processing.py::_compute_bout_burst_metrics · fingerprint f820111caa37Insider IBI
Burst IBI after each burst that ends inside a bout, except the bout's last burst.
InterpretationPauses between feeding episodes without leaving the food.
Code:
core/post_processing.py::_compute_bout_burst_metrics · fingerprint f820111caa37Burst latency
First burst onset inside the bout – bout onset; empty for a bout without a burst. (MATLAB takes the nearest burst onset anywhere, which is a burst before the bout for ≈5% of bouts; fixed.)
InterpretationHow quickly rhythmic feeding starts after the fly engages with the food.
Code:
core/post_processing.py::_compute_bout_burst_metrics · fingerprint f820111caa37