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

paulmthompson / WhiskerToolbox / 16059887550

03 Jul 2025 08:24PM UTC coverage: 74.575% (+1.6%) from 73.02%
16059887550

push

github

paulmthompson
fix zero phase error and test failures

124 of 125 new or added lines in 4 files covered. (99.2%)

108 existing lines in 3 files now uncovered.

13249 of 17766 relevant lines covered (74.58%)

1104.28 hits per line

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

0.0
/src/WhiskerToolbox/DataManager/transforms/TransformRegistry.cpp
1
#include "TransformRegistry.hpp"
2

3
#include "transforms/AnalogTimeSeries/analog_event_threshold.hpp"
4
#include "transforms/AnalogTimeSeries/analog_hilbert_phase.hpp"
5
#include "transforms/AnalogTimeSeries/analog_interval_threshold.hpp"
6
#include "transforms/AnalogTimeSeries/analog_scaling.hpp"
7
#include "transforms/AnalogTimeSeries/analog_filter.hpp"
8
#include "transforms/DigitalIntervalSeries/digital_interval_group.hpp"
9
#include "transforms/Lines/line_angle.hpp"
10
#include "transforms/Lines/line_clip.hpp"
11
#include "transforms/Lines/line_curvature.hpp"
12
#include "transforms/Lines/line_min_point_dist.hpp"
13
#include "transforms/Lines/line_point_extraction.hpp"
14
#include "transforms/Lines/line_resample.hpp"
15
#include "transforms/Lines/line_subsegment.hpp"
16
#include "transforms/Masks/mask_area.hpp"
17
#include "transforms/Masks/mask_centroid.hpp"
18
#include "transforms/Masks/mask_connected_component.hpp"
19
#include "transforms/Masks/mask_hole_filling.hpp"
20
#include "transforms/Masks/mask_median_filter.hpp"
21
#include "transforms/Masks/mask_principal_axis.hpp"
22
#include "transforms/Masks/mask_skeletonize.hpp"
23
#include "transforms/Masks/mask_to_line.hpp"
24

25
#include <iostream>// For init messages
26
#include <map>
27
#include <memory>// unique_ptr
28
#include <string>
29
#include <typeindex>
30
#include <variant>// Needed for the public interface
31
#include <vector>
32

33

UNCOV
34
TransformRegistry::TransformRegistry() {
×
35

UNCOV
36
    std::cout << "Initializing Operation Registry..." << std::endl;
×
37

38
    _registerOperation(std::make_unique<MaskAreaOperation>());
×
39
    _registerOperation(std::make_unique<MaskCentroidOperation>());
×
40
    _registerOperation(std::make_unique<MaskConnectedComponentOperation>());
×
41
    _registerOperation(std::make_unique<MaskHoleFillingOperation>());
×
42
    _registerOperation(std::make_unique<MaskMedianFilterOperation>());
×
43
    _registerOperation(std::make_unique<MaskPrincipalAxisOperation>());
×
44
    _registerOperation(std::make_unique<MaskToLineOperation>());
×
45
    _registerOperation(std::make_unique<MaskSkeletonizeOperation>());
×
46
    _registerOperation(std::make_unique<EventThresholdOperation>());
×
47
    _registerOperation(std::make_unique<IntervalThresholdOperation>());
×
48
    _registerOperation(std::make_unique<HilbertPhaseOperation>());
×
49
    _registerOperation(std::make_unique<AnalogScalingOperation>());
×
50
    _registerOperation(std::make_unique<LineAngleOperation>());
×
51
    _registerOperation(std::make_unique<LineMinPointDistOperation>());
×
52
    _registerOperation(std::make_unique<LineResampleOperation>());
×
53
    _registerOperation(std::make_unique<LineCurvatureOperation>());
×
54
    _registerOperation(std::make_unique<LineSubsegmentOperation>());
×
55
    _registerOperation(std::make_unique<LinePointExtractionOperation>());
×
56
    _registerOperation(std::make_unique<LineClipOperation>());
×
UNCOV
57
    _registerOperation(std::make_unique<GroupOperation>());
×
58
    _registerOperation(std::make_unique<AnalogFilterOperation>());
×
59

60
    _computeApplicableOperations();
×
UNCOV
61
    std::cout << "Operation Registry Initialized." << std::endl;
×
62
}
×
63

UNCOV
64
std::vector<std::string> TransformRegistry::getOperationNamesForVariant(DataTypeVariant const & dataVariant) const {
×
65
    // Get the type_index of the type currently stored in the variant.
66
    // Note: std::variant::type() returns the type_index of the *alternative*,
67
    // which in our case IS the std::shared_ptr<T>. This matches what
68
    // getTargetInputTypeIndex() should return.
UNCOV
69
    auto current_type_index = std::visit([](auto & v) -> std::type_index { return typeid(v); }, dataVariant);
×
70

71
    // Look up the type index in the pre-computed map
72
    auto it = type_index_to_op_names_.find(current_type_index);
×
UNCOV
73
    if (it != type_index_to_op_names_.end()) {
×
UNCOV
74
        return it->second;// Return the pre-computed list of names
×
75
    } else {
76
        // No registered operation targets this specific type_index.
77
        // This is normal if a data type has no operations defined for it.
UNCOV
78
        return {};// Return empty vector
×
79
    }
80
}
81

82
TransformOperation * TransformRegistry::findOperationByName(std::string const & operation_name) const {
×
83
    auto it = name_to_operation_.find(operation_name);
×
UNCOV
84
    if (it != name_to_operation_.end()) {
×
UNCOV
85
        return it->second;
×
86
    } else {
87
        // std::cerr << "Warning: Requested operation name not found: '" << operation_name << "'" << std::endl;
UNCOV
88
        return nullptr;
×
89
    }
90
}
91

92
void TransformRegistry::_registerOperation(std::unique_ptr<TransformOperation> op) {
×
93
    if (!op) return;
×
94
    std::string op_name = op->getName();
×
95
    if (name_to_operation_.count(op_name)) {
×
UNCOV
96
        std::cerr << "Warning: Operation with name '" << op_name << "' already registered." << std::endl;
×
UNCOV
97
        return;
×
98
    }
99
    std::cout << "Registering operation: " << op_name
100
              << " (Targets type index: " << op->getTargetInputTypeIndex().name() << ")"// Debug info
×
101
              << std::endl;
×
102
    name_to_operation_[op_name] = op.get();
×
UNCOV
103
    all_operations_.push_back(std::move(op));
×
104
}
×
105

106
void TransformRegistry::_computeApplicableOperations() {
×
UNCOV
107
    std::cout << "Computing applicable operations based on registered operations..." << std::endl;
×
108
    type_index_to_op_names_.clear();// Start fresh
×
109

UNCOV
110
    for (auto const & op_ptr: all_operations_) {
×
111
        if (!op_ptr) continue;
×
112
        // Get the type index this operation says it targets
113
        std::type_index target_type_index = op_ptr->getTargetInputTypeIndex();
×
114
        // Get the user-facing name of the operation
UNCOV
115
        std::string op_name = op_ptr->getName();
×
116

117
        // Add this operation's name to the list for its target type index
UNCOV
118
        type_index_to_op_names_[target_type_index].push_back(op_name);
×
119
    }
×
120

UNCOV
121
    std::cout << "Finished computing applicable operations." << std::endl;
×
122
// Debug print (optional): shows mangled names for type_index keys internally
123
#ifndef NDEBUG// Example: Only print in debug builds
124
    for (auto const & pair: type_index_to_op_names_) {
×
125
        std::cout << "  TypeIndex Hash(" << pair.first.hash_code()
×
126
                  << ", Name=" << pair.first.name() << ") supports: ";
×
UNCOV
127
        for (auto const & name: pair.second) std::cout << "'" << name << "' ";
×
UNCOV
128
        std::cout << std::endl;
×
129
    }
130
#endif
UNCOV
131
}
×
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