49 template <
typename ST,
typename IT,
typename CT>
55 const CT *connectivityList,
56 const size_t &nPoints,
58 const ST *pointSequences,
61 const IT *levels)
const;
63 template <
typename IT,
typename CT>
66 std::vector<size_t> &nodeIndices,
67 std::vector<size_t> &edgeIndices,
70 const CT *connectivityList,
71 const size_t &nPoints,
74 const IT *levels)
const;
76 template <
typename ST,
typename IT,
typename CT>
79 std::string &dotString,
82 const CT *connectivityList,
83 const ST *pointSequences,
86 const std::vector<size_t> &nodeIndices,
87 const std::vector<size_t> &edgeIndices,
88 const std::map<ST, size_t> &sequenceValueToIndexMap)
const;
90 template <
typename IT,
typename CT>
96 const CT *connectivityList,
97 const size_t &nPoints,
101 const IT &nLevels)
const;
109 const std::vector<size_t> &nodeIndices,
110 const std::string &dotString)
const;
120 std::vector<size_t> &nodeIndices,
121 std::vector<size_t> &edgeIndices,
124 const CT *connectivityList,
125 const size_t &nPoints,
126 const size_t &nEdges,
128 const IT *levels)
const {
131 if(levels ==
nullptr) {
132 nodeIndices.resize(nPoints);
133 for(
size_t i = 0; i < nPoints; i++)
136 edgeIndices.resize(nEdges);
137 for(
size_t i = 0; i < nEdges; i++)
144 for(
size_t i = 0; i < nPoints; i++)
145 if(levels[i] == level)
146 nodeIndices.push_back(i);
149 size_t const nEdges2 = nEdges * 2;
150 for(
size_t i = 0; i < nEdges2; i += 2) {
151 auto n0l = levels[connectivityList[i + 0]];
152 auto n1l = levels[connectivityList[i + 1]];
153 if(n0l == level && n0l == n1l)
154 edgeIndices.push_back(i / 2);
166 std::string &dotString,
169 const CT *connectivityList,
170 const ST *pointSequences,
173 const std::vector<size_t> &nodeIndices,
174 const std::vector<size_t> &edgeIndices,
175 const std::map<ST, size_t> &sequenceValueToIndexMap)
const {
181 bool const useSequences = pointSequences !=
nullptr;
182 bool const useSizes = sizes !=
nullptr;
183 bool const useBranches = branches !=
nullptr;
185 std::string
const headString =
"digraph g {rankdir=LR;";
186 std::string nodeString =
"";
187 std::string edgeString =
"";
188 std::string rankString =
"";
191 auto sl = [](
size_t s) {
return "\"s" + std::to_string(s) +
"\""; };
192 auto nl = [](
size_t id) {
return std::to_string(
id); };
199 nodeString +=
"node[label=\"\",shape=box,width=1,height=1];";
203 for(
auto &i : nodeIndices)
204 nodeString += nl(i) +
"[height=" + std::to_string(sizes[i]) +
"];";
211 size_t const nSequenceValues = sequenceValueToIndexMap.size();
216 for(
size_t s = 1; s < nSequenceValues; s++)
217 edgeString +=
"->" + sl(s);
218 edgeString +=
"[weight=1];";
222 std::vector<std::vector<size_t>> sequenceIndexToPointIndexMap(
224 for(
auto &i : nodeIndices)
225 sequenceIndexToPointIndexMap
226 [sequenceValueToIndexMap.find(pointSequences[i])->second]
230 for(
size_t s = 0; s < nSequenceValues; s++) {
231 rankString +=
"{rank=same " + sl(s);
233 auto &nodes = sequenceIndexToPointIndexMap[s];
235 rankString +=
" " + nl(i);
245 for(
auto &edgeIndex : edgeIndices) {
246 size_t const temp = edgeIndex * 2;
247 auto &i0 = connectivityList[temp + 0];
248 auto &i1 = connectivityList[temp + 1];
249 edgeString += nl(i0) +
"->" + nl(i1);
252 auto b0 = branches[i0];
253 auto b1 = branches[i1];
254 edgeString += b0 == b1 ?
"[weight=1]" :
"[weight=0]";
266 { dotString = headString + nodeString + edgeString + rankString +
"}"; }
284 const CT *connectivityList,
285 const size_t &nPoints,
286 const size_t &nEdges,
289 const IT &nLevels)
const {
291 if(sizes ==
nullptr || levels ==
nullptr) {
299 struct ChildrenComparator {
300 const float *layout_;
302 ChildrenComparator(
const float *layout) : layout_(layout) {
305 inline bool operator()(
const size_t &i,
const size_t &j) {
306 return layout_[i * 2 + 1] < layout_[j * 2 + 1];
310 auto comparator = ChildrenComparator(layout);
315 std::vector<std::vector<size_t>> nodeIndexChildrenIndexMap(nPoints);
317 size_t const nEdges2 = nEdges * 2;
318 for(
size_t i = 0; i < nEdges2; i += 2) {
319 auto n0 = connectivityList[i + 0];
320 auto n1 = connectivityList[i + 1];
321 if((levels[n0] + 1) == levels[n1])
322 nodeIndexChildrenIndexMap[n0].push_back(n1);
328 for(IT l = 0; l < nLevels - 1; l++) {
329 std::vector<size_t> nodeIndices;
330 std::vector<size_t> edgeIndices;
333 this->extractLevel<IT, CT>(
335 nodeIndices, edgeIndices,
338 connectivityList, nPoints, nEdges, l, levels);
341 for(
auto &parent : nodeIndices) {
342 auto &children = nodeIndexChildrenIndexMap[parent];
343 size_t const nChildren = children.size();
348 sort(children.begin(), children.end(), comparator);
351 float const sizeParent = sizes[parent];
354 float sizeChildren = 0;
355 for(
auto &child : children)
356 sizeChildren += sizes[child];
359 float const gap = sizeParent - sizeChildren;
360 float const gapDelta = (gap / (nChildren + 1)) / 2;
362 float y = layout[parent * 2 + 1] + sizeParent * 0.5 - gapDelta;
363 for(
auto &child : children) {
364 float const temp = gapDelta + sizes[child] / 2;
365 layout[child * 2 + 1] = y - temp;
385 const CT *connectivityList,
386 const size_t &nPoints,
387 const size_t &nEdges,
388 const ST *pointSequences,
391 const IT *levels)
const {
396 bool const useSequences = pointSequences !=
nullptr;
397 bool const useSizes = sizes !=
nullptr;
398 bool const useBranches = branches !=
nullptr;
399 bool const useLevels = levels !=
nullptr;
403 std::string modeS =
"";
405 modeS +=
"Sequence + ";
409 modeS +=
"Branches + ";
411 modeS +=
"Levels + ";
414 this->
printMsg({{
"#Nodes", std::to_string(nPoints)},
415 {
"#Edges", std::to_string(nEdges)},
416 {
"Mode", modeS.substr(0, modeS.length() - 3)}});
420 if(useLevels && !useSizes) {
421 this->printErr(
"'UseLevels' requires 'UseSizes'.");
426 std::map<ST, size_t> sequenceValueToIndexMap;
428 for(
size_t i = 0; i < nPoints; i++)
429 sequenceValueToIndexMap[pointSequences[i]] = 0;
431 for(
auto &el : sequenceValueToIndexMap)
438 for(
size_t i = 0; i < nPoints; i++)
439 if(nLevels < levels[i])
447 for(IT l = 0; l < nLevels; l++) {
448 std::vector<size_t> nodeIndices;
449 std::vector<size_t> edgeIndices;
453 int const status = this->extractLevel<IT, CT>(
455 nodeIndices, edgeIndices,
458 connectivityList, nPoints, nEdges, l, levels);
464 std::string dotString;
466 int const status = this->computeDotString<ST, IT, CT>(
471 connectivityList, pointSequences, sizes, branches, nodeIndices,
472 edgeIndices, sequenceValueToIndexMap);
479 int const status = this->computeDotLayout(layout, nodeIndices, dotString);
489 this->computeSlots<IT, CT>(
494 connectivityList, nPoints, nEdges, sizes, levels, nLevels);
int computeLayout(float *layout, const CT *connectivityList, const size_t &nPoints, const size_t &nEdges, const ST *pointSequences, const float *sizes, const IT *branches, const IT *levels) const
int computeDotString(std::string &dotString, const CT *connectivityList, const ST *pointSequences, const float *sizes, const IT *branches, const std::vector< size_t > &nodeIndices, const std::vector< size_t > &edgeIndices, const std::map< ST, size_t > &sequenceValueToIndexMap) const
int computeSlots(float *layout, const CT *connectivityList, const size_t &nPoints, const size_t &nEdges, const float *sizes, const IT *levels, const IT &nLevels) const
int extractLevel(std::vector< size_t > &nodeIndices, std::vector< size_t > &edgeIndices, const CT *connectivityList, const size_t &nPoints, const size_t &nEdges, const IT &level, const IT *levels) const
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)