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

BlueBrain / libsonata / 5354480256

pending completion
5354480256

push

github

web-flow
Merge branch 'master' into weji/metadata

2 of 2 new or added lines in 1 file covered. (100.0%)

1789 of 1858 relevant lines covered (96.29%)

75.53 hits per line

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

95.52
/src/nodes.cpp
1
/*************************************************************************
2
 * Copyright (C) 2018-2020 Blue Brain Project
3
 *
4
 * This file is part of 'libsonata', distributed under the terms
5
 * of the GNU Lesser General Public License version 3.
6
 *
7
 * See top-level COPYING.LESSER and COPYING files for details.
8
 *************************************************************************/
9

10
#include "population.hpp"
11
#include "utils.h"
12

13
#include <algorithm>  // std::binary_search, std::max_element, std::any_of
14
#include <regex>
15

16
#include <fmt/format.h>
17

18
#include <bbp/sonata/common.h>
19
#include <bbp/sonata/nodes.h>
20

21
namespace bbp {
22
namespace sonata {
23

24
namespace {
25

26
template <typename T>
27
Selection _matchAttributeValues(const NodePopulation& population,
30✔
28
                                const std::string& name,
29
                                const std::vector<T>& wanted) {
30
    if (wanted.empty()) {
30✔
31
        return Selection({});
×
32
    } else if (wanted.size() == 1) {
30✔
33
        return population.filterAttribute<T>(name,
34
                                             [&wanted](const T& v) { return wanted[0] == v; });
196✔
35
    } else {
36
        std::vector<T> wanted_sorted(wanted);
2✔
37
        std::sort(wanted_sorted.begin(), wanted_sorted.end());
2✔
38

39
        const auto pred = [&wanted_sorted](const T& v) {
26✔
40
            return std::binary_search(wanted_sorted.cbegin(), wanted_sorted.cend(), v);
12✔
41
        };
42
        return population.filterAttribute<T>(name, pred);
2✔
43
    }
44
}
45

46
bool is_unsigned_int(const HighFive::DataType& dtype) {
32✔
47
    return dtype == HighFive::AtomicType<uint8_t>() || dtype == HighFive::AtomicType<uint16_t>() ||
64✔
48
           dtype == HighFive::AtomicType<uint32_t>() || dtype == HighFive::AtomicType<uint64_t>();
96✔
49
}
50

51
bool is_signed_int(const HighFive::DataType& dtype) {
32✔
52
    return dtype == HighFive::AtomicType<int8_t>() || dtype == HighFive::AtomicType<int16_t>() ||
64✔
53
           dtype == HighFive::AtomicType<int32_t>() || dtype == HighFive::AtomicType<int64_t>();
96✔
54
}
55
bool is_floating(const HighFive::DataType& dtype) {
2✔
56
    return dtype == HighFive::AtomicType<float>() || dtype == HighFive::AtomicType<double>();
2✔
57
}
58

59
template <typename UnaryPredicate>
60
Selection _filterStringAttribute(const NodePopulation& population,
30✔
61
                                 std::string name,
62
                                 UnaryPredicate pred) {
63
    if (population.enumerationNames().count(name) > 0) {
30✔
64
        const auto& enum_values = population.enumerationValues(name);
44✔
65
        // it's assumed that the cardinality of a @library is low
66
        // enough that a std::vector<bool> won't be too large
67
        std::vector<bool> wanted_enum_mask(enum_values.size());
44✔
68

69
        bool has_elements = false;
22✔
70
        for (size_t i = 0; i < enum_values.size(); ++i) {
88✔
71
            if (pred(enum_values[i])) {
66✔
72
                wanted_enum_mask[i] = true;
36✔
73
                has_elements = true;
36✔
74
            }
75
        }
76

77
        if (!has_elements) {
22✔
78
            return Selection({});
2✔
79
        }
80

81
        const auto& values = population.getEnumeration<size_t>(name, population.selectAll());
40✔
82
        return _getMatchingSelection(values, [&wanted_enum_mask](const size_t v) {
120✔
83
            return wanted_enum_mask.at(v);
120✔
84
        });
20✔
85
    }
86

87
    // normal, non-enum, attribute
88
    return population.filterAttribute<std::string>(name, pred);
8✔
89
}
90
}  // anonymous namespace
91

92
NodePopulation::NodePopulation(const std::string& h5FilePath,
54✔
93
                               const std::string& csvFilePath,
94
                               const std::string& name)
54✔
95
    : Population(h5FilePath, csvFilePath, name, ELEMENT) {}
54✔
96

97
Selection NodePopulation::regexMatch(const std::string& name, const std::string& regex) const {
4✔
98
    std::regex re(regex);
8✔
99
    const auto pred = [re](const std::string& v) {
18✔
100
        std::smatch match;
18✔
101
        std::regex_search(v, match, re);
18✔
102
        return !match.empty();
36✔
103
    };
4✔
104
    return _filterStringAttribute(*this, name, pred);
8✔
105
}
106

107
template <typename T>
108
Selection NodePopulation::matchAttributeValues(const std::string& attribute,
32✔
109
                                               const std::vector<T>& values) const {
110
    if (enumerationNames().count(attribute) > 0) {
32✔
111
        throw SonataError("Matching a @library enum by non-string");
×
112
    }
113

114
    auto dtype = impl_->getAttributeDataSet(attribute).getDataType();
64✔
115
    if (is_unsigned_int(dtype) || is_signed_int(dtype)) {
32✔
116
        return _matchAttributeValues<T>(*this, attribute, values);
60✔
117
    } else if (is_floating(dtype)) {
2✔
118
        throw SonataError("Exact comparison for float/double explicitly not supported");
2✔
119
    } else {
120
        throw SonataError(
121
            fmt::format("Unexpected datatype for dataset '{}'", _attributeDataType(attribute)));
×
122
    }
123
}
124

125
template <typename T>
126
Selection NodePopulation::matchAttributeValues(const std::string& attribute, const T value) const {
18✔
127
    std::vector<T> values{value};
36✔
128
    return matchAttributeValues<T>(attribute, values);
34✔
129
}
130

131
template <>
132
Selection NodePopulation::matchAttributeValues<std::string>(
26✔
133
    const std::string& attribute, const std::vector<std::string>& values) const {
134
    std::vector<std::string> values_sorted(values);
28✔
135
    std::sort(values_sorted.begin(), values_sorted.end());
26✔
136

137
    const auto pred = [&values_sorted](const std::string& v) {
168✔
138
        return std::binary_search(values_sorted.cbegin(), values_sorted.cend(), v);
84✔
139
    };
26✔
140

141
    return _filterStringAttribute(*this, attribute, pred);
52✔
142
}
143

144
template <>
145
Selection NodePopulation::matchAttributeValues<std::string>(const std::string& attribute,
8✔
146
                                                            const std::string value) const {
147
    std::vector<std::string> values{value};
32✔
148
    return matchAttributeValues<std::string>(attribute, values);
14✔
149
}
150

151

152
#define INSTANTIATE_TEMPLATE_METHODS(T)                                                            \
153
    template Selection NodePopulation::matchAttributeValues<T>(const std::string&, const T) const; \
154
    template Selection NodePopulation::matchAttributeValues<T>(const std::string&,                 \
155
                                                               const std::vector<T>&) const;
156

157
/* Note: float/double are PURPOSEFULLY not instantiated */
158

159
INSTANTIATE_TEMPLATE_METHODS(int8_t)
160
INSTANTIATE_TEMPLATE_METHODS(uint8_t)
161
INSTANTIATE_TEMPLATE_METHODS(int16_t)
162
INSTANTIATE_TEMPLATE_METHODS(uint16_t)
163
INSTANTIATE_TEMPLATE_METHODS(int32_t)
164
INSTANTIATE_TEMPLATE_METHODS(uint32_t)
165
INSTANTIATE_TEMPLATE_METHODS(int64_t)
166
INSTANTIATE_TEMPLATE_METHODS(uint64_t)
167

168
#ifdef __APPLE__
169
INSTANTIATE_TEMPLATE_METHODS(size_t)
170
#endif
171

172
#undef INSTANTIATE_TEMPLATE_METHODS
173

174
//--------------------------------------------------------------------------------------------------
175

176
constexpr const char* NodePopulation::ELEMENT;
177

178
template class PopulationStorage<NodePopulation>;
179

180
//--------------------------------------------------------------------------------------------------
181

182
}  // namespace sonata
183
}  // namespace bbp
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

© 2025 Coveralls, Inc