• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

paulmthompson / WhiskerToolbox / 17920603410

22 Sep 2025 03:39PM UTC coverage: 71.97% (-0.05%) from 72.02%
17920603410

push

github

paulmthompson
all tests pass

277 of 288 new or added lines in 8 files covered. (96.18%)

520 existing lines in 35 files now uncovered.

40275 of 55961 relevant lines covered (71.97%)

1225.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.89
/src/DataManager/DigitalTimeSeries/Digital_Event_Series.cpp
1
#include "Digital_Event_Series.hpp"
2

3
#include "Entity/EntityRegistry.hpp"
4
#include "TimeFrame/TimeFrame.hpp"
5

6
#include <algorithm>// std::sort
7

8
DigitalEventSeries::DigitalEventSeries(std::vector<float> event_vector) {
123✔
9
    setData(std::move(event_vector));
123✔
10
}
123✔
11

12
void DigitalEventSeries::setData(std::vector<float> event_vector) {
143✔
13
    _data = std::move(event_vector);
143✔
14
    _sortEvents();
143✔
15
    notifyObservers();
143✔
16
    // Rebuild IDs if identity context present
17
    if (_identity_registry) {
143✔
18
        rebuildAllEntityIds();
×
19
    }
20
}
143✔
21

22
std::vector<float> const & DigitalEventSeries::getEventSeries() const {
30✔
23
    return _data;
30✔
24
}
25

26
void DigitalEventSeries::addEvent(float const event_time) {
137✔
27

28
    if (std::ranges::find(_data, event_time) != _data.end()) {
137✔
29
        return;
2✔
30
    }
31

32
    _data.push_back(event_time);
135✔
33

34
    _sortEvents();
135✔
35

36
    notifyObservers();
135✔
37
    if (_identity_registry) {
135✔
38
        // Rebuild to ensure order alignment
39
        rebuildAllEntityIds();
×
40
    }
41
}
42

43
bool DigitalEventSeries::removeEvent(float const event_time) {
5✔
44
    auto it = std::ranges::find(_data, event_time);
5✔
45
    if (it != _data.end()) {
5✔
46
        _data.erase(it);
3✔
47
        notifyObservers();
3✔
48
        if (_identity_registry) {
3✔
49
            rebuildAllEntityIds();
×
50
        }
51
        return true;
3✔
52
    }
53
    return false;
2✔
54
}
55

56
void DigitalEventSeries::_sortEvents() {
278✔
57
    std::ranges::sort(_data);
278✔
58
}
278✔
59

60
void DigitalEventSeries::rebuildAllEntityIds() {
33✔
61
    if (!_identity_registry) {
33✔
62
        _entity_ids.assign(_data.size(), 0);
×
63
        return;
×
64
    }
65
    _entity_ids.clear();
33✔
66
    _entity_ids.reserve(_data.size());
33✔
67
    for (int i = 0; i < static_cast<int>(_data.size()); ++i) {
506✔
68
        // Use time index = i (since data is float times, but consistent order gives stable local index)
69
        _entity_ids.push_back(_identity_registry->ensureId(_identity_data_key, EntityKind::EventEntity, TimeFrameIndex{i}, i));
473✔
70
    }
71
}
72

73
// ========== Events with EntityIDs ==========
74

75
std::vector<EventWithId> DigitalEventSeries::getEventsWithIdsInRange(TimeFrameIndex start_time, TimeFrameIndex stop_time) const {
4,556✔
76
    std::vector<EventWithId> result;
4,556✔
77
    //result.reserve(_data.size());// Reserve space for potential worst case
78

79
    for (size_t i = 0; i < _data.size(); ++i) {
50,341✔
80
        if (_data[i] >= static_cast<float>(start_time.getValue()) && _data[i] <= static_cast<float>(stop_time.getValue())) {
45,785✔
81
            EntityId const entity_id = (i < _entity_ids.size()) ? _entity_ids[i] : 0;
1,118✔
82
            result.emplace_back(_data[i], entity_id);
1,118✔
83
        }
84
    }
85
    return result;
4,556✔
UNCOV
86
}
×
87

88
std::vector<EventWithId> DigitalEventSeries::getEventsWithIdsInRange(TimeFrameIndex start_index,
4,556✔
89
                                                                     TimeFrameIndex stop_index,
90
                                                                     TimeFrame const * source_time_frame,
91
                                                                     TimeFrame const * event_time_frame) const {
92
    if (source_time_frame == event_time_frame) {
4,556✔
UNCOV
93
        return getEventsWithIdsInRange(start_index, stop_index);
×
94
    }
95

96
    // If either timeframe is null, fall back to original behavior
97
    if (!source_time_frame || !event_time_frame) {
4,556✔
UNCOV
98
        return getEventsWithIdsInRange(start_index, stop_index);
×
99
    }
100

101
    auto [target_start_index, target_stop_index] = _convertTimeFrameRange(start_index, stop_index, source_time_frame, event_time_frame);
4,556✔
102
    return getEventsWithIdsInRange(target_start_index, target_stop_index);
4,556✔
103
}
104

105
// ========== Helper Functions for Time Frame Conversion ==========
106

107
std::pair<TimeFrameIndex, TimeFrameIndex> DigitalEventSeries::_convertTimeFrameRange(
4,556✔
108
        TimeFrameIndex const start_index,
109
        TimeFrameIndex const stop_index,
110
        TimeFrame const * const source_time_frame,
111
        TimeFrame const * const target_time_frame) {
112

113
    // Get the time values from the source timeframe
114
    auto start_time_value = source_time_frame->getTimeAtIndex(start_index);
4,556✔
115
    auto stop_time_value = source_time_frame->getTimeAtIndex(stop_index);
4,556✔
116

117
    // Convert to indices in the target timeframe
118
    auto target_start_index = target_time_frame->getIndexAtTime(static_cast<float>(start_time_value), false);
4,556✔
119
    auto target_stop_index = target_time_frame->getIndexAtTime(static_cast<float>(stop_time_value));
4,556✔
120

121
    return {target_start_index, target_stop_index};
9,112✔
122
}
123

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc