Skip to content

Commit

Permalink
Update variable names
Browse files Browse the repository at this point in the history
Variable names changed to better convey that these values represent node order - in rectangular layouts these are the same as y positions, but not for other layouts. Storing these on the <phyloNode> is consistent with other layout (position) variables.

We now have:
<phyloNode>.displayOrder
                        .displayOrderRange
                        .y: y position in domain. Depends on layout.
                        .py: y position of parent node.
                        .yTip: y position in pixels (i.e. the range)
                        .yBase: yTip of parent node.

Note that the untangling code is not currently used, but has been tested here by turning on `globals.attemptUntangle`.
  • Loading branch information
jameshadfield committed Dec 20, 2021
1 parent d8b3d2a commit 00add58
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 36 deletions.
28 changes: 14 additions & 14 deletions src/components/tree/phyloTree/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ export const createChildrenAndParentsReturnNumTips = (nodes) => {
nodes.forEach((d) => {
d.parent = d.n.parent.shell;
if (d.terminal) {
d.yRange = [d.n.yvalue, d.n.yvalue];
d.orderRange = [d.displayOrder, d.displayOrder];
d.children = null;
numTips++;
} else {
d.yRange = [d.n.children[0].yvalue, d.n.children[d.n.children.length - 1].yvalue];
d.orderRange = [d.n.children[0].shell.displayOrder, d.n.children[d.n.children.length - 1].shell.displayOrder];
d.children = [];
for (let i = 0; i < d.n.children.length; i++) {
d.children.push(d.n.children[i].shell);
Expand All @@ -75,33 +75,33 @@ export const createChildrenAndParentsReturnNumTips = (nodes) => {
return numTips;
};

/** setYValuesRecursively
/** setDisplayOrderRecursively
*/
export const setYValuesRecursively = (node, yCounter) => {
export const setDisplayOrderRecursively = (node, yCounter) => {
if (node.children) {
for (let i = node.children.length - 1; i >= 0; i--) {
yCounter = setYValuesRecursively(node.children[i], yCounter);
yCounter = setDisplayOrderRecursively(node.children[i], yCounter);
}
} else {
node.n.yvalue = ++yCounter;
node.yRange = [yCounter, yCounter];
node.displayOrder = ++yCounter;
node.displayOrderRange = [yCounter, yCounter];
return yCounter;
}
/* if here, then all children have yvalues, but we dont. */
node.n.yvalue = node.children.reduce((acc, d) => acc + d.n.yvalue, 0) / node.children.length;
node.yRange = [node.n.children[0].yvalue, node.n.children[node.n.children.length - 1].yvalue];
/* if here, then all children have displayOrders, but we dont. */
node.displayOrder = node.children.reduce((acc, d) => acc + d.displayOrder, 0) / node.children.length;
node.displayOrderRange = [node.n.children[0].shell.displayOrder, node.n.children[node.n.children.length - 1].shell.displayOrder];
return yCounter;
};

/** setYValues
* given nodes, this fn sets node.yvalue for each node
/** setDisplayOrder
* given nodes, this fn sets <phyloNode>.displayOrder for each node
* Nodes are the phyloTree nodes (i.e. node.n is the redux node)
* Nodes must have parent child links established (via createChildrenAndParents)
* PhyloTree can subsequently use this information. Accessed by prototypes
* rectangularLayout, radialLayout, createChildrenAndParents
* side effects: node.n.yvalue (i.e. in the redux node) and node.yRange (i.e. in the phyloTree node)
* side effects: <phyloNode>.displayOrder (i.e. in the redux node) and <phyloNode>.displayOrderRange
*/
export const setYValues = (nodes) => setYValuesRecursively(nodes[0], 0);
export const setDisplayOrder = (nodes) => setDisplayOrderRecursively(nodes[0], 0);


export const formatDivergence = (divergence) => {
Expand Down
14 changes: 7 additions & 7 deletions src/components/tree/phyloTree/layouts.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const setLayout = function setLayout(layout, scatterVariables) {
*/
export const rectangularLayout = function rectangularLayout() {
this.nodes.forEach((d) => {
d.y = d.n.yvalue; // precomputed y-values
d.y = d.displayOrder; // precomputed y-values
d.x = d.depth; // depth according to current distance
d.px = d.pDepth; // parent positions
d.py = d.y;
Expand Down Expand Up @@ -196,9 +196,9 @@ export const radialLayout = function radialLayout() {
const nTips = this.numberOfTips;
const offset = this.nodes[0].depth;
this.nodes.forEach((d) => {
const angleCBar1 = 2.0 * 0.95 * Math.PI * d.yRange[0] / nTips;
const angleCBar2 = 2.0 * 0.95 * Math.PI * d.yRange[1] / nTips;
d.angle = 2.0 * 0.95 * Math.PI * d.n.yvalue / nTips;
const angleCBar1 = 2.0 * 0.95 * Math.PI * d.displayOrderRange[0] / nTips;
const angleCBar2 = 2.0 * 0.95 * Math.PI * d.displayOrderRange[1] / nTips;
d.angle = 2.0 * 0.95 * Math.PI * d.displayOrder / nTips;
d.y = (d.depth - offset) * Math.cos(d.angle);
d.x = (d.depth - offset) * Math.sin(d.angle);
d.py = d.y * (d.pDepth - offset) / (d.depth - offset + 1e-15);
Expand Down Expand Up @@ -459,7 +459,7 @@ export const mapToScreen = function mapToScreen() {
} else if (this.layout==="rect") {
this.nodes.forEach((d) => {
const stem_offset = 0.5*(d.parent["stroke-width"] - d["stroke-width"]) || 0.0;
const childrenY = [this.yScale(d.yRange[0]), this.yScale(d.yRange[1])];
const childrenY = [this.yScale(d.displayOrderRange[0]), this.yScale(d.displayOrderRange[1])];
// Note that a branch cannot be perfectly horizontal and also have a (linear) gradient applied to it
// So we add a tiny amount of jitter (e.g 1/1000px) to the horizontal line (d.branch[0])
// see https://stackoverflow.com/questions/13223636/svg-gradient-for-perfectly-horizontal-path
Expand All @@ -474,8 +474,8 @@ export const mapToScreen = function mapToScreen() {
} else if (this.layout==="radial") {
const offset = this.nodes[0].depth;
const stem_offset_radial = this.nodes.map((d) => {return (0.5*(d.parent["stroke-width"] - d["stroke-width"]) || 0.0);});
this.nodes.forEach((d) => {d.cBarStart = this.yScale(d.yRange[0]);});
this.nodes.forEach((d) => {d.cBarEnd = this.yScale(d.yRange[1]);});
this.nodes.forEach((d) => {d.cBarStart = this.yScale(d.displayOrderRange[0]);});
this.nodes.forEach((d) => {d.cBarEnd = this.yScale(d.displayOrderRange[1]);});
this.nodes.forEach((d, i) => {
d.branch =[
" M "+(d.xBase-stem_offset_radial[i]*Math.sin(d.angle)).toString() +
Expand Down
4 changes: 2 additions & 2 deletions src/components/tree/phyloTree/phyloTree.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createDefaultParams } from "./defaultParams";
import { createChildrenAndParentsReturnNumTips, setYValues } from "./helpers";
import { createChildrenAndParentsReturnNumTips, setDisplayOrder } from "./helpers";
import { change, modifySVG, modifySVGInStages } from "./change";

/* PROTOTYPES */
Expand Down Expand Up @@ -36,7 +36,7 @@ const PhyloTree = function PhyloTree(reduxNodes, id, idxOfInViewRootNode) {
return phyloNode;
});
this.numberOfTips = createChildrenAndParentsReturnNumTips(this.nodes);
setYValues(this.nodes);
setDisplayOrder(this.nodes);
this.zoomNode = this.nodes[idxOfInViewRootNode];
this.strainToNode = {};
this.nodes.forEach((phylonode) => {this.strainToNode[phylonode.n.name] = phylonode;});
Expand Down
26 changes: 13 additions & 13 deletions src/components/tree/tangle/untangling.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { setYValuesRecursively, setYValues } from "../phyloTree/helpers";
import { setDisplayOrderRecursively, setDisplayOrder } from "../phyloTree/helpers";


/** calculatePearsonCorrelationCoefficient
Expand All @@ -11,10 +11,10 @@ import { setYValuesRecursively, setYValues } from "../phyloTree/helpers";
const calculatePearsonCorrelationCoefficient = (phylotree1, phylotree2) => {
let count=0, my1=0, my2=0, sqy1=0, sqy2=0, y12=0;
for (let i=0; i<phylotree2.nodes.length; i++) {
const n2=phylotree2.nodes[i].n;
if ((!n2.children) && phylotree1.strainToNode[n2.name]) {
const y1 = phylotree1.strainToNode[n2.name].n.yvalue;
const y2 = n2.yvalue;
const n2=phylotree2.nodes[i];
if ((!n2.n.children) && phylotree1.strainToNode[n2.n.name]) {
const y1 = phylotree1.strainToNode[n2.n.name].displayOrder;
const y2 = n2.displayOrder;
count++;
my1+=y1;
my2+=y2;
Expand Down Expand Up @@ -50,24 +50,24 @@ const flipChildrenPostorder = (phylotree1, phylotree2) => {
while (leftMostNode.hasChildren) {
let nodeWithSmallestY = leftMostNode.children[0];
leftMostNode.children.forEach((node) => {
if (node.yvalue < nodeWithSmallestY.yvalue) {
if (node.shell.displayOrder < nodeWithSmallestY.shell.displayOrder) {
nodeWithSmallestY = node;
}
});
leftMostNode = nodeWithSmallestY;
}
const originalStartingY = leftMostNode.yvalue - 1; // setYValuesRecursively expects the previous Y value
const originalStartingY = leftMostNode.shell.displayOrder - 1; // setDisplayOrderRecursively expects the previous Y value

/* step 2: reverse the children, recalc the y-values, and see if things improved */
phyloNode.children.reverse();
reduxNode.children.reverse();
setYValuesRecursively(phyloNode, originalStartingY);
setDisplayOrderRecursively(phyloNode, originalStartingY);
const new_corr = calculatePearsonCorrelationCoefficient(phylotree1, phylotree2);
if (correlation > new_corr) {
phyloNode.children.reverse();
reduxNode.children.reverse();
setYValuesRecursively(phyloNode, originalStartingY);
// setYValuesRecursively(phylotree2.nodes[0], 0);
setDisplayOrderRecursively(phyloNode, originalStartingY);
// setDisplayOrderRecursively(phylotree2.nodes[0], 0);
} else {
correlation = new_corr;
}
Expand All @@ -76,10 +76,10 @@ const flipChildrenPostorder = (phylotree1, phylotree2) => {
};

export const untangleTreeToo = (phylotree1, phylotree2) => {
// console.time("untangle");
console.time("untangle");
// const init_corr = calculatePearsonCorrelationCoefficient(phylotree1, phylotree2);
flipChildrenPostorder(phylotree1, phylotree2);
// console.log(`Untangling ${init_corr} -> ${calculatePearsonCorrelationCoefficient(phylotree1, phylotree2)}`);
setYValues(phylotree2.nodes);
// console.timeEnd("untangle");
setDisplayOrder(phylotree2.nodes);
console.timeEnd("untangle");
};

0 comments on commit 00add58

Please sign in to comment.