樹状突起ノードクラス (同じ距離のノード郡 (山崎氏の論文(2006)ではclusterと呼ばれているもの))
예제 #1
0
        private bool ShavingNodeChecker(DendriteNode node, DendriteNode parent, int level)
        {
            if (level > 0)
            {
                if (node.NodeType == DendriteNodeType.EDGE && node != root)
                {
                    // 端点が見つかればそこからノードを削除
                    // ConnectedNodes[0]はnodeのparent??? ← その通り
                    // 基本的にはそうだが、補間によって接続されると、そうとも限らないかもしれない
                    // ChangeRootNodeしたときにうまく動いているかもしれないけど
                    ShavingRec(node.ConnectedNodes[0], node);
                    return(true);
                }
                else if (node.NodeType == DendriteNodeType.CONNECT)
                {
                    // 通過点の場合 探索続行
                    // foreachを使うと動かない (ShavingRecの中でConnectedNodesが削除されるから
                    //
                    // removeされたものが1つでもあったらi--しないといけないかも??
                    for (int i = 0; i < node.GetConnectedNodeNum(); i++)
                    {
                        var next = node.ConnectedNodes[i];
                        if (next != parent)
                        {
                            if (ShavingNodeChecker(next, node, level - 1))
                            {
                                i--;
                            }
                        }
                    }
                }
            }

            return(false);
        }
예제 #2
0
        //ノード情報から樹状突起の実際の長さと電気長などを計算
        private void SetDistanceRec(DendriteNode node, DendriteNode parent)
        {
            XMax = Math.Max(XMax, node.gx);
            XMin = Math.Min(XMin, node.gx);
            YMax = Math.Max(YMax, node.gy);
            YMin = Math.Min(YMin, node.gy);
            ZMax = Math.Max(ZMax, node.gz);
            ZMin = Math.Min(ZMin, node.gz);

            //親ノードと子ノード間のユークリッド距離
            double d = node.EuclideanDistanceTo(parent);

            node.RealDistance = parent.RealDistance + d;

            //二点のノードの平均半径
            double aveRadius = (node.Radius + parent.Radius) / 2;

            //電気的距離 R = ρ*L/(pi*r_ave^2) 定数部分は除去して R = L/r_ave^2
            node.ElectricalDistance = parent.ElectricalDistance + d / (aveRadius);

            MaxRealDistance       = Math.Max(node.RealDistance, MaxRealDistance);
            MaxElectricalDistance = Math.Max(node.ElectricalDistance, MaxElectricalDistance);

            TotalLength           += d;
            TotalElectricalLength += d / aveRadius;

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SetDistanceRec(next, node);
                }
            }
        }
예제 #3
0
        private void SetNodeTypeRec(DendriteNode node, DendriteNode parent)
        {
            //連結しているノードの数でノードのタイプを判定
            if (node.GetConnectedNodeNum() == 1) // 他の一つのクラスターにしか繋がっていないクラスターはEdgeクラスターである
            {
                node.NodeType = DendriteNodeType.EDGE;
                edge++;
            }
            else if (node.GetConnectedNodeNum() >= 3) // 他の3つのクラスターに繋がっているクラスターはBranchクラスターである
            {
                node.NodeType = DendriteNodeType.BRANCH;
                branch++;
            }
            else
            {
                node.NodeType = DendriteNodeType.CONNECT; // 他の2つのクラスターに繋がっているクラスターはEdgeクラスターでもBranchクラスターでもない
            }

            foreach (var child in node.ConnectedNodes)
            {
                if (child != parent)
                {
                    SetNodeTypeRec(child, node);
                }
            }
        }
예제 #4
0
        // whiskerlevelの長さをもつひげを除去
        private void ShavingRec(DendriteNode master, DendriteNode slave)
        {
            master.ConnectedNodes.Remove(slave);

            if (master.NodeType != DendriteNodeType.BRANCH)
            {
                // ConnectedNodes[0]はnodeのparent
                ShavingRec(master.ConnectedNodes[0], master);
            }
        }
예제 #5
0
 private void GetDendriteNodesRec(IList <DendriteNode> list, DendriteNode node, DendriteNode parent)
 {
     list.Add(node);
     foreach (var next in node.ConnectedNodes)
     {
         if (next != parent)
         {
             GetDendriteNodesRec(list, next, node);
         }
     }
 }
예제 #6
0
        //ルートノードの変更
        public void ChangeRootNode(DendriteNode node)
        {
            root = node;

            SetId();
            SetNodeType();
            SetDistance();
            SetParentNodeAsFirstElement();

            this.MaxDegree = SetDegree(root, null) + 1;
        }
예제 #7
0
 private void SetParentNodeAsFirstElementRec(DendriteNode node, DendriteNode parent)
 {
     node.ConnectedNodes.Remove(parent);
     node.ConnectedNodes.Insert(0, parent);
     foreach (var next in node.ConnectedNodes)
     {
         if (next != parent)
         {
             SetParentNodeAsFirstElementRec(next, node);
         }
     }
 }
예제 #8
0
        private void OutputVTKPointsRec(DendriteNode node, DendriteNode parent)
        {

            sbmain.AppendLine(node.gx.ToString("G7") + " " + node.gy.ToString("G7") + " " + node.gz.ToString("G7"));

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    OutputVTKPointsRec(next, node);
                }

            }
        }
