public static decimal DistanceNodeToFinalParent(UpgmaNode node, int recursiveLevel = 0)
        {
            if (node.ParentNodeA != null)
            {
                var r = node.DistanceParentNodeA + DistanceNodeToFinalParent(node.ParentNodeA, recursiveLevel + 1);

                if (recursiveLevel == 0)
                {
                    //Console.WriteLine(String.Join("_", node.NodeIdList) + " distance to final parent: " + r);
                }

                return(r);
            }

            if (node.ParentNodeB != null)
            {
                var r = node.DistanceParentNodeB + DistanceNodeToFinalParent(node.ParentNodeB, recursiveLevel + 1);

                if (recursiveLevel == 0)
                {
                    //Console.WriteLine(String.Join("_", node.NodeIdList) + " distance to final parent: " + r);
                }

                return(r);
            }

            if (!node.IsLeafNode())
            {
                throw new Exception("Node has no parents but is not a leaf node");
            }

            return(0);
        }
예제 #2
0
        public static List <UpgmaNode> CopyNetwork(List <UpgmaNode> network)
        {
            var networkCopy = new List <UpgmaNode>();

            for (int index = 0; index < network.Count; index++)
            {
                var node     = network[index];
                var nodeCopy = new UpgmaNode();
                nodeCopy.VectorIndexes = new List <int>(node.VectorIndexes);
                networkCopy.Add(nodeCopy);
            }

            for (int index = 0; index < network.Count; index++)
            {
                var node     = network[index];
                var nodeCopy = networkCopy[index];

                if (node.ChildNode != null)
                {
                    nodeCopy.ChildNode = networkCopy[network.IndexOf(node.ChildNode)];
                }
                if (node.ParentNodeA != null)
                {
                    nodeCopy.ParentNodeA = networkCopy[network.IndexOf(node.ParentNodeA)];
                }
                if (node.ParentNodeB != null)
                {
                    nodeCopy.ParentNodeB = networkCopy[network.IndexOf(node.ParentNodeB)];
                }
                nodeCopy.DistanceChildNode             = node.DistanceChildNode;
                nodeCopy.DistanceParentNodeA           = node.DistanceParentNodeA;
                nodeCopy.DistanceParentNodeB           = node.DistanceParentNodeB;
                nodeCopy.DistanceMatrixIterationNumber = node.DistanceMatrixIterationNumber;

                foreach (var parentNode in node.ParentList)
                {
                    UpgmaNode parentNodeCopy = null;
                    if (parentNode.Node != null)
                    {
                        parentNodeCopy = networkCopy[network.IndexOf((UpgmaNode)parentNode.Node)];
                    }

                    nodeCopy.ParentList.Add(new GenericNodeWithDistance(parentNodeCopy, parentNode.DistanceToNode));
                }

                foreach (var childNode in node.ChildrenList)
                {
                    UpgmaNode childNodeCopy = null;
                    if (childNode.Node != null)
                    {
                        childNodeCopy = networkCopy[network.IndexOf((UpgmaNode)childNode.Node)];
                    }

                    nodeCopy.ChildrenList.Add(new GenericNodeWithDistance(childNodeCopy, childNode.DistanceToNode));
                }
            }

            return(networkCopy);
        }
