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

paulmthompson / WhiskerToolbox / 17700769195

13 Sep 2025 06:37PM UTC coverage: 71.744% (-0.1%) from 71.842%
17700769195

push

github

paulmthompson
update to new version of whisker tracker

7 of 84 new or added lines in 2 files covered. (8.33%)

112 existing lines in 5 files now uncovered.

37096 of 51706 relevant lines covered (71.74%)

1307.13 hits per line

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

69.96
/src/DataManager/utils/TableView/ComputerRegistry.cpp
1
#include "ComputerRegistry.hpp"
2

3
#include "Lines/Line_Data.hpp"
4
#include "Points/Point_Data.hpp"
5
#include "adapters/LineDataAdapter.h"
6
#include "adapters/PointComponentAdapter.h"
7
#include "computers/AnalogSliceGathererComputer.h"
8
#include "computers/AnalogTimestampOffsetsMultiComputer.h"
9
#include "computers/EventInIntervalComputer.h"
10
#include "computers/IntervalOverlapComputer.h"
11
#include "computers/IntervalPropertyComputer.h"
12
#include "computers/IntervalReductionComputer.h"
13
#include "computers/LineSamplingMultiComputer.h"
14
#include "computers/TimestampInIntervalComputer.h"
15
#include "computers/TimestampValueComputer.h"
16
#include "interfaces/IEventSource.h"
17
#include "interfaces/ILineSource.h"
18

19
#include <iostream>
20
#include <optional>
21
#include <set>
22
#include <sstream>
23

24
IParameterDescriptor::IParameterDescriptor() = default;
1,895✔
25

26
IParameterDescriptor::~IParameterDescriptor() = default;
1,895✔
27

UNCOV
28
ComputerParameterInfo::ComputerParameterInfo()
×
UNCOV
29
    : name(),
×
UNCOV
30
      description(),
×
31
      type(typeid(void)),
×
32
      isRequired(false),
×
UNCOV
33
      defaultValue() {}
×
34

35
ComputerParameterInfo::ComputerParameterInfo(std::string name_, std::string description_, std::type_index type_, bool required, std::string defaultValue_)
×
UNCOV
36
    : name(std::move(name_)),
×
37
      description(std::move(description_)),
×
UNCOV
38
      type(type_),
×
UNCOV
39
      isRequired(required),
×
UNCOV
40
      defaultValue(std::move(defaultValue_)) {}
×
41

UNCOV
42
ComputerParameterInfo::~ComputerParameterInfo() = default;
×
43

44
ComputerRegistry::ComputerRegistry() {
290✔
45
    //std::cout << "Initializing Computer Registry..." << std::endl;
46

47
    registerBuiltInComputers();
290✔
48
    registerBuiltInAdapters();
290✔
49

50
    computeComputerMappings();
290✔
51
    computeAdapterMappings();
290✔
52

53
    /*
54
    std::cout << "Computer Registry Initialized with " 
55
              << all_computers_.size() << " computers and " 
56
              << all_adapters_.size() << " adapters." << std::endl;
57
    */
58
}
290✔
59

60
std::vector<ComputerInfo> ComputerRegistry::getAvailableComputers(
395✔
61
        RowSelectorType rowSelectorType,
62
        DataSourceVariant const & dataSource) const {
63

64
    auto sourceTypeIndex = getSourceTypeIndex(dataSource);
395✔
65
    auto key = std::make_pair(rowSelectorType, sourceTypeIndex);
395✔
66

67
    auto it = selector_source_to_computers_.find(key);
395✔
68
    if (it != selector_source_to_computers_.end()) {
395✔
69
        std::vector<ComputerInfo> result;
395✔
70
        result.reserve(it->second.size());
395✔
71

72
        for (auto const * computerInfo: it->second) {
2,690✔
73
            result.push_back(*computerInfo);
2,295✔
74
        }
75

76
        return result;
395✔
77
    }
395✔
78

79
    return {};// No computers available for this combination
×
80
}
81

82
std::vector<AdapterInfo> ComputerRegistry::getAvailableAdapters(std::type_index dataType) const {
×
UNCOV
83
    auto it = input_type_to_adapters_.find(dataType);
×
84
    if (it != input_type_to_adapters_.end()) {
×
85
        std::vector<AdapterInfo> result;
×
UNCOV
86
        result.reserve(it->second.size());
×
87

88
        for (auto const * adapterInfo: it->second) {
×
89
            result.push_back(*adapterInfo);
×
90
        }
91

UNCOV
92
        return result;
×
UNCOV
93
    }
×
94

UNCOV
95
    return {};// No adapters available for this type
×
96
}
97

98
std::unique_ptr<IComputerBase> ComputerRegistry::createComputer(
237✔
99
        std::string const & computerName,
100
        DataSourceVariant const & dataSource,
101
        std::map<std::string, std::string> const & parameters) const {
102

103
    auto it = computer_factories_.find(computerName);
237✔
104
    if (it != computer_factories_.end()) {
237✔
105
        try {
106
            return it->second(dataSource, parameters);
237✔
107
        } catch (std::exception const & e) {
1✔
108
            std::cerr << "Error creating computer '" << computerName << "': " << e.what() << std::endl;
1✔
109
            return nullptr;
1✔
110
        }
1✔
111
    }
112

UNCOV
113
    std::cerr << "Computer '" << computerName << "' not found in registry." << std::endl;
×
UNCOV
114
    return nullptr;
×
115
}
116