예제 #9
0
        private void SetIdRec(DendriteNode node, DendriteNode parent)
        {
            //分類番号の設定
            node.Id = idsum;
            idsum++;

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SetIdRec(next, node);
                }
            }
        }
예제 #10
0
        // 呼び出す前に、SetNodeType()しておくこと
        private int SetDegree(DendriteNode node, DendriteNode parent)
        {
            // node is not root
            if (node.NodeType == DendriteNodeType.EDGE && parent != null)
            {
                node.Degree = 1;
                return(node.Degree);
            }

            IList <int> vals = new List <int>();

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    int deg = SetDegree(next, node);
                    vals.Add(deg);
                }
            }

            if (node.NodeType == DendriteNodeType.CONNECT || parent == null)
            {
                // サイズが0のswcを食わせると、ここで落ちることが判明したので
                // ad-hocな処理だけどとりあえず修復
                if (vals.Count > 0)
                {
                    node.Degree = vals[0];
                }
                else
                {
                    node.Degree = 1;
                }
                return(node.Degree);
            }
            else // NodeType = BRANCH
            {
                // このdegreeの定義はよく分からない
                int max = vals.Max();
                if (vals.Sum() == max * vals.Count)
                {
                    node.Degree = max + 1;
                }
                else
                {
                    node.Degree = max;
                }
                return(node.Degree);
            }
        }
예제 #11
0
        void TLPElectricalDistance(StreamWriter sw, DendriteNode node, DendriteNode parent)
        {
            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine("  (node {0} \"{1}\" )", node.Id, node.ElectricalDistance);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    TLPElectricalDistance(sw, next, node);
                }
            }
        }
예제 #12
0
        //平滑後の値の更新
        private static void RenewValues(DendriteNode node, DendriteNode parent)
        {
            node.gx     = node.tmpx;
            node.gy     = node.tmpy;
            node.gz     = node.tmpz;
            node.Radius = node.tmpr;

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    RenewValues(next, node);
                }
            }
        }
예제 #13
0
        private void GetEdgeAndBranchNodesRec(IList <DendriteNode> list, DendriteNode node, DendriteNode parent)
        {
            if (node.NodeType == DendriteNodeType.EDGE || node.NodeType == DendriteNodeType.BRANCH)
            {
                list.Add(node);
            }

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    GetEdgeAndBranchNodesRec(list, next, node);
                }
            }
        }
예제 #14
0
        private static void GetEdgeNodesRec(IList <DendriteNode> list, DendriteNode node, DendriteNode parent)
        {
            if (node.NodeType == DendriteNodeType.EDGE)
            {
                list.Add(node);
            }

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    GetEdgeNodesRec(list, next, node);
                }
            }
        }
예제 #15
0
        void TLPCoord(StreamWriter sw, DendriteNode node, DendriteNode parent)
        {
            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine("  (node {0} \"({1},{2},{3})\")", node.Id, node.gx, node.gy, node.gz);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    TLPCoord(sw, next, node);
                }
            }
        }
예제 #16
0
        private void SetGravityPointAndRadiusRec(DendriteNode node, DendriteNode parent)
        {
            //重心計算
            node.SetGravityPointByClusters(resox, resoz);

            //突起半径計算
            node.CalcRadius(volunit);

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SetGravityPointAndRadiusRec(next, node);
                }
            }
        }
예제 #17
0
        //径の平滑化
        private static void SmoothRadius(DendriteNode node, DendriteNode parent)
        {
            node.tmpr = node.Radius + node.ConnectedNodes.Sum(cobj => cobj.Radius);

            int count = node.GetConnectedNodeNum() + 1;

            node.tmpr /= count;

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SmoothRadius(next, node);
                }
            }
        }
예제 #18
0
        //ノード間連結性チェッカ
        private static bool NodeConnectionCheck(DendriteNode a, DendriteNode b)
        {
            foreach (Point3Di pta in a.voxels)
            {
                foreach (Point3Di ptb in b.voxels)
                {
                    int dx = ptb.X - pta.X;
                    int dy = ptb.Y - pta.Y;
                    int dz = ptb.Z - pta.Z;
                    if (Math.Abs(dx) <= 1 && Math.Abs(dy) <= 1 && Math.Abs(dz) <= 1)
                        return true;
                }
            }

            return false;
        }
예제 #19
0
        void TLPNodes(StreamWriter sw, DendriteNode node, DendriteNode parent, ref int count)
        {
            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                node.Id = count;
                sw.Write("{0} ", count++);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    TLPNodes(sw, next, node, ref count);
                }
            }
        }
예제 #20
0
        void CytNodes(StreamWriter sw, Dendrite dend, DendriteNode node, DendriteNode parent, ref int count)
        {
            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                node.Id = count;
                sw.WriteLine("{0} {1} {2} {3} {4} {5}", count++, node.RealDistance, node.ElectricalDistance, (node.gx - dend.XMin) / (dend.XMax - dend.XMin), (node.gy - dend.YMin) / (dend.YMax - dend.YMin), (node.gz - dend.ZMin) / (dend.ZMax - dend.ZMin));
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    CytNodes(sw, dend, next, node, ref count);
                }
            }
        }
