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

paulmthompson / WhiskerToolbox / 17846711083

19 Sep 2025 02:28AM UTC coverage: 72.02% (+0.08%) from 71.942%
17846711083

push

github

paulmthompson
event in interval computer works with entity ids

259 of 280 new or added lines in 6 files covered. (92.5%)

268 existing lines in 17 files now uncovered.

40247 of 55883 relevant lines covered (72.02%)

1227.29 hits per line

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

85.71
/src/DataManager/utils/TableView/computers/EventInIntervalComputer.h
1
#ifndef EVENT_IN_INTERVAL_COMPUTER_H
2
#define EVENT_IN_INTERVAL_COMPUTER_H
3

4
#include "utils/TableView/core/ExecutionPlan.h"
5
#include "utils/TableView/interfaces/IColumnComputer.h"
6

7
#include <algorithm>
8
#include <cstdint>
9
#include <memory>
10
#include <span>
11
#include <string>
12
#include <vector>
13

14
class IEventSource;
15

16
/**
17
 * @brief Enumeration of operations that can be performed on events within intervals.
18
 */
19
enum class EventOperation : std::uint8_t {
20
    Presence,    ///< Returns bool: true if any events exist in the interval
21
    Count,       ///< Returns int: number of events in the interval
22
    Gather,      ///< Returns std::vector<float>: all events in the interval
23
    Gather_Center///< Returns std::vector<float>: all events in the interval, centered relative to interval center
24
};
25

26
/**
27
 * @brief Templated computer for processing events within time intervals.
28
 * 
29
 * Source type: IEventSource
30
 * Selector type: Interval
31
 * Output type: T
32
 * 
33
 * This computer analyzes event data from an IEventSource and performs statistical operations
34
 * on events that fall within specified time intervals. It supports different analysis modes
35
 * through the EventOperation enum, each requiring a specific template parameter type.
36
 * 
37
 * The computer efficiently processes events using binary search algorithms and handles
38
 * time frame conversions between source and destination time frames automatically.
39
 * 
40
 * @tparam T The return type for the computation. Must match the operation:
41
 *           - EventOperation::Presence requires T = bool
42
 *           - EventOperation::Count requires T = int  
43
 *           - EventOperation::Gather requires T = std::vector<float>
44
 *           - EventOperation::Gather_Center requires T = std::vector<float>
45
 * 
46
 * @par Usage Example:
47
 * @code
48
 * // Create an event source with spike data
49
 * auto spikeSource = std::make_shared<SpikeEventSource>("Neuron1", timeFrame, spikeTimes);
50
 * 
51
 * // Create intervals for analysis
52
 * std::vector<TimeFrameInterval> intervals = {
53
 *     TimeFrameInterval(TimeFrameIndex(0), TimeFrameIndex(10)),  // 0-10ms
54
 *     TimeFrameInterval(TimeFrameIndex(10), TimeFrameIndex(20)), // 10-20ms
55
 *     TimeFrameInterval(TimeFrameIndex(20), TimeFrameIndex(30))  // 20-30ms
56
 * };
57
 * ExecutionPlan plan(intervals, timeFrame);
58
 * 
59
 * // Check for presence of events in each interval
60
 * EventInIntervalComputer<bool> presenceComputer(spikeSource, EventOperation::Presence, "Neuron1");
61
 * auto presenceResults = presenceComputer.compute(plan);
62
 * // Result: [true, false, true] - events present in intervals 0-10ms and 20-30ms
63
 * 
64
 * // Count events in each interval
65
 * EventInIntervalComputer<int> countComputer(spikeSource, EventOperation::Count, "Neuron1");
66
 * auto countResults = countComputer.compute(plan);
67
 * // Result: [3, 0, 2] - 3 events in 0-10ms, 0 in 10-20ms, 2 in 20-30ms
68
 * 
69
 * // Gather all events in each interval
70
 * EventInIntervalComputer<std::vector<float>> gatherComputer(spikeSource, EventOperation::Gather, "Neuron1");
71
 * auto gatherResults = gatherComputer.compute(plan);
72
 * // Result: [[1.2, 3.4, 8.9], [], [22.1, 25.7]] - actual event times
73
 * @endcode
74
 * 
75
 */
