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

BlueBrain / MorphIO / 5679884058

pending completion
5679884058

push

github

mgeplf
cleanup

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

1968 of 2587 relevant lines covered (76.07%)

905.27 hits per line

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

63.85
/src/mut/section.cpp
1
#include <algorithm>  // any_of
2

3
#include <morphio/errorMessages.h>
4
#include <morphio/mut/morphology.h>
5
#include <morphio/mut/section.h>
6
#include <morphio/tools.h>
7
#include <morphio/vector_types.h>
8

9
#include "../point_utils.h"
10

11
namespace morphio {
12
namespace mut {
13
using morphio::readers::ErrorMessages;
14

15
static inline bool _emptySection(const std::shared_ptr<Section>& section) {
460✔
16
    return section->points().empty();
460✔
17
}
18

19
Section::Section(Morphology* morphology,
770✔
20
                 unsigned int id,
21
                 SectionType type,
22
                 const Property::PointLevel& pointProperties)
770✔
23
    : morphology_(morphology)
24
    , point_properties_(pointProperties)
25
    , id_(id)
26
    , section_type_(type) {}
770✔
27

28
Section::Section(Morphology* morphology, unsigned int id, const morphio::Section& section)
268✔
29
    : Section(morphology,
30
              id,
31
              section.type(),
32
              Property::PointLevel(section.properties_->_pointLevel, section.range_)) {}
268✔
33

34
Section::Section(Morphology* morphology, unsigned int id, const Section& section)
×
35
    : morphology_(morphology)
36
    , point_properties_(section.point_properties_)
×
37
    , id_(id)
38
    , section_type_(section.section_type_) {}
×
39

40
void Section::throwIfNoOwningMorphology() const {
4,788✔
41
    if (!morphology_) {
4,788✔
42
        throw std::runtime_error("Section does not belong to a morphology, impossible operation");
×
43
    }
44
}
4,788✔
45

46
Morphology* Section::getOwningMorphologyOrThrow() const {
4,428✔
47
    throwIfNoOwningMorphology();
4,428✔
48
    return morphology_;
4,428✔
49
}
50

51
const std::shared_ptr<Section>& Section::parent() const {
408✔
52
    const Morphology* morphology = getOwningMorphologyOrThrow();
408✔
53
    return morphology->_sections.at(morphology->_parent.at(id()));
408✔
54
}
55

56
bool Section::isRoot() const {
1,382✔
57
    const Morphology* morphology = getOwningMorphologyOrThrow();
1,382✔
58
    const auto parentId = morphology->_parent.find(id());
1,382✔
59
    if (parentId != morphology->_parent.end()) {
1,382✔
60
        return morphology->_sections.find(parentId->second) == morphology->_sections.end();
828✔
61
    }
62
    return true;
554✔
63
}
64

65
bool Section::hasSameShape(const Section& other) const noexcept {
774✔
66
    return (other.type() == type() && other.diameters() == diameters() &&
1,546✔
67
            other.points() == points() && other.perimeters() == perimeters());
1,546✔
68
}
69

70
bool Section::isHeterogeneous(bool downstream) const {
24✔
71
    auto predicate = [&](const std::shared_ptr<Section>& s) { return type() != s->type(); };
36✔
72

73
    if (downstream) {
24✔
74
        return std::any_of(breadth_begin(), breadth_end(), predicate);
12✔
75
    }
76

77
    return std::any_of(upstream_begin(), upstream_end(), predicate);
12✔
78
}
79

80
const std::vector<std::shared_ptr<Section>>& Section::children() const {
2,178✔
81
    const Morphology* morphology = getOwningMorphologyOrThrow();
2,178✔
82

83
    const auto it = morphology->_children.find(id());
2,178✔
84
    if (it == morphology->_children.end()) {
2,178✔
85
        static std::vector<std::shared_ptr<Section>> empty;
1,470✔
86
        return empty;
1,470✔
87
    }
88
    return it->second;
708✔
89
}
90

91
depth_iterator Section::depth_begin() const {
×
92
    throwIfNoOwningMorphology();
×
93
    return depth_iterator(const_cast<Section*>(this)->shared_from_this());
×
94
}
95

96
depth_iterator Section::depth_end() const {
×
97
    throwIfNoOwningMorphology();
×
98
    return depth_iterator();
×
99
}
100

101
breadth_iterator Section::breadth_begin() const {
324✔
102
    throwIfNoOwningMorphology();
324✔
103
    return breadth_iterator(const_cast<Section*>(this)->shared_from_this());
648✔
104
}
105

106
breadth_iterator Section::breadth_end() const {
12✔
107
    throwIfNoOwningMorphology();
12✔
108
    return breadth_iterator();
12✔
109
}
110

111
upstream_iterator Section::upstream_begin() const {
12✔
112
    throwIfNoOwningMorphology();
12✔
113
    return upstream_iterator(const_cast<Section*>(this)->shared_from_this());
12✔
114
}
115

116
upstream_iterator Section::upstream_end() const {
12✔
117
    throwIfNoOwningMorphology();
12✔
118
    return upstream_iterator();
12✔
119
}
120

121
/*
122
static std::ostream& operator<<(std::ostream& os, const Section& section) {
123
    ::operator<<(os, section);
124
    return os;
125
}
126

127
std::ostream& operator<<(std::ostream& os, const std::shared_ptr<Section>& sectionPtr) {
128
    os << *sectionPtr;
129
    return os;
130
}
131
*/
132

133
std::shared_ptr<Section> Section::appendSection(std::shared_ptr<Section> original_section,
×
134
                                                bool recursive) {
135
    Morphology* morphology = getOwningMorphologyOrThrow();
×
136

137
    const std::shared_ptr<Section> ptr(
138
        new Section(morphology, morphology->_counter, *original_section));
×
139
    unsigned int parentId = id();
×
140
    uint32_t childId = morphology->_register(ptr);
×
141
    auto& _sections = morphology->_sections;
×
142

143
    bool emptySection = _emptySection(_sections[childId]);
×
144
    if (emptySection) {
×
145
        printError(Warning::APPENDING_EMPTY_SECTION,
×
146
                   morphology->_err.WARNING_APPENDING_EMPTY_SECTION(_sections[childId]));
×
147
    }
148

149
    if (!ErrorMessages::isIgnored(Warning::WRONG_DUPLICATE) && !emptySection &&
×
150
        !_checkDuplicatePoint(_sections[parentId], _sections[childId])) {
×
151
        printError(Warning::WRONG_DUPLICATE,
×
152
                   morphology->_err.WARNING_WRONG_DUPLICATE(_sections[childId],
×
153
                                                            _sections.at(parentId)));
×
154
    }
155

156
    morphology->_parent[childId] = parentId;
×
157
    morphology->_children[parentId].push_back(ptr);
×
158

159
    // Careful not to use a reference here or you will face ref invalidation problem with vector
160
    // resize The argument `original_section` of this function could be a reference to the
161
    // `_children` array and that reference might be invalidated by this `push_back` (in case
162
    // `vector` needs to reallocate the array)
163
    if (recursive) {
×
164
        for (auto child : original_section->children()) {
×
165
            ptr->appendSection(child, true);
×
166
        }
167
    }
168

169
    return ptr;
×
170
}
171

172
std::shared_ptr<Section> Section::appendSection(const morphio::Section& section, bool recursive) {
164✔
173
    Morphology* morphology = getOwningMorphologyOrThrow();
164✔
174
    const std::shared_ptr<Section> ptr(new Section(morphology, morphology->_counter, section));
164✔
175
    // const auto ptr = std::make_shared<Section>(morphology, morphology->_counter, section);
176
    unsigned int parentId = id();
164✔
177
    uint32_t childId = morphology->_register(ptr);
164✔
178
    auto& _sections = morphology->_sections;
164✔
179

180
    bool emptySection = _emptySection(_sections[childId]);
164✔
181
    if (emptySection) {
164✔
182
        printError(Warning::APPENDING_EMPTY_SECTION,
×
183
                   morphology->_err.WARNING_APPENDING_EMPTY_SECTION(_sections[childId]));
×
184
    }
185

186
    if (!ErrorMessages::isIgnored(Warning::WRONG_DUPLICATE) && !emptySection &&
328✔
187
        !_checkDuplicatePoint(_sections[parentId], _sections[childId])) {
164✔
188
        printError(Warning::WRONG_DUPLICATE,
8✔
189
                   morphology->_err.WARNING_WRONG_DUPLICATE(_sections[childId],
16✔
190
                                                            _sections.at(parentId)));
8✔
191
    }
192

193
    morphology->_parent[childId] = parentId;
164✔
194
    morphology->_children[parentId].push_back(ptr);
164✔
195

196
    if (recursive) {
164✔
197
        for (auto child : section.children()) {
176✔
198
            ptr->appendSection(child, true);
12✔
199
        }
200
    }
201

202
    return ptr;
328✔
203
}
204

205
std::shared_ptr<Section> Section::appendSection(const Property::PointLevel& pointProperties,
296✔
206
                                                SectionType sectionType) {
207
    Morphology* morphology = getOwningMorphologyOrThrow();
296✔
208
    unsigned int parentId = id();
296✔
209

210
    auto& _sections = morphology->_sections;
296✔
211
    if (sectionType == SectionType::SECTION_UNDEFINED) {
296✔
212
        sectionType = type();
×
213
    }
214

215
    if (sectionType == SECTION_SOMA) {
296✔
216
        throw morphio::SectionBuilderError("Cannot create section with type soma");
×
217
    }
218

219
    std::shared_ptr<Section> ptr(
220
        new Section(morphology, morphology->_counter, sectionType, pointProperties));
296✔
221

222
    uint32_t childId = morphology->_register(ptr);
296✔
223

224
    bool emptySection = _emptySection(_sections[childId]);
296✔
225
    if (emptySection) {
296✔
226
        printError(Warning::APPENDING_EMPTY_SECTION,
×
227
                   morphology->_err.WARNING_APPENDING_EMPTY_SECTION(_sections[childId]));
×
228
    }
229

230
    if (!ErrorMessages::isIgnored(Warning::WRONG_DUPLICATE) && !emptySection &&
592✔
231
        !_checkDuplicatePoint(_sections[parentId], _sections[childId])) {
296✔
232
        printError(Warning::WRONG_DUPLICATE,
×
233
                   morphology->_err.WARNING_WRONG_DUPLICATE(_sections[childId],
×
234
                                                            _sections[parentId]));
×
235
    }
236

237
    morphology->_parent[childId] = parentId;
296✔
238
    morphology->_children[parentId].push_back(ptr);
296✔
239
    return ptr;
592✔
240
}
241

242
}  // end namespace mut
243
}  // end namespace morphio
244

245
std::ostream& operator<<(std::ostream& os, const morphio::mut::Section& section) {
×
246
    const auto& points = section.points();
×
247
    if (points.empty()) {
×
248
        os << "Section(id=" << section.id() << ", points=[])";
×
249
    } else {
250
        os << "Section(id=" << section.id() << ", points=[(" << points[0] << "),..., ("
×
251
           << points[points.size() - 1] << ")])";
×
252
    }
253

254
    return os;
×
255
}
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