예제 #21
0
        // 参考情報: SWCファイルのフォーマット
        // 1. ノードID (1オリジン)
        // 2. NodeType (0:undefined, 1:soma, 2:axon, 3:dendrite, 4:apical dendrite, 5:fork point(ブランチ), 6:end point(エッジ), 7:custom)
        // 3,4,5. x座標,y座標,z座標
        // 6. 半径
        // 7. 親ノード (1オリジン, ルートノードの親ノードは-1)
        // http://research.mssm.edu/cnic/swc.html
        private IEnumerable <Dendrite> ParseSWC(IEnumerable <string> fileContents)
        {
            // nodeId -> DendriteNode
            var nodelist = new Dictionary <int, DendriteNode>();

            var parser = new SwcParser(fileContents);

            foreach (var swcNode in parser.GetSwcNode())
            {
                DendriteNode node = new DendriteNode(swcNode);
                nodelist.Add(node.Id, node);
            }

            // 1つのSWCファイルにルートノードは1つとは限らないので配列にしてある
            List <Dendrite> dendrites = new List <Dendrite>();

            foreach (var node in nodelist.Values)
            {
                int parentNodeId = node.Distance;

                // nodeがルートノードだったとき
                if (parentNodeId == -1)
                {
                    Dendrite dend = new Dendrite(/* maxdist = */ 0, /* rx = */ 1.0, /* rz = */ 1.0);
                    dend.root = node;
                    dendrites.Add(dend);
                }
                else
                {
                    // nodeとその親ノードを連結する
                    var parentNode = nodelist[parentNodeId];

                    parentNode.ConnectedNodes.Add(node);
                    node.ConnectedNodes.Add(parentNode);
                }
            }

            // 1つのSWCファイルにルートノードは1つとは限らないので
            // それぞれについてツリー構造を生成
            foreach (Dendrite dend in dendrites)
            {
                dend.Create();
                dend.SwcHeader.InitBySwcComments(parser.Comments);
            }

            return(dendrites);
        }
예제 #22
0
        // 参考情報: SWCファイルのフォーマット
        // 1. ノードID (1オリジン)
        // 2. NodeType (0:undefined, 1:soma, 2:axon, 3:dendrite, 4:apical dendrite, 5:fork point(ブランチ), 6:end point(エッジ), 7:custom)
        // 3,4,5. x座標,y座標,z座標
        // 6. 半径
        // 7. 親ノード (1オリジン, ルートノードの親ノードは-1)
        // http://research.mssm.edu/cnic/swc.html
        private IEnumerable<Dendrite> ParseSWC(IEnumerable<string> fileContents)
        {
            // nodeId -> DendriteNode
            var nodelist = new Dictionary<int, DendriteNode>();

            var parser = new SwcParser(fileContents);

            foreach (var swcNode in parser.GetSwcNode())
            {
                DendriteNode node = new DendriteNode(swcNode);
                nodelist.Add(node.Id, node);
            }

            // 1つのSWCファイルにルートノードは1つとは限らないので配列にしてある
            List<Dendrite> dendrites = new List<Dendrite>();

            foreach (var node in nodelist.Values)
            {
                int parentNodeId = node.Distance;

                // nodeがルートノードだったとき
                if (parentNodeId == -1)
                {
                    Dendrite dend = new Dendrite(/* maxdist = */ 0, /* rx = */ 1.0, /* rz = */ 1.0);
                    dend.root = node;
                    dendrites.Add(dend);
                }
                else
                {
                    // nodeとその親ノードを連結する
                    var parentNode = nodelist[parentNodeId];

                    parentNode.ConnectedNodes.Add(node);
                    node.ConnectedNodes.Add(parentNode);
                }
            }

            // 1つのSWCファイルにルートノードは1つとは限らないので
            // それぞれについてツリー構造を生成
            foreach (Dendrite dend in dendrites)
            {
                dend.Create();
                dend.SwcHeader.InitBySwcComments(parser.Comments);
            }

            return dendrites;
        }
예제 #23
0
        void PajekVerticesRD(StreamWriter sw, Dendrite dend, DendriteNode node, DendriteNode parent, ref int count)
        {
            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                node.Id = count;
                sw.WriteLine("{0} \"{1}\" {2} {3} {4} ", count++, node.RealDistance, (node.gx - dend.XMin) / (dend.XMax - dend.XMin), (node.gy - dend.YMin) / (dend.YMax - dend.YMin), (node.gz - dend.ZMin) / (dend.ZMax - dend.ZMin));
                //sw.WriteLine("{0} {1}", count++, node.RealDistance);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    PajekVerticesRD(sw, dend, next, node, ref count);
                }
            }
        }
예제 #24
0
        private void PruningRec(DendriteNode node, DendriteNode parent, int nodeId)
        {
            if (node.Id == nodeId)
            {
                node.ConnectedNodes.Clear();
                node.AddConnectedNode(parent);
                return;
            }

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    PruningRec(next, node, nodeId);
                }
            }
        }