117
std::unique_ptr<IComputerBase> ComputerRegistry::createMultiComputer(
11✔
118
        std::string const & computerName,
119
        DataSourceVariant const & dataSource,
120
        std::map<std::string, std::string> const & parameters) const {
121
    auto it = multi_computer_factories_.find(computerName);
11✔
122
    if (it != multi_computer_factories_.end()) {
11✔
123
        try {
124
            return it->second(dataSource, parameters);
11✔
125
        } catch (std::exception const & e) {
×
126
            std::cerr << "Error creating multi-computer '" << computerName << "': " << e.what() << std::endl;
×
UNCOV
127
            return nullptr;
×
128
        }
×
129
    }
UNCOV
130
    std::cerr << "Multi-computer '" << computerName << "' not found in registry." << std::endl;
×
UNCOV
131
    return nullptr;
×
132
}
133

134
DataSourceVariant ComputerRegistry::createAdapter(
1✔
135
        std::string const & adapterName,
136
        std::shared_ptr<void> const & sourceData,
137
        std::shared_ptr<TimeFrame> const & timeFrame,
138
        std::string const & name,
139
        std::map<std::string, std::string> const & parameters) const {
140

141
    auto it = adapter_factories_.find(adapterName);
1✔
142
    if (it != adapter_factories_.end()) {
1✔
143
        try {
144
            return it->second(sourceData, timeFrame, name, parameters);
1✔
145
        } catch (std::exception const & e) {
×
146
            std::cerr << "Error creating adapter '" << adapterName << "': " << e.what() << std::endl;
×
147
            return DataSourceVariant{};
×
UNCOV
148
        }
×
149
    }
150

151
    std::cerr << "Adapter '" << adapterName << "' not found in registry." << std::endl;
×
UNCOV
152
    return DataSourceVariant{};
×
153
}
154

155
ComputerInfo const * ComputerRegistry::findComputerInfo(std::string const & computerName) const {
373✔
156
    auto it = name_to_computer_.find(computerName);
373✔
157
    return (it != name_to_computer_.end()) ? it->second : nullptr;
746✔
158
}
159

160
AdapterInfo const * ComputerRegistry::findAdapterInfo(std::string const & adapterName) const {
×
161
    auto it = name_to_adapter_.find(adapterName);
×
UNCOV
162
    return (it != name_to_adapter_.end()) ? it->second : nullptr;
×
163
}
164

165
std::vector<std::string> ComputerRegistry::getAllComputerNames() const {
×
166
    std::vector<std::string> names;
×
UNCOV
167
    names.reserve(all_computers_.size());
×
168

169
    for (auto const & info: all_computers_) {
×
UNCOV
170
        names.push_back(info.name);
×
171
    }
172

173
    return names;
×
UNCOV
174
}
×
175

176
std::vector<std::string> ComputerRegistry::getAllAdapterNames() const {
1✔
177
    std::vector<std::string> names;
1✔
178
    names.reserve(all_adapters_.size());
1✔
179

180
    for (auto const & info: all_adapters_) {
4✔
181
        names.push_back(info.name);
3✔
182
    }
183

184
    return names;
1✔
UNCOV
185
}
×
186

187
std::vector<std::type_index> ComputerRegistry::getAvailableOutputTypes() const {
×
UNCOV
188
    std::set<std::type_index> unique_types;
×
189

190
    for (auto const & info: all_computers_) {
×
UNCOV
191
        unique_types.insert(info.outputType);
×
192
    }
193

194
    return std::vector<std::type_index>(unique_types.begin(), unique_types.end());
×
UNCOV
195
}
×
196

197
std::map<std::type_index, std::string> ComputerRegistry::getOutputTypeNames() const {
×
UNCOV
198
    std::map<std::type_index, std::string> type_names;
×
199

200
    for (auto const & info: all_computers_) {
×
UNCOV
201
        type_names[info.outputType] = info.outputTypeName;
×
202
    }
203

204
    return type_names;
×
UNCOV
205
}
×
206

UNCOV
207
std::vector<ComputerInfo> ComputerRegistry::getComputersByOutputType(
×
208
        std::type_index outputType,
209
        std::optional<RowSelectorType> rowSelectorType,
210
        std::optional<std::type_index> sourceType) const {
211
    std::vector<ComputerInfo> result;
×
212

213
    for (auto const & info: all_computers_) {
×
214
        if (info.outputType != outputType) {
×
215
            continue;
×
216
        }
217

218
        if (rowSelectorType && info.requiredRowSelector != *rowSelectorType) {
×
219
            continue;
×
220
        }
221

222
        if (sourceType && info.requiredSourceType != *sourceType) {
×
223
            continue;
×
224
        }
225

226
        result.push_back(info);
×
227
    }
228

229
    return result;
×
230
}
×
231

232
bool ComputerRegistry::isVectorComputer(std::string const & computerName) const {
×
233
    auto info = findComputerInfo(computerName);
×
234
    return info ? info->isVectorType : false;
×
235
}
236

237
std::type_index ComputerRegistry::getElementType(std::string const & computerName) const {
×
238
    auto info = findComputerInfo(computerName);
×
239
    return info ? info->elementType : typeid(void);
×
240
}
241

242
void ComputerRegistry::registerComputer(ComputerInfo info, ComputerFactory factory) {
5,800✔
243
    std::string const name = info.name;// Copy the name before moving
5,800✔
244

245
    if (name_to_computer_.count(name)) {
5,800✔
246
        std::cerr << "Warning: Computer '" << name << "' already registered." << std::endl;
×
247
        return;
×
248
    }
249

250
    /*
251
    std::cout << "Registering computer: " << name 
252
              << " (Row selector: " << static_cast<int>(info.requiredRowSelector)
253
              << ", Source type: " << info.requiredSourceType.name() << ")" << std::endl;
254
    */
255
    all_computers_.push_back(std::move(info));
5,800✔
256
    ComputerInfo const * infoPtr = &all_computers_.back();
5,800✔
257

258
    name_to_computer_[name] = infoPtr;
5,800✔
259
    computer_factories_[name] = std::move(factory);
5,800✔
260
}
5,800✔
261