예제 #3
0
 public UpgmaNode(int distanceMatrixIterationNumber, UpgmaNode parentNodeA, decimal distanceParentNodeA, UpgmaNode parentNodeB, decimal distanceParentNodeB, UpgmaNode childNode, decimal distanceChildNode)
 {
     DistanceMatrixIterationNumber = distanceMatrixIterationNumber;
     ParentNodeA         = parentNodeA;
     DistanceParentNodeA = distanceParentNodeA;
     ParentNodeB         = parentNodeB;
     DistanceParentNodeB = distanceParentNodeB;
     ChildNode           = childNode;
     DistanceChildNode   = distanceChildNode;
 }
        public static void Upgma(List <List <decimal> > distanceMatrix, List <string> vectorNames, int minimumOutputTreeLeafs, out List <List <UpgmaNode> > nodeListList, out List <List <string> > treeListList, out List <string> finalTreeLeafOrderList, bool newickTreeEveryIteration = false, ProgressActionSet progressActionSet = null)
        {
            if (distanceMatrix == null || distanceMatrix.Count == 0 || distanceMatrix.Select(a => a.Count).Contains(0))
            {
                throw new ArgumentOutOfRangeException(nameof(distanceMatrix), "distance matrix is null or empty");
            }

            //var makeIterationTrees = false;

            //var distanceMatrixCache = new List<decimal[,]>();

            nodeListList = new List <List <UpgmaNode> >();
            var nodeList = new List <UpgmaNode>();

            treeListList = new List <List <string> >();

            finalTreeLeafOrderList = new List <string>();

            // store a list of every index merged to each index position in the distance matrix
            var distanceMatrixMap = new List <List <int> >();

            //var distanceMatrixMapCache = new List<List<List<int>>>();

            for (var matrixIndex = 0; matrixIndex < distanceMatrix.Count; matrixIndex++)
            {
                distanceMatrixMap.Add(new List <int>());
                distanceMatrixMap[matrixIndex].Add(matrixIndex);

                var node = new UpgmaNode();
                node.VectorIndexes.Add(matrixIndex);
                //node.IsLeafNode = true;
                node.CopyPropertiesToGenericNodeProperties();
                nodeList.Add(node);
            }


            int itemsCompleted = 0;
            int itemsTotal     = distanceMatrix.Count;

            var startTicks = DateTime.Now.Ticks;


            ProgressActionSet.StartAction(itemsTotal, progressActionSet);

            while (distanceMatrix.Count > 1 && distanceMatrix.Select(a => a.Count).Max() > 1)
            {
                // find which indexes to join
                var lowestIndexes = UpgmaLowestDistanceIndexes(distanceMatrix);
                var lowestValue   = distanceMatrix[lowestIndexes.X][lowestIndexes.Y];
                var lowerIndex    = lowestIndexes.X < lowestIndexes.Y ? lowestIndexes.X : lowestIndexes.Y;
                var higherIndex   = lowestIndexes.X > lowestIndexes.Y ? lowestIndexes.X : lowestIndexes.Y;
                var nodeDistance  = lowestValue / 2;

                if (lowerIndex == higherIndex)
                {
                    throw new Exception("lower index and higher index have the same value");
                }

                // Take parent node identities
                var parentNodeIdA = distanceMatrixMap[lowerIndex].OrderBy(o => o).ToList();
                var parentNodeIdB = distanceMatrixMap[higherIndex].OrderBy(o => o).ToList();

                var childNodeId = new List <int>();
                childNodeId.AddRange(parentNodeIdA);
                childNodeId.AddRange(parentNodeIdB);
                childNodeId = childNodeId.Distinct().ToList();

                // Find if parent nodes already exist
                var parentNodeCandidatesA = nodeList.Where(a => a.VectorIndexes.OrderBy(o => o).SequenceEqual(parentNodeIdA)).ToList();
                var parentNodeCandidatesB = nodeList.Where(a => a.VectorIndexes.OrderBy(o => o).SequenceEqual(parentNodeIdB)).ToList();

                UpgmaNode parentNodeA;
                parentNodeA = parentNodeCandidatesA[0];

                UpgmaNode parentNodeB;
                parentNodeB = parentNodeCandidatesB[0];


                var childNode = new UpgmaNode();
                nodeList.Add(childNode);

                parentNodeA.ChildNode = childNode;
                parentNodeB.ChildNode = childNode;
                childNode.ParentNodeA = parentNodeA;
                childNode.ParentNodeB = parentNodeB;

                var parentTotalDistanceA = DistanceNodeToFinalParent(parentNodeA);
                var parentTotalDistanceB = DistanceNodeToFinalParent(parentNodeB);

                parentNodeA.DistanceChildNode = nodeDistance - parentTotalDistanceA;
                parentNodeB.DistanceChildNode = nodeDistance - parentTotalDistanceB;
                childNode.DistanceParentNodeA = nodeDistance - parentTotalDistanceA;
                childNode.DistanceParentNodeB = nodeDistance - parentTotalDistanceB;

                childNode.DistanceMatrixIterationNumber = itemsCompleted;// distanceMatrixCache.Count - 1;
                childNode.VectorIndexes = childNodeId;

                parentNodeA.CopyPropertiesToGenericNodeProperties();
                parentNodeB.CopyPropertiesToGenericNodeProperties();
                childNode.CopyPropertiesToGenericNodeProperties();
                // rearrange the matrix map with the new indexes joined distanceMatrixMap[higherIndex]
                distanceMatrixMap[lowerIndex].AddRange(distanceMatrixMap[higherIndex]);
                distanceMatrixMap.RemoveAt(higherIndex);

                // recalculate distance matrix with indexes joined with mean average
                distanceMatrix = UpgmaDistanceMatrixNextIteration(distanceMatrix, lowestIndexes);

                if (newickTreeEveryIteration)
                {
                    List <string> treeLeafOrderList;
                    var           iterationTree = Newick.NewickTreeFormat(nodeList.ToList <GenericNode>(), vectorNames, out treeLeafOrderList, minimumOutputTreeLeafs);
                    treeListList.Add(iterationTree);
                    finalTreeLeafOrderList = treeLeafOrderList;
                    nodeListList.Add(UpgmaNode.CopyNetwork(nodeList));
                }

                itemsCompleted++;

                ProgressActionSet.ProgressAction(1, progressActionSet);
                ProgressActionSet.EstimatedTimeRemainingAction(startTicks, itemsCompleted, itemsTotal, progressActionSet);
            }

            if (!newickTreeEveryIteration)
            {
                List <string> treeLeafOrderList;
                var           iterationTree = Newick.NewickTreeFormat(nodeList.ToList <GenericNode>(), vectorNames, out treeLeafOrderList, minimumOutputTreeLeafs);
                treeListList.Add(iterationTree);
                finalTreeLeafOrderList = treeLeafOrderList;
                nodeListList.Add(UpgmaNode.CopyNetwork(nodeList));
            }

            ProgressActionSet.FinishAction(true, progressActionSet);
        }