예제 #25
0
        //ノード間連結性チェッカ
        private static bool NodeConnectionCheck(DendriteNode a, DendriteNode b)
        {
            foreach (Point3Di pta in a.voxels)
            {
                foreach (Point3Di ptb in b.voxels)
                {
                    int dx = ptb.X - pta.X;
                    int dy = ptb.Y - pta.Y;
                    int dz = ptb.Z - pta.Z;
                    if (Math.Abs(dx) <= 1 && Math.Abs(dy) <= 1 && Math.Abs(dz) <= 1)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #26
0
        //ノード連結関係を調べて木構造を生成
        public void CreateNodeTree()
        {
            //ルートは距離値1のノード (SSDT開始点)
            root = nodelist[0][0];

            for (int z = 0; z < nodelist.Count - 1; z++)
            {
                List <DendriteNode> nodes1 = nodelist[z];
                List <DendriteNode> nodes2 = nodelist[z + 1];

                foreach (DendriteNode parent in nodes1)
                {
                    foreach (DendriteNode child in nodes2)
                    {
                        // 未連結であるか?
                        if (child.isConnected == false)
                        {
                            // clusterの連結性チェック
                            bool ischild = NodeConnectionCheck(parent, child);

                            if (ischild)
                            {
                                // 相互連結
                                parent.AddConnectedNode(child);
                                child.AddConnectedNode(parent);

                                // 既に連結済みである
                                child.isConnected = true;
                            }
                        }
                    }
                }
            }

            nodelist.Clear();

            SetGravityPointAndRadius();

            SetNodeType(); // GetEdgeNodesする前に呼ばないとバグる
            var edgenodes = GetEdgeNodes();

            // たぶん意味は無いと思うが、rootを変更しても問題になることは無いだろう的な
            ChangeRootNode(edgenodes.First());
        }
예제 #27
0
        //重心座標の平滑化
        private static void SmoothGravityLine(DendriteNode node, DendriteNode parent)
        {
            //接続ノードの重心座標の平均をとる
            node.tmpx = node.gx + node.ConnectedNodes.Sum(cobj => cobj.gx);
            node.tmpy = node.gy + node.ConnectedNodes.Sum(cobj => cobj.gy);
            node.tmpz = node.gz + node.ConnectedNodes.Sum(cobj => cobj.gz);

            int count = node.GetConnectedNodeNum() + 1;

            node.tmpx /= count;
            node.tmpy /= count;
            node.tmpz /= count;

            /*
             * else if(node.nodetype == DendriteNodeType.BRANCH)
             * {
             *  for(int i=0;i<node.GetConnectedNodeNum();i++)
             *  {
             *      if(node.cnodes[i] != parent)
             *      {
             *          double tx,ty,tz;
             *
             *          tx = parent.gx+node.gx+node.cnodes[i].gx;
             *          ty = parent.gy+node.gy+node.cnodes[i].gy;
             *          tz = parent.gz+node.gz+node.cnodes[i].gz;
             *
             *          node.gx = tx/3.0;
             *          node.gy = ty/3.0;
             *          node.gz = tz/3.0;
             *      }
             *  }
             * }
             */
            //node.CalcRadius0(resox,resoz);
            //node.CalcRadius(this.volunit);

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SmoothGravityLine(next, node);
                }
            }
        }
예제 #28
0
        void TLPEdgeLength(StreamWriter sw, DendriteNode node, DendriteNode parent, DendriteNode pnode, ref int count)
        {
            if (parent != null && node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine(" (edge {0} \"{1}\")", count++, node.RealDistance - pnode.RealDistance);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    if (node.NodeType != DendriteNodeType.CONNECT)
                    {
                        TLPEdgeLength(sw, next, node, node, ref count);
                    }
                    else
                    {
                        TLPEdgeLength(sw, next, node, pnode, ref count);
                    }
                }
            }
        }
예제 #29
0
        void PajekEdgesRD(StreamWriter sw, DendriteNode node, DendriteNode parent, DendriteNode pnode)
        {
            if (pnode != null && node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine("{0} {1} {2}", pnode.Id, node.Id, node.RealDistance - pnode.RealDistance);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    if (node.NodeType == DendriteNodeType.CONNECT)
                    {
                        PajekEdgesRD(sw, next, node, pnode);
                    }
                    else
                    {
                        PajekEdgesRD(sw, next, node, node);
                    }
                }
            }
        }
예제 #30
0
        void CytEdges(StreamWriter sw, Dendrite dend, DendriteNode node, DendriteNode parent, DendriteNode pnode)
        {
            if (pnode != null && node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine("{0} {1} {2} {3}", pnode.Id, node.Id, (node.RealDistance - pnode.RealDistance), (node.ElectricalDistance - pnode.ElectricalDistance));
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    if (node.NodeType == DendriteNodeType.CONNECT)
                    {
                        CytEdges(sw, dend, next, node, pnode);
                    }
                    else
                    {
                        CytEdges(sw, dend, next, node, node);
                    }
                }
            }
        }
예제 #31
0
        void TLPEdge(StreamWriter sw, DendriteNode node, DendriteNode parent, DendriteNode pnode, ref int count)
        {
            if (parent != null && node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine(" (edge {0} {1} {2})", count++, pnode.Id, node.Id);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    if (node.NodeType != DendriteNodeType.CONNECT)
                    {
                        TLPEdge(sw, next, node, node, ref count);
                    }
                    else
                    {
                        TLPEdge(sw, next, node, pnode, ref count);
                    }
                }
            }
        }
예제 #32
0
        void SaveToSWCRec(DendriteNode node, DendriteNode parent, StreamWriter writer)
        {
            int type;

            switch (node.NodeType)
            {
            case DendriteNodeType.EDGE:
                type = 6;
                break;

            case DendriteNodeType.BRANCH:
                type = 5;
                break;

            case DendriteNodeType.CONNECT:
                type = 3;
                break;

            default:
                type = 0;
                break;
            }

            int parentId = (parent == null ? -1 : parent.Id + 1);

            writer.WriteLine("{0} {1} {2} {3} {4} {5} {6}",
                             node.Id + 1, type,
                             node.gx, node.gy, node.gz,
                             node.Radius.ToString("G7"),
                             parentId);

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SaveToSWCRec(next, node, writer);
                }
            }
        }