262
void ComputerRegistry::registerAdapter(AdapterInfo info, AdapterFactory factory) {
870✔
263
    std::string const name = info.name;// Copy the name before moving
870✔
264

265
    if (name_to_adapter_.count(name)) {
870✔
266
        std::cerr << "Warning: Adapter '" << name << "' already registered." << std::endl;
×
267
        return;
×
268
    }
269

270
    /*
271
    std::cout << "Registering adapter: " << name 
272
              << " (Input type: " << info.inputType.name()
273
              << ", Output type: " << info.outputType.name() << ")" << std::endl;
274
    */
275
    all_adapters_.push_back(std::move(info));
870✔
276
    AdapterInfo const * infoPtr = &all_adapters_.back();
870✔
277

278
    name_to_adapter_[name] = infoPtr;
870✔
279
    adapter_factories_[name] = std::move(factory);
870✔
280
}
870✔
281

282
void ComputerRegistry::registerMultiComputer(ComputerInfo info, MultiComputerFactory factory) {
580✔
283
    std::string const name = info.name;
580✔
284
    if (name_to_computer_.count(name) || multi_computer_factories_.count(name)) {
580✔
285
        std::cerr << "Warning: Computer '" << name << "' already registered." << std::endl;
×
286
        return;
×
287
    }
288

289
    info.isMultiOutput = true;
580✔
290

291
    /*
292
    std::cout << "Registering multi-output computer: " << name
293
              << " (Row selector: " << static_cast<int>(info.requiredRowSelector)
294
              << ", Source type: " << info.requiredSourceType.name() << ")" << std::endl;
295
    */
296
    all_computers_.push_back(std::move(info));
580✔
297
    ComputerInfo const * infoPtr = &all_computers_.back();
580✔
298

299
    name_to_computer_[name] = infoPtr;
580✔
300
    multi_computer_factories_[name] = std::move(factory);
580✔
301
}
580✔
302

303
void ComputerRegistry::computeComputerMappings() {
290✔
304
    //std::cout << "Computing computer mappings..." << std::endl;
305
    selector_source_to_computers_.clear();
290✔
306

307
    for (auto const & info: all_computers_) {
6,670✔
308
        auto key = std::make_pair(info.requiredRowSelector, info.requiredSourceType);
6,380✔
309
        selector_source_to_computers_[key].push_back(&info);
6,380✔
310
    }
311

312
    //std::cout << "Finished computing computer mappings." << std::endl;
313
}
290✔
314

315
void ComputerRegistry::computeAdapterMappings() {
290✔
316
    //std::cout << "Computing adapter mappings..." << std::endl;
317
    input_type_to_adapters_.clear();
290✔
318

319
    for (auto const & info: all_adapters_) {
1,160✔
320
        input_type_to_adapters_[info.inputType].push_back(&info);
870✔
321
    }
322

323
    //std::cout << "Finished computing adapter mappings." << std::endl;
324
}
290✔
325

326
std::type_index ComputerRegistry::getSourceTypeIndex(DataSourceVariant const & source) const {
395✔
327
    return std::visit([](auto const & src) -> std::type_index {
1,185✔
328
        return typeid(src);
395✔
329
    },
330
                      source);
790✔
331
}
332

333
void ComputerRegistry::registerBuiltInComputers() {
290✔
334
    //std::cout << "Registering built-in computers..." << std::endl;
335

336
    // IntervalReductionComputer - Mean
337
    {
338
        ComputerInfo info("Interval Mean",
290✔
339
                          "Calculate mean value over intervals",
340
                          typeid(double),
341
                          "double",
342
                          RowSelectorType::IntervalBased,
343
                          typeid(std::shared_ptr<IAnalogSource>));
2,030✔
344

345
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
346
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
347
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
6✔
348
                auto computer = std::make_unique<IntervalReductionComputer>(*analogSrc, ReductionType::Mean);
6✔
349
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
6✔
350
            }
6✔
UNCOV
351
            return nullptr;
×
352
        };
290✔
353

354
        registerComputer(std::move(info), std::move(factory));
290✔
355
    }
290✔
356

357
    // IntervalReductionComputer - Max
358
    {
359
        ComputerInfo info("Interval Max",
290✔
360
                          "Calculate maximum value over intervals",
361
                          typeid(double),
362
                          "double",
363
                          RowSelectorType::IntervalBased,
364
                          typeid(std::shared_ptr<IAnalogSource>));
2,030✔
365

366
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
367
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
368
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
2✔
369
                auto computer = std::make_unique<IntervalReductionComputer>(*analogSrc, ReductionType::Max);
2✔
370
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
2✔
371
            }
2✔
UNCOV
372
            return nullptr;
×
373
        };
290✔
374

375
        registerComputer(std::move(info), std::move(factory));
290✔
376
    }
290✔
377

378
    // IntervalReductionComputer - Min
379
    {
380
        ComputerInfo info("Interval Min",
290✔
381
                          "Calculate minimum value over intervals",
382
                          typeid(double),
383
                          "double",
384
                          RowSelectorType::IntervalBased,
385
                          typeid(std::shared_ptr<IAnalogSource>));
2,030✔
386

387
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
388
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
389
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
1✔
390
                auto computer = std::make_unique<IntervalReductionComputer>(*analogSrc, ReductionType::Min);
1✔
391
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
1✔
392
            }
