detectCycles method
Detects sit-to-stand cycles based on peaks and troughs.
peaks
- List of peak indices.
troughs
- List of trough indices.
filteredAcc
- Filtered accelerometer or gyroscope data.
timestamps
- List of timestamps.
minCycleDuration
- Minimum duration for a valid cycle.
Returns a list of detected Cycles.
Implementation
List<Cycle> detectCycles({
required List<int> peaks,
required List<int> troughs,
required List<SensorEvent> filteredAcc,
required List<DateTime> timestamps,
required double minCycleDuration,
}) {
List<Cycle> cycles = [];
// 1. Standard detection: peak → trough → peak
for (int i = 0; i < peaks.length - 1; i++) {
int peak1 = peaks[i];
int peak2 = peaks[i + 1];
final validTroughs = troughs.where((t) => t > peak1 && t < peak2).toList();
if (validTroughs.isNotEmpty) {
int troughBetween = validTroughs.first;
double durationSec = timestamps[peak2].difference(timestamps[peak1]).inMilliseconds / 1000;
if (durationSec >= minCycleDuration) {
final events = filteredAcc.sublist(peak1, peak2 + 1);
cycles.add(Cycle(peak1, peak2, events));
if (kDebugMode) {
print('[StsProcessor] Cycle from peak $peak1 to $peak2 via trough $troughBetween');
}
}
}
}
// 2. Edge-case: last "peak → (trough) → END"
if (peaks.isNotEmpty && troughs.isNotEmpty) {
int lastPeak = peaks.last;
final troughsAfterLastPeak = troughs.where((t) => t > lastPeak).toList();
if (troughsAfterLastPeak.isNotEmpty) {
final events = filteredAcc.sublist(lastPeak, filteredAcc.length);
cycles.add(Cycle(lastPeak, filteredAcc.length - 1, events));
if (kDebugMode) {
print('[StsProcessor] (Edge) Cycle from last peak $lastPeak to END (trough after last peak)');
}
}
}
return cycles;
}