예제 #33
0
        void CytNodes(StreamWriter sw, Dendrite dend, DendriteNode node, DendriteNode parent, ref int count)
        {
            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                node.Id = count;
                sw.WriteLine("{0} {1} {2} {3} {4} {5}", count++, node.RealDistance, node.ElectricalDistance, (node.gx - dend.XMin) / (dend.XMax - dend.XMin), (node.gy - dend.YMin) / (dend.YMax - dend.YMin), (node.gz - dend.ZMin) / (dend.ZMax - dend.ZMin));


            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    CytNodes(sw, dend, next, node, ref count);
                }
            }

        }
예제 #34
0
        void Edge(DendriteNode node, DendriteNode root, int deg, StringBuilder sb)
        {
            if (node.Degree == deg && !flag)
            {
                flag = true;
                if (root != null && root.NodeType == DendriteNodeType.BRANCH) edgec.Add(root);
            }

            if (flag) edgec.Add(node);

            if (node.NodeType == DendriteNodeType.EDGE && root != null && flag)
            {
                double aver = 0;
                double length = 0;
                double elength = 0;

                // calc average radius
                edgec.ForEach(item => aver += item.Radius);
                aver /= edgec.Count;

                // calc edge length
                length = edgec[edgec.Count - 1].RealDistance - edgec[0].RealDistance;
                elength = edgec[edgec.Count - 1].ElectricalDistance - edgec[0].ElectricalDistance;


                sb.AppendFormat("{0},{1},{2},", aver, length, elength);
                edgec.ForEach(item => sb.AppendFormat("{0},", item.Id + 1));
                sb.Remove(sb.Length - 1, 1);
                sb.AppendLine();

                edgec.Clear();
                count[deg - 1]++;

                flag = false;
                return;
            }


            bool end = true;
            DendriteNode tmp;
            if (node.NodeType == DendriteNodeType.BRANCH && flag)
            {
                for (int i = 0; i < node.ConnectedNodes.Count; i++)
                {
                    if (node.ConnectedNodes[i] != root)
                    {
                        if (node.ConnectedNodes[i].Degree == deg)
                        {
                            end = false;
                            if (i == 0) continue;
                            tmp = node.ConnectedNodes[0];
                            node.ConnectedNodes[0] = node.ConnectedNodes[i];
                            node.ConnectedNodes[i] = tmp;
                        }
                    }
                }

                if (end)
                {
                    double aver = 0;
                    double length = 0;
                    double elength = 0;

                    // calc average radius
                    edgec.ForEach(item => aver += item.Radius);
                    aver /= edgec.Count;

                    // calc edge length
                    length = edgec[edgec.Count - 1].RealDistance - edgec[0].RealDistance;
                    elength = edgec[edgec.Count - 1].ElectricalDistance - edgec[0].ElectricalDistance;

                    sb.AppendFormat("{0},{1},{2},", aver, length, elength);
                    edgec.ForEach(item => sb.AppendFormat("{0},", item.Id + 1));
                    sb.Remove(sb.Length - 1, 1);
                    sb.AppendLine();

                    edgec.Clear();
                    count[deg - 1]++;
                    flag = false;
                }
            }
            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != root)
                {
                    Edge(next, node, deg, sb);
                }
            }


        }
예제 #35
0
        // 呼び出す前に、SetNodeType()しておくこと
        private int SetDegree(DendriteNode node, DendriteNode parent)
        {
            // node is not root
            if (node.NodeType == DendriteNodeType.EDGE && parent != null)
            {
                node.Degree = 1;
                return node.Degree;
            }

            IList<int> vals = new List<int>();
            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    int deg = SetDegree(next, node);
                    vals.Add(deg);
                }
            }

            if (node.NodeType == DendriteNodeType.CONNECT || parent == null)
            {
                // サイズが0のswcを食わせると、ここで落ちることが判明したので
                // ad-hocな処理だけどとりあえず修復
                if (vals.Count > 0)
                {
                    node.Degree = vals[0];
                }
                else
                {
                    node.Degree = 1;
                }
                return node.Degree;
            }
            else // NodeType = BRANCH
            {
                // このdegreeの定義はよく分からない
                int max = vals.Max();
                if (vals.Sum() == max * vals.Count) node.Degree = max + 1;
                else node.Degree = max;
                return node.Degree;
            }
        }
예제 #36
0
        //重心座標の平滑化
        private static void SmoothGravityLine(DendriteNode node, DendriteNode parent)
        {
            //接続ノードの重心座標の平均をとる
            node.tmpx = node.gx + node.ConnectedNodes.Sum(cobj => cobj.gx);
            node.tmpy = node.gy + node.ConnectedNodes.Sum(cobj => cobj.gy);
            node.tmpz = node.gz + node.ConnectedNodes.Sum(cobj => cobj.gz);

            int count = node.GetConnectedNodeNum() + 1;

            node.tmpx /= count;
            node.tmpy /= count;
            node.tmpz /= count;

            /*
            else if(node.nodetype == DendriteNodeType.BRANCH)
            {
                for(int i=0;i<node.GetConnectedNodeNum();i++)
                {
                    if(node.cnodes[i] != parent)
                    {
                        double tx,ty,tz;

                        tx = parent.gx+node.gx+node.cnodes[i].gx;
                        ty = parent.gy+node.gy+node.cnodes[i].gy;
                        tz = parent.gz+node.gz+node.cnodes[i].gz;

                        node.gx = tx/3.0;
                        node.gy = ty/3.0;
                        node.gz = tz/3.0;
                    }
                }
            }
            */
            //node.CalcRadius0(resox,resoz);
            //node.CalcRadius(this.volunit);

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SmoothGravityLine(next, node);
                }
            }
        }