1✔
UNCOV
393
            return nullptr;
×
394
        };
290✔
395

396
        registerComputer(std::move(info), std::move(factory));
290✔
397
    }
290✔
398

399
    // IntervalReductionComputer - StdDev
400
    {
401
        ComputerInfo info("Interval Standard Deviation",
290✔
402
                          "Calculate standard deviation over intervals",
403
                          typeid(double),
404
                          "double",
405
                          RowSelectorType::IntervalBased,
406
                          typeid(std::shared_ptr<IAnalogSource>));
2,030✔
407

408
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
409
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
410
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
2✔
411
                auto computer = std::make_unique<IntervalReductionComputer>(*analogSrc, ReductionType::StdDev);
2✔
412
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
2✔
413
            }
2✔
UNCOV
414
            return nullptr;
×
415
        };
290✔
416

417
        registerComputer(std::move(info), std::move(factory));
290✔
418
    }
290✔
419

420
    // IntervalReductionComputer - Sum
421
    {
422
        ComputerInfo info("Interval Sum",
290✔
423
                          "Calculate sum of values over intervals",
424
                          typeid(double),
425
                          "double",
426
                          RowSelectorType::IntervalBased,
427
                          typeid(std::shared_ptr<IAnalogSource>));
2,030✔
428

429
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
430
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
431
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
2✔
432
                auto computer = std::make_unique<IntervalReductionComputer>(*analogSrc, ReductionType::Sum);
2✔
433
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
2✔
434
            }
2✔
UNCOV
435
            return nullptr;
×
436
        };
290✔
437

438
        registerComputer(std::move(info), std::move(factory));
290✔
439
    }
290✔
440

441
    // IntervalReductionComputer - Count
442
    {
443
        ComputerInfo info("Interval Count",
290✔
444
                          "Count number of values over intervals",
445
                          typeid(double),
446
                          "double",
447
                          RowSelectorType::IntervalBased,
448
                          typeid(std::shared_ptr<IAnalogSource>));
2,030✔
449

450
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
451
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
452
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
1✔
453
                auto computer = std::make_unique<IntervalReductionComputer>(*analogSrc, ReductionType::Count);
1✔
454
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
1✔
455
            }
1✔
UNCOV
456
            return nullptr;
×
457
        };
290✔
458

459
        registerComputer(std::move(info), std::move(factory));
290✔
460
    }
290✔
461

462
    // EventInIntervalComputer - Presence
463
    {
464
        ComputerInfo info("Event Presence",
290✔
465
                          "Check if events exist in intervals",
466
                          typeid(bool),
467
                          "bool",
468
                          RowSelectorType::IntervalBased,
469
                          typeid(std::shared_ptr<IEventSource>));
2,030✔
470

471
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
472
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
473
            if (auto eventSrc = std::get_if<std::shared_ptr<IEventSource>>(&source)) {
80✔
474
                auto computer = std::make_unique<EventInIntervalComputer<bool>>(*eventSrc, EventOperation::Presence, (*eventSrc)->getName());
80✔
475
                return std::make_unique<ComputerWrapper<bool>>(std::move(computer));
80✔
476
            }
80✔
UNCOV
477
            return nullptr;
×
478
        };
290✔
479

480
        registerComputer(std::move(info), std::move(factory));
290✔
481
    }
290✔
482

483
    // EventInIntervalComputer - Count
484
    {
485
        ComputerInfo info("Event Count",
290✔
486
                          "Count events in intervals",
487
                          typeid(int),
488
                          "int",
489
                          RowSelectorType::IntervalBased,
490
                          typeid(std::shared_ptr<IEventSource>));
2,030✔
491

492
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
493
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
494
            if (auto eventSrc = std::get_if<std::shared_ptr<IEventSource>>(&source)) {
77✔
495
                auto computer = std::make_unique<EventInIntervalComputer<int>>(*eventSrc, EventOperation::Count, (*eventSrc)->getName());
77✔
496
                return std::make_unique<ComputerWrapper<int>>(std::move(computer));
77✔
497
            }
77✔
UNCOV
498
            return nullptr;
×
499
        };
290✔
500

501
        registerComputer(std::move(info), std::move(factory));
290✔
502
    }
290✔
503

504
    // IntervalPropertyComputer - Start
505
    {
506
        ComputerInfo info("Interval Start",
290✔
507
                          "Get the start time of intervals",
508
                          typeid(double),
509
                          "double",
510
                          RowSelectorType::IntervalBased,
511
                          typeid(std::shared_ptr<IIntervalSource>));
2,030✔
512

513
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
514
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
515
            if (auto intervalSrc = std::get_if<std::shared_ptr<IIntervalSource>>(&source)) {
3✔
516
                auto computer = std::make_unique<IntervalPropertyComputer<double>>(*intervalSrc, IntervalProperty::Start, (*intervalSrc)->getName());
3✔
517
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
3✔
518
            }
3✔
UNCOV
519
            return nullptr;
×
520
        };
290✔
521

522
        registerComputer(std::move(info), std::move(factory));
290✔
523
    }
290✔
524

525
    // IntervalPropertyComputer - End
526
    {
527
        ComputerInfo info("Interval End",
290✔
528
                          "Get the end time of intervals",
529
                          typeid(double),
530
                          "double",
531
                          RowSelectorType::IntervalBased,
532
                          typeid(std::shared_ptr<IIntervalSource>));
2,030✔
533

534
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
535
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
536
            if (auto intervalSrc = std::get_if<std::shared_ptr<IIntervalSource>>(&source)) {
2✔
537
                auto computer = std::make_unique<IntervalPropertyComputer<double>>(*intervalSrc, IntervalProperty::End, (*intervalSrc)->getName());
2✔
538
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
2✔
539
            }
2✔
UNCOV
540
            return nullptr;
×
541
        };
