76 std::vector<float> &retVec,
77 std::vector<LongSimplexId> &treeSimplexId,
78 std::vector<ftm::idNode> &
ttkNotUsed(branching),
79 std::vector<std::vector<ftm::idNode>> &nodeBranching) {
82 float const rootY = retVec[treeSimplexId[treeRoot] * 2 + 1];
83 float const rootOriginY = retVec[treeSimplexId[treeRootOrigin] * 2 + 1];
84 float const rootYmin = std::min(rootY, rootOriginY);
85 float const rootYmax = std::max(rootY, rootOriginY);
87 std::vector<std::tuple<float, float>> allNodeSpanX(
89 std::vector<std::tuple<float, float>> allNodeImportantSpanX(
93 float const nonImportantPairsGap
95 float const importantPairsGap
104 return not compLowerPers(a, b);
108 std::vector<ftm::idNode> leaves;
110 std::sort(leaves.begin(), leaves.end(), compLowerPers);
111 std::queue<ftm::idNode> queue;
112 for(
auto node : leaves)
114 while(!queue.empty()) {
120 retVec[treeSimplexId[nodeOrigin] * 2] = 0;
121 retVec[treeSimplexId[nodeOrigin] * 2 + 1]
122 = nodePers / rootPers * (rootYmax - rootYmin) + rootYmin;
127 std::vector<ftm::idNode> nodeBranchingVector;
128 for(
size_t i = 1; i < nodeBranching[nodeOrigin].size(); ++i)
129 nodeBranchingVector.push_back(nodeBranching[nodeOrigin][i]);
130 std::sort(nodeBranchingVector.begin(), nodeBranchingVector.end(),
134 int lastIndexImportant = -1;
135 for(
size_t i = 0; i < nodeBranchingVector.size(); ++i) {
136 ftm::idNode const nodeBranchingI = nodeBranchingVector[i];
139 float const oldMin = std::get<0>(allNodeSpanX[nodeBranchingI]);
140 float const oldMax = std::get<1>(allNodeSpanX[nodeBranchingI]);
143 float nodeSpacing = 0;
149 nodeSpacing = importantPairsGap;
157 nodeSpacing = nonImportantPairsGap;
168 float const newMin = prevX + nodeSpacing;
169 float const shiftX = newMin - oldMin;
172 dataType nodeBranchingIPers
175 float diffY = retVec[treeSimplexId[nodeBranchingI] * 2 + 1];
176 retVec[treeSimplexId[nodeBranchingI] * 2 + 1]
177 = retVec[treeSimplexId[nodeOrigin] * 2 + 1] - shiftY;
178 diffY = retVec[treeSimplexId[nodeBranchingI] * 2 + 1] - diffY;
181 std::queue<ftm::idNode> queueBranching;
182 queueBranching.emplace(nodeBranchingI);
183 while(!queueBranching.empty()) {
184 ftm::idNode const nodeBranchOrigin = queueBranching.front();
185 queueBranching.pop();
186 retVec[treeSimplexId[nodeBranchOrigin] * 2] += shiftX;
187 if(nodeBranchOrigin != nodeBranchingI)
188 retVec[treeSimplexId[nodeBranchOrigin] * 2 + 1] += diffY;
190 for(
auto nodeB : nodeBranching[nodeBranchOrigin])
191 queueBranching.emplace(nodeB);
195 allNodeSpanX[nodeBranchingI]
196 = std::make_tuple(oldMin + shiftX, oldMax + shiftX);
197 float const oldMinImp
198 = std::get<0>(allNodeImportantSpanX[nodeBranchingI]);
199 float const oldMaxImp
200 = std::get<1>(allNodeImportantSpanX[nodeBranchingI]);
201 allNodeImportantSpanX[nodeBranchingI]
202 = std::make_tuple(oldMinImp + shiftX, oldMaxImp + shiftX);
205 prevX = std::get<1>(allNodeSpanX[nodeBranchingI]);
210 lastIndexImportant = i;
211 prevX = std::get<1>(allNodeImportantSpanX[nodeBranchingI]);
212 if(i < nodeBranchingVector.size() - 1
218 = std::get<0>(allNodeSpanX[nodeBranchingVector[0]]);
220 = std::get<1>(allNodeImportantSpanX
221 [nodeBranchingVector[lastIndexImportant]]);
222 prevX = (spanMin + spanMax) / 2;
228 float spanMin = std::get<0>(allNodeSpanX[nodeBranchingVector[0]]);
229 if(lastIndexImportant != -1) {
230 float const spanMaxImp = std::get<1>(
231 allNodeImportantSpanX[nodeBranchingVector[lastIndexImportant]]);
232 allNodeImportantSpanX[nodeOrigin]
233 = std::make_tuple(spanMin, spanMaxImp);
235 allNodeImportantSpanX[nodeOrigin] = std::make_tuple(0, 0);
238 float const spanMax = std::get<1>(
239 allNodeSpanX[nodeBranchingVector[nodeBranchingVector.size() - 1]]);
240 allNodeSpanX[nodeOrigin] = std::make_tuple(spanMin, spanMax);
242 allNodeSpanX[nodeOrigin] = std::make_tuple(0, 0);
243 allNodeImportantSpanX[nodeOrigin] = std::make_tuple(0, 0);
247 float const spanMin = std::get<0>(allNodeImportantSpanX[nodeOrigin]);
248 float const spanMax = std::get<1>(allNodeImportantSpanX[nodeOrigin]);
249 retVec[treeSimplexId[nodeOrigin] * 2] = (spanMin + spanMax) / 2;
253 for(
auto node : leaves)
255 while(!queue.empty()) {
259 retVec[treeSimplexId[node] * 2] = retVec[treeSimplexId[nodeOrigin] * 2];
260 retVec[treeSimplexId[node] * 2 + 1]
261 = retVec[treeSimplexId[nodeOrigin] * 2 + 1];
269 std::tuple<double, double, double, double, double, double> oldBounds,
271 std::vector<float> &retVec) {
282 int const outNumberOfPoints = nPoints * 2;
283 retVec.resize(outNumberOfPoints);
287 std::vector<ftm::idNode> branching;
288 std::vector<int> branchingID;
289 std::vector<std::vector<ftm::idNode>> nodeBranching;
292 std::stringstream ss;
302 std::queue<ftm::idNode> queue;
305 queue.emplace(treeRoot);
306 while(!queue.empty()) {
311 treeSimplexId[node] = cptNode;
315 std::vector<ftm::idNode> children;
317 for(
size_t i = 0; i < children.size(); ++i) {
318 auto child = children[i];
319 queue.emplace(child);
323 std::stringstream ss2;
330 std::queue<ftm::idNode> queue2;
331 queue2.emplace(treeRoot);
332 while(!queue2.empty()) {
336 retVec[treeSimplexId[node] * 2]
337 = tree->
getValue<dataType>(branching[node]);
338 retVec[treeSimplexId[node] * 2 + 1] = tree->
getValue<dataType>(node);
341 std::vector<ftm::idNode> children;
343 for(
auto child : children)
344 queue2.emplace(child);
353 float x_min, y_min, x_max, y_max;
354 x_min = std::numeric_limits<float>::max();
355 y_min = std::numeric_limits<float>::max();
356 x_max = std::numeric_limits<float>::lowest();
357 y_max = std::numeric_limits<float>::lowest();
358 for(
int i = 0; i < outNumberOfPoints; i += 2) {
359 x_min = std::min(x_min, retVec[i]);
360 x_max = std::max(x_max, retVec[i]);
361 y_min = std::min(y_min, retVec[i + 1]);
362 y_max = std::max(y_max, retVec[i + 1]);
364 auto newBounds = std::make_tuple(x_min, x_max, y_min, y_max, 0, 0);
367 double diff = std::max((std::get<1>(oldBounds) - std::get<0>(oldBounds)),
368 (std::get<3>(oldBounds) - std::get<2>(oldBounds)));
369 double offset = std::max(std::get<0>(oldBounds), std::get<2>(oldBounds));
374 offset = tree->
getBirth<dataType>(treeRoot);
377 for(
int i = 0; i < outNumberOfPoints; i += 2) {
379 = std::get<1>(newBounds) - std::get<0>(newBounds);
380 divisor1 = (divisor1 == 0 ? 1 : divisor1);
382 = std::get<3>(newBounds) - std::get<2>(newBounds);
383 divisor2 = (divisor2 == 0 ? 1 : divisor2);
386 retVec[i] = (retVec[i] - std::get<0>(newBounds)) / divisor1;
387 retVec[i] = retVec[i] * diff / 2 + offset;
390 retVec[i + 1] = (retVec[i + 1] - std::get<2>(newBounds)) / divisor2;
391 retVec[i + 1] = retVec[i + 1] * diff + offset;
394 std::stringstream ss3;
402 treePlanarLayoutBDImpl<dataType>(
403 tree, retVec, treeSimplexId, branching, nodeBranching);
413 float const rootY = retVec[treeSimplexId[treeRoot] * 2 + 1];
414 float const rootOriginY = retVec[treeSimplexId[treeRootOrigin] * 2 + 1];
415 float const rootYmin = std::min(rootY, rootOriginY);
416 float const rootYmax = std::max(rootY, rootOriginY);
417 auto rootBirthDeath = tree->
getBirthDeath<dataType>(treeRoot);
418 const double rootBirth = std::get<0>(rootBirthDeath);
419 const double rootDeath = std::get<1>(rootBirthDeath);
421 retVec[treeSimplexId[i] * 2 + 1]
422 = (tree->
getValue<dataType>(i) - rootBirth) / (rootDeath - rootBirth);
423 retVec[treeSimplexId[i] * 2 + 1]
424 = retVec[treeSimplexId[i] * 2 + 1] * (rootYmax - rootYmin) + rootYmin;
427 std::stringstream ss4;
439 std::vector<ftm::idNode> leaves;
445 std::sort(leaves.begin(), leaves.end(), compLowerPers);
446 std::stack<ftm::idNode> stack;
447 for(
auto node : leaves)
450 while(!stack.empty()) {
453 nodeDone[node] =
true;
455 if(node == treeRoot or node == treeRootOrigin
464 float const nodeDiff = (retVec[treeSimplexId[node] * 2]
465 - retVec[treeSimplexId[nodeOrigin] * 2]);
466 const auto sign = nodeDiff / std::abs(nodeDiff);
467 auto inc = sign * nodePers / rootPers * (rootYmax - rootYmin) / 2;
468 retVec[treeSimplexId[node] * 2]
469 = retVec[treeSimplexId[nodeOrigin] * 2] + inc;
474 while(nodeParent != nodeOrigin) {
475 if(not nodeDone[nodeParent])
476 stack.emplace(nodeParent);
479 oldNodeParent = nodeParent;
481 if(oldNodeParent == nodeParent) {
482 std::stringstream ss5;
483 ss5 <<
"treePlanarLayoutImpl oldNodeParent == nodeParent";
495 retVec[treeSimplexId[node] * 2] = branchY;
499 std::stringstream ss5;
515 std::vector<std::tuple<float, float, float, float>> allBranchBounds(
517 std::vector<std::vector<ftm::idNode>> allBranchOrigins(
520 std::queue<ftm::idNode> queueCrossing;
524 int maxSize = std::numeric_limits<int>::lowest();
525 for(
auto leaf : leaves)
526 queueCrossing.emplace(leaf);
527 while(!queueCrossing.empty()) {
533 std::tuple<std::vector<ftm::idNode>, std::vector<ftm::idNode>>
536 allBranchOrigins[nodeOrigin] = std::get<0>(tupBranchOrigins);
537 std::vector<ftm::idNode> nonBranchOrigins
538 = std::get<1>(tupBranchOrigins);
539 allBranchOrigins[nodeOrigin].insert(allBranchOrigins[nodeOrigin].
end(),
540 nonBranchOrigins.begin(),
541 nonBranchOrigins.end());
542 std::sort(allBranchOrigins[nodeOrigin].
begin(),
543 allBranchOrigins[nodeOrigin].
end(), compValue);
544 allBranchOriginsSize[nodeOrigin] = allBranchOrigins[nodeOrigin].size();
547 for(
size_t i = 0; i < allBranchOrigins[nodeOrigin].size(); ++i) {
548 ftm::idNode const branchNodeOrigin = allBranchOrigins[nodeOrigin][i];
553 if(not isSubBranchImportant)
554 allBranchOriginsSize[nodeOrigin]
555 += allBranchOriginsSize[branchNodeOrigin];
561 maxSize = std::max(maxSize, allBranchOriginsSize[nodeOrigin]);
563 double const nonImportantPairsGap
565 double importantPairsGap = (maxSize)*nonImportantPairsGap * 1.05;
566 bool const customimportantPairsSpacing_
568 if(customimportantPairsSpacing_)
572 for(
auto leaf : leaves)
573 queueCrossing.emplace(leaf);
574 while(!queueCrossing.empty()) {
582 auto restrictedBounds
583 = std::make_tuple(retVec[treeSimplexId[node] * 2],
584 retVec[treeSimplexId[node] * 2], 0, 0);
585 for(
size_t i = 0; i < allBranchOrigins[nodeOrigin].size(); ++i) {
586 ftm::idNode const branchNodeOrigin = allBranchOrigins[nodeOrigin][i];
594 bool const toLeft = not isSubBranchImportant;
598 float const branchNodeOriginXmax
599 = std::get<1>(allBranchBounds[branchNodeOrigin]);
601 = toLeft ? std::get<0>(restrictedBounds) - branchNodeOriginXmax :
603 std::get<1>(restrictedBounds)
604 - retVec[treeSimplexId[branchNode] * 2];
605 shift += (toLeft ? -1 : 1)
606 * (isSubBranchImportant ? importantPairsGap
607 : nonImportantPairsGap);
610 allBranchOrigins[branchNodeOrigin], tree,
611 branchNodeOrigin, shift);
615 for(
size_t i = 1; i < allBranchOrigins[nodeOrigin].size(); ++i) {
616 ftm::idNode const branchNodeOrigin = allBranchOrigins[nodeOrigin][i];
619 for(
size_t j = 0; j < i; ++j) {
620 auto first = allBranchBounds[branchNodeOrigin];
622 = allBranchOrigins[nodeOrigin][j];
623 auto second = allBranchBounds[previousBranchNodeOrigin];
626 first, second, tree, previousBranchNodeOrigin, retVec,
631 int const lastIndex = nodeBranching[branchNodeOrigin].size() - 1;
634 [treeSimplexId[nodeBranching[branchNodeOrigin][lastIndex]]
637 < retVec[treeSimplexId[node] * 2]);
640 float const branchNodeOriginXmax = std::get<1>(first);
641 float const previousbranchNodeOriginXmin = std::get<0>(second);
643 float const previousbranchNodeOriginXmax = std::get<1>(second);
645 = isLeft ? previousbranchNodeOriginXmin - branchNodeOriginXmax :
647 previousbranchNodeOriginXmax
648 - retVec[treeSimplexId[branchNode] * 2];
653 shift += (isLeft ? -1 : 1)
654 * (isSubBranchImportant ? importantPairsGap
655 : nonImportantPairsGap);
661 allBranchOrigins[branchNodeOrigin], tree,
662 branchNodeOrigin, shift);
669 allBranchBounds[nodeOrigin]
681 double realImportantPairsGap = std::numeric_limits<double>::lowest();
703 realImportantPairsGap = importantPairsGap;
706 for(
auto leaf : leaves)
707 queueCrossing.emplace(leaf);
708 while(!queueCrossing.empty()) {
716 if(not isBranchImportant)
719 for(
size_t i = 0; i < allBranchOrigins[nodeOrigin].size(); ++i) {
720 ftm::idNode const branchNodeOrigin = allBranchOrigins[nodeOrigin][i];
726 if(not isSubBranchImportant) {
727 double const gap = retVec[treeSimplexId[node] * 2]
728 - std::get<0>(allBranchBounds[nodeOrigin]);
732 shift = -(importantPairsGap
733 - realImportantPairsGap);
737 allBranchOrigins[branchNodeOrigin], tree,
738 branchNodeOrigin, shift);
742 std::stringstream ss6;