예제 #37
0
        void TLPNodes(StreamWriter sw, DendriteNode node, DendriteNode parent, ref int count)
        {

            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                node.Id = count;
                sw.Write("{0} ", count++);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent) TLPNodes(sw, next, node, ref count);
            }
        }
예제 #38
0
        void TLPCoord(StreamWriter sw, DendriteNode node, DendriteNode parent)
        {
            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine("  (node {0} \"({1},{2},{3})\")", node.Id, node.gx, node.gy, node.gz);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent) TLPCoord(sw, next, node);
            }
        }
예제 #39
0
        void TLPNodeType(StreamWriter sw, DendriteNode node, DendriteNode parent)
        {

            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine("  (node {0} \"{1}\" )", node.Id, (int)node.NodeType);
            }


            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent) TLPNodeType(sw, next, node);
            }
        }
예제 #40
0
        void TLPEdge(StreamWriter sw, DendriteNode node, DendriteNode parent, DendriteNode pnode, ref int count)
        {
            if (parent != null && node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine(" (edge {0} {1} {2})", count++, pnode.Id, node.Id);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    if (node.NodeType != DendriteNodeType.CONNECT) TLPEdge(sw, next, node, node, ref count);
                    else TLPEdge(sw, next, node, pnode, ref count);
                }
            }
        }
예제 #41
0
        void TLPEdgeLength(StreamWriter sw, DendriteNode node, DendriteNode parent, DendriteNode pnode, ref int count)
        {
            if (parent != null && node.NodeType != DendriteNodeType.CONNECT)
            {
                sw.WriteLine(" (edge {0} \"{1}\")", count++, node.RealDistance - pnode.RealDistance);
            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    if (node.NodeType != DendriteNodeType.CONNECT) TLPEdgeLength(sw, next, node, node, ref count);
                    else TLPEdgeLength(sw, next, node, pnode, ref count);
                }
            }
        }
예제 #42
0
        void PajekVerticesRD(StreamWriter sw, Dendrite dend, DendriteNode node, DendriteNode parent, ref int count)
        {
            if (node.NodeType != DendriteNodeType.CONNECT)
            {
                node.Id = count;
                sw.WriteLine("{0} \"{1}\" {2} {3} {4} ", count++, node.RealDistance, (node.gx - dend.XMin) / (dend.XMax - dend.XMin), (node.gy - dend.YMin) / (dend.YMax - dend.YMin), (node.gz - dend.ZMin) / (dend.ZMax - dend.ZMin));
                //sw.WriteLine("{0} {1}", count++, node.RealDistance);

            }

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    PajekVerticesRD(sw, dend, next, node, ref count);
                }
            }

        }
예제 #43
0
 private void SetParentNodeAsFirstElementRec(DendriteNode node, DendriteNode parent) {
     node.ConnectedNodes.Remove(parent);
     node.ConnectedNodes.Insert(0, parent);
     foreach (var next in node.ConnectedNodes)
     {
         if (next != parent)
         {
             SetParentNodeAsFirstElementRec(next, node);
         }
     }
 }
예제 #44
0
        //平滑後の値の更新
        private static void RenewValues(DendriteNode node, DendriteNode parent)
        {
            node.gx = node.tmpx;
            node.gy = node.tmpy;
            node.gz = node.tmpz;
            node.Radius = node.tmpr;

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    RenewValues(next, node);
                }
            }
        }
예제 #45
0
        //径の平滑化
        private static void SmoothRadius(DendriteNode node, DendriteNode parent)
        {
            node.tmpr = node.Radius + node.ConnectedNodes.Sum(cobj => cobj.Radius);

            int count = node.GetConnectedNodeNum() + 1;
            node.tmpr /= count;

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SmoothRadius(next, node);
                }
            }
        }
예제 #46
0
        void SaveToSWCRec(DendriteNode node, DendriteNode parent, StreamWriter writer)
        {
            int type;

            switch (node.NodeType)
            {
                case DendriteNodeType.EDGE:
                    type = 6;
                    break;

                case DendriteNodeType.BRANCH:
                    type = 5;
                    break;

                case DendriteNodeType.CONNECT:
                    type = 3;
                    break;

                default:
                    type = 0;
                    break;
            }

            int parentId = (parent == null ? -1 : parent.Id + 1);

            writer.WriteLine("{0} {1} {2} {3} {4} {5} {6}",
                node.Id + 1, type,
                node.gx, node.gy, node.gz,
                node.Radius.ToString("G7"),
                parentId);

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent) SaveToSWCRec(next, node, writer);
            }
        }
예제 #47
0
        // whiskerlevelの長さをもつひげを除去
        private void ShavingRec(DendriteNode master, DendriteNode slave)
        {
            master.ConnectedNodes.Remove(slave);

            if (master.NodeType != DendriteNodeType.BRANCH)
            {
                // ConnectedNodes[0]はnodeのparent
                ShavingRec(master.ConnectedNodes[0], master);
            }
        }