290✔
542

543
        registerComputer(std::move(info), std::move(factory));
290✔
544
    }
290✔
545

546
    // IntervalPropertyComputer - Duration
547
    {
548
        ComputerInfo info("Interval Duration",
290✔
549
                          "Get the duration of intervals",
550
                          typeid(double),
551
                          "double",
552
                          RowSelectorType::IntervalBased,
553
                          typeid(std::shared_ptr<IIntervalSource>));
2,030✔
554

555
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
556
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
557
            if (auto intervalSrc = std::get_if<std::shared_ptr<IIntervalSource>>(&source)) {
4✔
558
                auto computer = std::make_unique<IntervalPropertyComputer<double>>(*intervalSrc, IntervalProperty::Duration, (*intervalSrc)->getName());
4✔
559
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
4✔
560
            }
4✔
UNCOV
561
            return nullptr;
×
562
        };
290✔
563

564
        registerComputer(std::move(info), std::move(factory));
290✔
565
    }
290✔
566

567
    // EventInIntervalComputer - Gather with parameter
568
    {
569
        // Create parameter descriptors
570
        std::vector<std::unique_ptr<IParameterDescriptor>> paramDescriptors;
290✔
571
        paramDescriptors.push_back(std::make_unique<EnumParameterDescriptor>(
870✔
572
                "mode", "Gathering mode for event times",
573
                std::vector<std::string>{"absolute", "centered"},
2,030✔
574
                "absolute", true));
580✔
575

576
        ComputerInfo info("Event Gather",
290✔
577
                          "Gather event times within intervals",
578
                          typeid(std::vector<float>),
579
                          "std::vector<float>",
580
                          typeid(float),
581
                          "float",
582
                          RowSelectorType::IntervalBased,
583
                          typeid(std::shared_ptr<IEventSource>),
584
                          std::move(paramDescriptors));
2,610✔
585

586
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
587
                                     std::map<std::string, std::string> const & parameters) -> std::unique_ptr<IComputerBase> {
588
            if (auto eventSrc = std::get_if<std::shared_ptr<IEventSource>>(&source)) {
7✔
589
                // Parse the mode parameter
590
                EventOperation operation = EventOperation::Gather;// default
7✔
591
                auto mode_it = parameters.find("mode");
21✔
592
                if (mode_it != parameters.end()) {
7✔
593
                    if (mode_it->second == "centered") {
5✔
594
                        operation = EventOperation::Gather_Center;
2✔
595
                    } else {
596
                        operation = EventOperation::Gather;
3✔
597
                    }
598
                }
599

600
                auto computer = std::make_unique<EventInIntervalComputer<std::vector<float>>>(
7✔
601
                        *eventSrc, operation, (*eventSrc)->getName());
7✔
602
                return std::make_unique<ComputerWrapper<std::vector<float>>>(std::move(computer));
7✔
603
            }
7✔
604
            return nullptr;
×
605
        };
290✔
606

607
        registerComputer(std::move(info), std::move(factory));
290✔
608
    }
290✔
609

610
    // TimestampValueComputer - Extract values at specific timestamps
611
    {
612
        ComputerInfo info("Timestamp Value",
290✔
613
                          "Extract analog signal values at specific timestamps",
614
                          typeid(double),
615
                          "double",
616
                          RowSelectorType::Timestamp,
617
                          typeid(std::shared_ptr<IAnalogSource>));
2,030✔
618

619
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
620
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
621
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
26✔
622
                auto computer = std::make_unique<TimestampValueComputer>(*analogSrc);
26✔
623
                return std::make_unique<ComputerWrapper<double>>(std::move(computer));
25✔
624
            }
25✔
625
            return nullptr;
×
626
        };
290✔
627

628
        registerComputer(std::move(info), std::move(factory));
290✔
629
    }
290✔
630

631
    // AnalogTimestampOffsetsMultiComputer - multi-output sampling at offsets