76
template<typename T>
77
class EventInIntervalComputer : public IColumnComputer<T> {
78
public:
79
    /**
80
     * @brief Constructor for EventInIntervalComputer.
81
     * 
82
     * Creates a computer that will analyze events from the specified source using
83
     * the given operation. The source name is used for dependency tracking in
84
     * the table view system.
85
     * 
86
     * @param source Shared pointer to the event source providing the event data.
87
     *               Must not be null.
88
     * @param operation The statistical operation to perform on events within intervals.
89
     *                 Must be compatible with the template parameter T.
90
     * @param sourceName The name of the data source for dependency tracking.
91
     *                  Used to identify data dependencies in the table view system.
92
     * 
93
     * @pre @p source is not null
94
     * @pre @p sourceName is not empty
95
     * @pre @p operation is compatible with template parameter T:
96
     *      - EventOperation::Presence requires T = bool
97
     *      - EventOperation::Count requires T = int
98
     *      - EventOperation::Gather requires T = std::vector<float>
99
     *      - EventOperation::Gather_Center requires T = std::vector<float>
100
     * 
101
     * @post The computer is ready to process events from the specified source
102
     * @post getSourceDependency() returns @p sourceName
103
     */
104
    EventInIntervalComputer(std::shared_ptr<IEventSource> source,
213✔
105
                            EventOperation operation,
106
                            std::string sourceName)
107
        : m_source(std::move(source)),
213✔
108
          m_operation(operation),
213✔
109
          m_sourceName(std::move(sourceName)) {}
426✔
110

111
    /**
112
     * @brief Computes the result for all intervals in the execution plan.
113
     * 
114
     * Processes each interval in the execution plan and applies the configured
115
     * operation to events that fall within each interval. The computation handles
116
     * time frame conversions automatically between the source and destination time frames.
117
     * 
118
     * @param plan The execution plan containing interval boundaries and destination time frame.
119
     *             Must contain valid intervals and a non-null time frame.
120
     * 
121
     * @return Vector of computed results for each interval in the same order as the plan.
122
     *         The size of the result vector equals the number of intervals in the plan.
123
     * 
124
     * @pre @p plan contains valid intervals (start <= end for each interval)
125
     * @pre @p plan.getTimeFrame() is not null
126
     * @pre The template parameter T matches the operation type:
127
     *      - EventOperation::Presence requires T = bool
128
     *      - EventOperation::Count requires T = int
129
     *      - EventOperation::Gather requires T = std::vector<float>
130
     *      - EventOperation::Gather_Center requires T = std::vector<float>
131
     * 
132
     * @post Result vector size equals plan.getIntervals().size()
133
     * @post For Presence operation: each result is true if any events exist in the interval, false otherwise
134
     * @post For Count operation: each result is the number of events in the corresponding interval
135
     * @post For Gather operation: each result is a vector of event times within the interval
136
     * @post For Gather_Center operation: each result is a vector of event times relative to interval center
137
     * 
138
     * @throws std::runtime_error if the operation type doesn't match the template parameter T
139
     * @throws std::runtime_error if the source time frame is incompatible with the destination time frame
140
     */
141
    [[nodiscard]] std::vector<T> compute(ExecutionPlan const & plan) const override;
142

143
    /**
144
     * @brief Returns the name of the data source this computer depends on.
145
     * 
146
     * Used by the table view system to track data dependencies and determine
147
     * when recomputation is needed.
148
     * 
149
     * @return The name of the source dependency as specified in the constructor.
150
     */
151
    [[nodiscard]] std::string getSourceDependency() const override {
1,302✔
152
        return m_sourceName;
1,302✔
153
    }
154

155
    /**
156
     * @brief Gets the EntityID structure type for this computer.
157
     * 
158
     * For EventInIntervalComputer, the EntityID structure depends on the operation:
159
     * - Presence and Count operations have no EntityIDs (EntityIdStructure::None)
160
     * - Gather and Gather_Center operations provide multiple EntityIDs per row (EntityIdStructure::Complex)
161
     * 
162
     * @return The EntityID structure type for this computer.
163
     */
164
    [[nodiscard]] EntityIdStructure getEntityIdStructure() const override {
23✔
165
        switch (m_operation) {
23✔
166
            case EventOperation::Presence:
8✔
167
            case EventOperation::Count:
168
                return EntityIdStructure::None;
8✔
169
            case EventOperation::Gather:
15✔
170
            case EventOperation::Gather_Center:
171
                return EntityIdStructure::Complex; // Multiple EntityIDs per row (all events in interval)
15✔
NEW
172
            default:
×
NEW
173
                return EntityIdStructure::None;
×
174
        }
175
    }
176

177
    /**
178
     * @brief Computes all EntityIDs for the column.
179
     * 
180
     * For Gather and Gather_Center operations, this returns a vector of vectors where each
181
     * inner vector contains the EntityIDs of all events that fall within the corresponding interval.
182
     * 
183
     * @param plan The execution plan containing interval boundaries and destination time frame.
184
     * @return ColumnEntityIds variant containing the EntityIDs for this column.
185
     */
186
    [[nodiscard]] ColumnEntityIds computeColumnEntityIds(ExecutionPlan const & plan) const override;
187

188
private:
189
    std::shared_ptr<IEventSource> m_source;
190
    EventOperation m_operation;
191
    std::string m_sourceName;
192

193
    /**
194
     * @brief Finds events within a specific interval using binary search.
195
     * 
196
     * Efficiently locates all events that fall within the specified interval
197
     * using binary search algorithms. This method assumes the events are
198
     * sorted in ascending order.
199
     * 
200
     * @param events Span of all events, must be sorted in ascending order.
201
     * @param startIdx Start index of the interval (inclusive).
202
     * @param endIdx End index of the interval (inclusive).
203
     * 
204
     * @return Vector of TimeFrameIndex values representing events within the interval.
205
     *         Events are returned in ascending order.
206
     * 
207
     * @pre @p events is sorted in ascending order
208
     * @pre @p startIdx <= @p endIdx
209
     * 
210
     * @post Result contains only events where startIdx <= event <= endIdx
211
     * @post Result is sorted in ascending order
212
     * 
213
     * @note Time complexity: O(log n) where n is the number of events
214
     */
215
    [[nodiscard]] std::vector<TimeFrameIndex> findEventsInInterval(std::span<TimeFrameIndex const> events,
216
                                                                   TimeFrameIndex startIdx,
217
                                                                   TimeFrameIndex endIdx) const;
218
};
219

220
// Template specializations for different operation types
221
template<>
222
[[nodiscard]] std::vector<bool> EventInIntervalComputer<bool>::compute(ExecutionPlan const & plan) const;
223

224
template<>
225
[[nodiscard]] std::vector<int> EventInIntervalComputer<int>::compute(ExecutionPlan const & plan) const;
226

227
template<>
228
[[nodiscard]] std::vector<std::vector<float>> EventInIntervalComputer<std::vector<float>>::compute(ExecutionPlan const & plan) const;
229

230
#endif// EVENT_IN_INTERVAL_COMPUTER_H
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