예제 #48
0
        //ノード連結関係を調べて木構造を生成
        public void CreateNodeTree()
        {
            //ルートは距離値1のノード (SSDT開始点)
            root = nodelist[0][0];

            for (int z = 0; z < nodelist.Count - 1; z++)
            {
                List<DendriteNode> nodes1 = nodelist[z];
                List<DendriteNode> nodes2 = nodelist[z + 1];

                foreach (DendriteNode parent in nodes1)
                {
                    foreach (DendriteNode child in nodes2)
                    {
                        // 未連結であるか?
                        if (child.isConnected == false)
                        {
                            // clusterの連結性チェック
                            bool ischild = NodeConnectionCheck(parent, child);

                            if (ischild)
                            {
                                // 相互連結
                                parent.AddConnectedNode(child);
                                child.AddConnectedNode(parent);

                                // 既に連結済みである
                                child.isConnected = true;
                            }
                        }
                    }
                }
            }

            nodelist.Clear();

            SetGravityPointAndRadius();

            SetNodeType(); // GetEdgeNodesする前に呼ばないとバグる
            var edgenodes = GetEdgeNodes();
            // たぶん意味は無いと思うが、rootを変更しても問題になることは無いだろう的な
            ChangeRootNode(edgenodes.First());
        }
예제 #49
0
        private bool ShavingNodeChecker(DendriteNode node, DendriteNode parent, int level)
        {
            if (level > 0)
            {
                if (node.NodeType == DendriteNodeType.EDGE && node != root)
                {
                    // 端点が見つかればそこからノードを削除
                    // ConnectedNodes[0]はnodeのparent??? ← その通り
                    // 基本的にはそうだが、補間によって接続されると、そうとも限らないかもしれない
                    // ChangeRootNodeしたときにうまく動いているかもしれないけど
                    ShavingRec(node.ConnectedNodes[0], node);
                    return true;
                }
                else if (node.NodeType == DendriteNodeType.CONNECT)
                {
                    // 通過点の場合 探索続行
                    // foreachを使うと動かない (ShavingRecの中でConnectedNodesが削除されるから
                    // 
                    // removeされたものが1つでもあったらi--しないといけないかも??
                    for (int i = 0; i < node.GetConnectedNodeNum(); i++)
                    {
                        var next = node.ConnectedNodes[i];
                        if (next != parent)
                        {
                            if (ShavingNodeChecker(next, node, level - 1))
                            {
                                i--;
                            }
                        }
                    }
                }
            }

            return false;
        }
예제 #50
0
        private void GetEdgeAndBranchNodesRec(IList<DendriteNode> list, DendriteNode node, DendriteNode parent)
        {
            if (node.NodeType == DendriteNodeType.EDGE || node.NodeType == DendriteNodeType.BRANCH) list.Add(node);

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    GetEdgeAndBranchNodesRec(list, next, node);
                }
            }
        }
예제 #51
0
        //ノード情報から樹状突起の実際の長さと電気長などを計算
        private void SetDistanceRec(DendriteNode node, DendriteNode parent)
        {
            XMax = Math.Max(XMax, node.gx);
            XMin = Math.Min(XMin, node.gx);
            YMax = Math.Max(YMax, node.gy);
            YMin = Math.Min(YMin, node.gy);
            ZMax = Math.Max(ZMax, node.gz);
            ZMin = Math.Min(ZMin, node.gz);

            //親ノードと子ノード間のユークリッド距離
            double d = node.EuclideanDistanceTo(parent);

            node.RealDistance = parent.RealDistance + d;

            //二点のノードの平均半径
            double aveRadius = (node.Radius + parent.Radius) / 2;

            //電気的距離 R = ρ*L/(pi*r_ave^2) 定数部分は除去して R = L/r_ave^2
            node.ElectricalDistance = parent.ElectricalDistance + d / (aveRadius);

            MaxRealDistance = Math.Max(node.RealDistance, MaxRealDistance);
            MaxElectricalDistance = Math.Max(node.ElectricalDistance, MaxElectricalDistance);

            TotalLength += d;
            TotalElectricalLength += d / aveRadius;

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SetDistanceRec(next, node);
                }
            }
        }
예제 #52
0
        private void SetGravityPointAndRadiusRec(DendriteNode node, DendriteNode parent)
        {
            //重心計算
            node.SetGravityPointByClusters(resox, resoz);

            //突起半径計算
            node.CalcRadius(volunit);

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SetGravityPointAndRadiusRec(next, node);
                }
            }
        }
예제 #53
0
        private static void GetEdgeNodesRec(IList<DendriteNode> list, DendriteNode node, DendriteNode parent)
        {
            if (node.NodeType == DendriteNodeType.EDGE)
            {
                list.Add(node);
            }

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    GetEdgeNodesRec(list, next, node);
                }
            }
        }
예제 #54
0
        void CytEdges(StreamWriter sw, Dendrite dend, DendriteNode node, DendriteNode parent, DendriteNode pnode)
        {
            if (pnode != null && node.NodeType != DendriteNodeType.CONNECT) sw.WriteLine("{0} {1} {2} {3}", pnode.Id, node.Id, (node.RealDistance - pnode.RealDistance), (node.ElectricalDistance - pnode.ElectricalDistance));

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    if (node.NodeType == DendriteNodeType.CONNECT) CytEdges(sw, dend, next, node, pnode);
                    else CytEdges(sw, dend, next, node, node);
                }
            }

        }