632
    {
633
        std::vector<std::unique_ptr<IParameterDescriptor>> paramDescriptors;
290✔
634
        // Offsets provided as comma-separated integers, e.g., "-2,-1,0,1"
635
        // Use a simple text parameter via IParameterDescriptor base replacement: reuse IntParameterDescriptor for a hint?
636
        // We'll not enforce via UI here; consumers pass string list in parameters["offsets"].
637

638
        ComputerInfo info("Analog Timestamp Offsets",
290✔
639
                          "Sample analog values at specified integer offsets from each timestamp",
640
                          typeid(double),
641
                          "double",
642
                          RowSelectorType::Timestamp,
643
                          typeid(std::shared_ptr<IAnalogSource>),
644
                          std::move(paramDescriptors));
2,030✔
645
        info.isMultiOutput = true;
290✔
646
        info.makeOutputSuffixes = [](std::map<std::string, std::string> const & parameters) {
580✔
647
            std::vector<std::string> suffixes;
×
648
            auto it = parameters.find("offsets");
×
649
            if (it == parameters.end() || it->second.empty()) {
×
650
                // default single output at t+0
651
                suffixes.emplace_back(".t+0");
×
652
                return suffixes;
×
653
            }
654
            std::string const & csv = it->second;
×
655
            size_t pos = 0;
×
656
            while (pos < csv.size()) {
×
657
                size_t next = csv.find(',', pos);
×
658
                std::string token = csv.substr(pos, next == std::string::npos ? std::string::npos : next - pos);
×
659
                // trim spaces
660
                size_t beg = token.find_first_not_of(" \t");
×
661
                size_t end = token.find_last_not_of(" \t");
×
662
                if (beg != std::string::npos) token = token.substr(beg, end - beg + 1);
×
663
                int off = 0;
×
664
                try {
665
                    off = std::stoi(token);
×
666
                } catch (...) { off = 0; }
×
667
                if (off == 0) suffixes.emplace_back(".t+0");
×
668
                else if (off > 0)
×
669
                    suffixes.emplace_back(".t+" + std::to_string(off));
×
670
                else
671
                    suffixes.emplace_back(".t" + std::to_string(off));
×
672
                if (next == std::string::npos) break;
×
UNCOV
673
                pos = next + 1;
×
UNCOV
674
            }
×
UNCOV
675
            if (suffixes.empty()) suffixes.emplace_back(".t+0");
×
UNCOV
676
            return suffixes;
×
677
        };
290✔
678

679
        MultiComputerFactory factory = [](DataSourceVariant const & source,
580✔
680
                                          std::map<std::string, std::string> const & parameters) -> std::unique_ptr<IComputerBase> {
681
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
2✔
682
                // parse offsets
683
                std::vector<int> offsets;
2✔
684
                auto it = parameters.find("offsets");
6✔
685
                if (it != parameters.end()) {
2✔
686
                    std::string const & csv = it->second;
2✔
687
                    size_t pos = 0;
2✔
688
                    while (pos < csv.size()) {
6✔
689
                        size_t next = csv.find(',', pos);
6✔
690
                        std::string token = csv.substr(pos, next == std::string::npos ? std::string::npos : next - pos);
6✔
691
                        size_t beg = token.find_first_not_of(" \t");
6✔
692
                        size_t end = token.find_last_not_of(" \t");
6✔
693
                        if (beg != std::string::npos) token = token.substr(beg, end - beg + 1);
6✔
694
                        try {
695
                            offsets.push_back(std::stoi(token));
6✔
UNCOV
696
                        } catch (...) { offsets.push_back(0); }
×
697
                        if (next == std::string::npos) break;
6✔
698
                        pos = next + 1;
4✔
699
                    }
6✔
700
                }
701
                if (offsets.empty()) offsets.push_back(0);
2✔
702
                auto comp = std::make_unique<AnalogTimestampOffsetsMultiComputer>(*analogSrc, (*analogSrc)->getName(), offsets);
2✔
703
                return std::make_unique<MultiComputerWrapper<double>>(std::move(comp));
2✔
704
            }
2✔
UNCOV
705
            return nullptr;
×
706
        };
290✔
707

708
        registerMultiComputer(std::move(info), std::move(factory));
290✔
709
    }
290✔
710

711
    // TimestampInIntervalComputer - bool for timestamps inside digital intervals
712
    {
713
        ComputerInfo info("Timestamp In Interval",
290✔
714
                          "Returns true if timestamp lies within any digital interval",
715
                          typeid(bool),
716
                          "bool",
717
                          RowSelectorType::Timestamp,
718
                          typeid(std::shared_ptr<IIntervalSource>));
2,030✔
719

720
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
721
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
722
            if (auto intervalSrc = std::get_if<std::shared_ptr<IIntervalSource>>(&source)) {
6✔
723
                auto comp = std::make_unique<TimestampInIntervalComputer>(*intervalSrc, (*intervalSrc)->getName());
6✔
724
                return std::make_unique<ComputerWrapper<bool>>(std::move(comp));
6✔
725
            }
6✔
UNCOV
726
            return nullptr;
×
727
        };
290✔
728

729
        registerComputer(std::move(info), std::move(factory));
290✔
730
    }
290✔
731

732
    // LineSamplingMultiComputer - sample x/y at equally spaced segments along line
733
    {
734
        std::vector<std::unique_ptr<IParameterDescriptor>> paramDescriptors;
290✔
735
        paramDescriptors.push_back(std::make_unique<IntParameterDescriptor>(
870✔
736
                "segments", "Number of equal segments to divide the line into (generates segments+1 sample points)", 2, 1, 1000, true));
580✔
737

738
        ComputerInfo info("Line Sample XY",
290✔
739
                          "Sample line x and y at equally spaced positions",
740
                          typeid(double),
741
                          "double",
742
                          RowSelectorType::Timestamp,
743
                          typeid(std::shared_ptr<ILineSource>),
744
                          std::move(paramDescriptors));
2,030✔
745
        info.isMultiOutput = true;
290✔
746
        info.makeOutputSuffixes = [](std::map<std::string, std::string> const & parameters) {
580✔
747
            int segments = 2;
×
748
            auto it = parameters.find("segments");
×
749
            if (it != parameters.end()) {
×
750
                segments = std::max(1, std::stoi(it->second));
×
751
            }
752
            std::vector<std::string> suffixes;
×
753
            suffixes.reserve(static_cast<size_t>((segments + 1) * 2));
×
UNCOV
754
            for (int i = 0; i <= segments; ++i) {
×
755
                double frac = static_cast<double>(i) / static_cast<double>(segments);
×
UNCOV
756
                char buf[32];
×
UNCOV
757
                std::snprintf(buf, sizeof(buf), "@%.3f", frac);
×
UNCOV
758
                suffixes.emplace_back(std::string{".x"} + buf);
×
UNCOV
759
                suffixes.emplace_back(std::string{".y"} + buf);
×
760
            }
UNCOV
761
            return suffixes;
×
762
        };
290✔
763

764
        MultiComputerFactory factory = [](DataSourceVariant const & source,
580✔
765
                                          std::map<std::string, std::string> const & parameters) -> std::unique_ptr<IComputerBase> {
766
            if (auto lineSrc = std::get_if<std::shared_ptr<ILineSource>>(&source)) {
9✔
767
                int segments = 2;
9✔
768
                auto it = parameters.find("segments");
27✔
769
                if (it != parameters.end()) {
9✔
770
                    segments = std::max(1, std::stoi(it->second));
9✔
771
                }
772
                auto comp = std::make_unique<LineSamplingMultiComputer>(*lineSrc, (*lineSrc)->getName(), (*lineSrc)->getTimeFrame(), segments);
9✔
773
                return std::make_unique<MultiComputerWrapper<double>>(std::move(comp));
9✔
774
            }
9✔
UNCOV
775
            return nullptr;
×
776
        };
290✔
777

778
        registerMultiComputer(std::move(info), std::move(factory));
290✔
779
    }