예제 #55
0
        private void SetNodeTypeRec(DendriteNode node, DendriteNode parent)
        {
            //連結しているノードの数でノードのタイプを判定
            if (node.GetConnectedNodeNum() == 1) // 他の一つのクラスターにしか繋がっていないクラスターはEdgeクラスターである
            {
                node.NodeType = DendriteNodeType.EDGE;
                edge++;
            }
            else if (node.GetConnectedNodeNum() >= 3) // 他の3つのクラスターに繋がっているクラスターはBranchクラスターである
            {
                node.NodeType = DendriteNodeType.BRANCH;
                branch++;
            }
            else
            {
                node.NodeType = DendriteNodeType.CONNECT; // 他の2つのクラスターに繋がっているクラスターはEdgeクラスターでもBranchクラスターでもない
            }

            foreach (var child in node.ConnectedNodes)
            {
                if (child != parent)
                {
                    SetNodeTypeRec(child, node);
                }
            }
        }
예제 #56
0
 private void GetDendriteNodesRec(IList<DendriteNode> list, DendriteNode node, DendriteNode parent)
 {
     list.Add(node);
     foreach (var next in node.ConnectedNodes)
     {
         if (next != parent)
         {
             GetDendriteNodesRec(list, next, node);
         }
     }
 }
예제 #57
0
        private void SetIdRec(DendriteNode node, DendriteNode parent)
        {
            //分類番号の設定
            node.Id = idsum;
            idsum++;

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    SetIdRec(next, node);
                }
            }
        }
예제 #58
0
        private void PruningRec(DendriteNode node, DendriteNode parent, int nodeId) {
            if (node.Id == nodeId)
            {
                node.ConnectedNodes.Clear();
                node.AddConnectedNode(parent);
                return;
            }

            foreach (var next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    PruningRec(next, node, nodeId);
                }
            }
        }
예제 #59
0
        void Edge(DendriteNode node, DendriteNode root, int deg, StringBuilder sb)
        {
            if (node.Degree == deg && !flag)
            {
                flag = true;
                if (root != null && root.NodeType == DendriteNodeType.BRANCH)
                {
                    edgec.Add(root);
                }
            }

            if (flag)
            {
                edgec.Add(node);
            }

            if (node.NodeType == DendriteNodeType.EDGE && root != null && flag)
            {
                double aver    = 0;
                double length  = 0;
                double elength = 0;

                // calc average radius
                edgec.ForEach(item => aver += item.Radius);
                aver /= edgec.Count;

                // calc edge length
                length  = edgec[edgec.Count - 1].RealDistance - edgec[0].RealDistance;
                elength = edgec[edgec.Count - 1].ElectricalDistance - edgec[0].ElectricalDistance;


                sb.AppendFormat("{0},{1},{2},", aver, length, elength);
                edgec.ForEach(item => sb.AppendFormat("{0},", item.Id + 1));
                sb.Remove(sb.Length - 1, 1);
                sb.AppendLine();

                edgec.Clear();
                count[deg - 1]++;

                flag = false;
                return;
            }


            bool         end = true;
            DendriteNode tmp;

            if (node.NodeType == DendriteNodeType.BRANCH && flag)
            {
                for (int i = 0; i < node.ConnectedNodes.Count; i++)
                {
                    if (node.ConnectedNodes[i] != root)
                    {
                        if (node.ConnectedNodes[i].Degree == deg)
                        {
                            end = false;
                            if (i == 0)
                            {
                                continue;
                            }
                            tmp = node.ConnectedNodes[0];
                            node.ConnectedNodes[0] = node.ConnectedNodes[i];
                            node.ConnectedNodes[i] = tmp;
                        }
                    }
                }

                if (end)
                {
                    double aver    = 0;
                    double length  = 0;
                    double elength = 0;

                    // calc average radius
                    edgec.ForEach(item => aver += item.Radius);
                    aver /= edgec.Count;

                    // calc edge length
                    length  = edgec[edgec.Count - 1].RealDistance - edgec[0].RealDistance;
                    elength = edgec[edgec.Count - 1].ElectricalDistance - edgec[0].ElectricalDistance;

                    sb.AppendFormat("{0},{1},{2},", aver, length, elength);
                    edgec.ForEach(item => sb.AppendFormat("{0},", item.Id + 1));
                    sb.Remove(sb.Length - 1, 1);
                    sb.AppendLine();

                    edgec.Clear();
                    count[deg - 1]++;
                    flag = false;
                }
            }
            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != root)
                {
                    Edge(next, node, deg, sb);
                }
            }
        }
예제 #60
0
        void PajekEdgesRD(StreamWriter sw, DendriteNode node, DendriteNode parent, DendriteNode pnode)
        {
            if (pnode != null && node.NodeType != DendriteNodeType.CONNECT) sw.WriteLine("{0} {1} {2}", pnode.Id, node.Id, node.RealDistance - pnode.RealDistance);

            foreach (DendriteNode next in node.ConnectedNodes)
            {
                if (next != parent)
                {
                    if (node.NodeType == DendriteNodeType.CONNECT) PajekEdgesRD(sw, next, node, pnode);
                    else PajekEdgesRD(sw, next, node, node);
                }
            }

        }