290✔
780

781
    // IntervalOverlapComputer - AssignID operation
782
    {
783
        ComputerInfo info("Interval Overlap Assign ID",
290✔
784
                          "Find the ID of the column interval that overlaps with each row interval",
785
                          typeid(int64_t),
786
                          "int64_t",
787
                          RowSelectorType::IntervalBased,
788
                          typeid(std::shared_ptr<IIntervalSource>));
2,030✔
789

790
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
791
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
792
            if (auto intervalSrc = std::get_if<std::shared_ptr<IIntervalSource>>(&source)) {
5✔
793
                auto computer = std::make_unique<IntervalOverlapComputer<int64_t>>(
5✔
794
                        *intervalSrc, IntervalOverlapOperation::AssignID, (*intervalSrc)->getName());
5✔
795
                return std::make_unique<ComputerWrapper<int64_t>>(std::move(computer));
5✔
796
            }
5✔
UNCOV
797
            return nullptr;
×
798
        };
290✔
799

800
        registerComputer(std::move(info), std::move(factory));
290✔
801
    }
290✔
802

803
    // IntervalOverlapComputer - CountOverlaps operation
804
    {
805
        ComputerInfo info("Interval Overlap Count",
290✔
806
                          "Count the number of column intervals that overlap with each row interval",
807
                          typeid(int64_t),
808
                          "int64_t",
809
                          RowSelectorType::IntervalBased,
810
                          typeid(std::shared_ptr<IIntervalSource>));
2,030✔
811

812
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
813
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
814
            if (auto intervalSrc = std::get_if<std::shared_ptr<IIntervalSource>>(&source)) {
5✔
815
                auto computer = std::make_unique<IntervalOverlapComputer<int64_t>>(
5✔
816
                        *intervalSrc, IntervalOverlapOperation::CountOverlaps, (*intervalSrc)->getName());
5✔
817
                return std::make_unique<ComputerWrapper<int64_t>>(std::move(computer));
5✔
818
            }
5✔
UNCOV
819
            return nullptr;
×
820
        };
290✔
821

822
        registerComputer(std::move(info), std::move(factory));
290✔
823
    }
290✔
824

825
    // IntervalOverlapComputer - AssignID_Start operation
826
    {
827
        ComputerInfo info("Interval Overlap Assign Start",
290✔
828
                          "Find the start index of the column interval that overlaps with each row interval",
829
                          typeid(int64_t),
830
                          "int64_t",
831
                          RowSelectorType::IntervalBased,
832
                          typeid(std::shared_ptr<IIntervalSource>));
2,030✔
833

834
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
835
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
836
            if (auto intervalSrc = std::get_if<std::shared_ptr<IIntervalSource>>(&source)) {
1✔
837
                auto computer = std::make_unique<IntervalOverlapComputer<int64_t>>(
1✔
838
                        *intervalSrc, IntervalOverlapOperation::AssignID_Start, (*intervalSrc)->getName());
1✔
839
                return std::make_unique<ComputerWrapper<int64_t>>(std::move(computer));
1✔
840
            }
1✔
UNCOV
841
            return nullptr;
×
842
        };
290✔
843

844
        registerComputer(std::move(info), std::move(factory));
290✔
845
    }
290✔
846

847
    // IntervalOverlapComputer - AssignID_End operation
848
    {
849
        ComputerInfo info("Interval Overlap Assign End",
290✔
850
                          "Find the end index of the column interval that overlaps with each row interval",
851
                          typeid(int64_t),
852
                          "int64_t",
853
                          RowSelectorType::IntervalBased,
854
                          typeid(std::shared_ptr<IIntervalSource>));
2,030✔
855

856
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
857
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
858
            if (auto intervalSrc = std::get_if<std::shared_ptr<IIntervalSource>>(&source)) {
1✔
859
                auto computer = std::make_unique<IntervalOverlapComputer<int64_t>>(
1✔
860
                        *intervalSrc, IntervalOverlapOperation::AssignID_End, (*intervalSrc)->getName());
1✔
861
                return std::make_unique<ComputerWrapper<int64_t>>(std::move(computer));
1✔
862
            }
1✔
UNCOV
863
            return nullptr;
×
864
        };
290✔
865

866
        registerComputer(std::move(info), std::move(factory));
290✔
867
    }
290✔
868

869
    // AnalogSliceGathererComputer - Gather analog data slices within intervals
870
    {
871
        ComputerInfo info("Analog Slice Gatherer",
290✔
872
                          "Gather analog data slices within intervals as vectors",
873
                          typeid(std::vector<double>),
874
                          "std::vector<double>",
875
                          typeid(double),
876
                          "double",
877
                          RowSelectorType::IntervalBased,
878
                          typeid(std::shared_ptr<IAnalogSource>));
2,610✔
879

880
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
881
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
882
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
4✔
883
                auto computer = std::make_unique<AnalogSliceGathererComputer<std::vector<double>>>(*analogSrc, (*analogSrc)->getName());
4✔
884
                return std::make_unique<ComputerWrapper<std::vector<double>>>(std::move(computer));
4✔
885
            }
4✔
UNCOV
886
            return nullptr;
×
887
        };
290✔
888

889
        registerComputer(std::move(info), std::move(factory));
290✔
890
    }
290✔
891

892
    // AnalogSliceGathererComputer - Float version
893
    {
894
        ComputerInfo info("Analog Slice Gatherer Float",
290✔
895
                          "Gather analog data slices within intervals as vectors of floats",
896
                          typeid(std::vector<float>),
897
                          "std::vector<float>",
898
                          typeid(float),
899
                          "float",
900
                          RowSelectorType::IntervalBased,
901
                          typeid(std::shared_ptr<IAnalogSource>));
2,610✔
902

903
        ComputerFactory factory = [](DataSourceVariant const & source,
580✔
904
                                     std::map<std::string, std::string> const &) -> std::unique_ptr<IComputerBase> {
905
            if (auto analogSrc = std::get_if<std::shared_ptr<IAnalogSource>>(&source)) {
2✔
906
                auto computer = std::make_unique<AnalogSliceGathererComputer<std::vector<float>>>(*analogSrc, (*analogSrc)->getName());
2✔
907
                return std::make_unique<ComputerWrapper<std::vector<float>>>(std::move(computer));
2✔
908
            }
2✔
UNCOV
909
            return nullptr;
×
910
        };
290✔
911

912
        registerComputer(std::move(info), std::move(factory));
290✔
913
    }
290✔
914

915
    //std::cout << "Finished registering built-in computers." << std::endl;
916
}
1,160✔
917

918
void ComputerRegistry::registerBuiltInAdapters() {
290✔
919
    //std::cout << "Registering built-in adapters..." << std::endl;
920

921
    // PointComponentAdapter - X Component
922
    {
923
        AdapterInfo info("Point X Component",
290✔
924
                         "Extract X component from PointData as analog source",
925
                         typeid(PointData),
926
                         typeid(std::shared_ptr<IAnalogSource>));
1,450✔
927

928
        AdapterFactory factory = [](std::shared_ptr<void> const & sourceData,
580✔
929
                                    std::shared_ptr<TimeFrame> const & timeFrame,
930
                                    std::string const & name,
931
                                    std::map<std::string, std::string> const &) -> DataSourceVariant {
932
            if (auto pointData = std::static_pointer_cast<PointData>(sourceData)) {
×
933
                auto adapter = std::make_shared<PointComponentAdapter>(
×
934
                        pointData,
935
                        PointComponentAdapter::Component::X,
×
936
                        timeFrame,
UNCOV
937
                        name + "_X");
×
UNCOV
938
                return DataSourceVariant{std::static_pointer_cast<IAnalogSource>(adapter)};
×
UNCOV
939
            }
×
UNCOV
940
            return DataSourceVariant{};
×
941
        };
290✔
942

943
        registerAdapter(std::move(info), std::move(factory));
290✔
944
    }
290✔
945

946
    // PointComponentAdapter - Y Component
947
    {
948
        AdapterInfo info("Point Y Component",
290✔
949
                         "Extract Y component from PointData as analog source",
950
                         typeid(PointData),
951
                         typeid(std::shared_ptr<IAnalogSource>));
1,450✔
952

953
        AdapterFactory factory = [](std::shared_ptr<void> const & sourceData,
580✔
954
                                    std::shared_ptr<TimeFrame> const & timeFrame,
955
                                    std::string const & name,
956
                                    std::map<std::string, std::string> const &) -> DataSourceVariant {
957
            if (auto pointData = std::static_pointer_cast<PointData>(sourceData)) {
×
958
                auto adapter = std::make_shared<PointComponentAdapter>(
×
959
                        pointData,
960
                        PointComponentAdapter::Component::Y,
×
961
                        timeFrame,
UNCOV
962
                        name + "_Y");
×
UNCOV
963
                return DataSourceVariant{std::static_pointer_cast<IAnalogSource>(adapter)};
×
UNCOV
964
            }
×
UNCOV
965
            return DataSourceVariant{};
×
966
        };
290✔
967

968
        registerAdapter(std::move(info), std::move(factory));
290✔
969
    }
290✔
970

971
    // LineDataAdapter - LineData -> ILineSource
972
    {
973
        AdapterInfo info("Line Data",
290✔
974
                         "Expose LineData as ILineSource",
975
                         typeid(LineData),
976
                         typeid(std::shared_ptr<ILineSource>));
1,450✔
977

978
        AdapterFactory factory = [](std::shared_ptr<void> const & sourceData,
580✔
979
                                    std::shared_ptr<TimeFrame> const & timeFrame,
980
                                    std::string const & name,
981
                                    std::map<std::string, std::string> const &) -> DataSourceVariant {
982
            if (auto ld = std::static_pointer_cast<LineData>(sourceData)) {
1✔
983
                auto adapter = std::make_shared<LineDataAdapter>(ld, timeFrame, name);
1✔
984
                return DataSourceVariant{std::static_pointer_cast<ILineSource>(adapter)};
1✔
985
            }
2✔
UNCOV
986
            return DataSourceVariant{};
×
987
        };
290✔
988

989
        registerAdapter(std::move(info), std::move(factory));
290✔
990
    }
290✔
991

992
    //std::cout << "Finished registering built-in adapters." << std::endl;
993
}
290✔
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