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); }
//ノード情報から樹状突起の実際の長さと電気長などを計算 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); } } }
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); } } }
// 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); } }
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); } } }
//ルートノードの変更 public void ChangeRootNode(DendriteNode node) { root = node; SetId(); SetNodeType(); SetDistance(); SetParentNodeAsFirstElement(); this.MaxDegree = SetDegree(root, null) + 1; }
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); } } }
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); } } }
private void SetIdRec(DendriteNode node, DendriteNode parent) { //分類番号の設定 node.Id = idsum; idsum++; foreach (var next in node.ConnectedNodes) { if (next != parent) { SetIdRec(next, node); } } }
// 呼び出す前に、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); } }
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); } } }
//平滑後の値の更新 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); } } }
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); } } }
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); } } }
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); } } }
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); } } }
//径の平滑化 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); } } }
//ノード間連結性チェッカ 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; }
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); } } }
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); } } }
// 参考情報: 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); }
// 参考情報: 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; }
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); } } }
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); } } }
//ノード間連結性チェッカ 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); }
//ノード連結関係を調べて木構造を生成 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()); }
//重心座標の平滑化 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); } } }
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); } } } }
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); } } } }
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); } } } }
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); } } } }
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); } } }
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); } } }
// 呼び出す前に、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; } }
//重心座標の平滑化 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); } } }
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); } }
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); } }
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); } }
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); } } }
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); } } }
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); } }
//ノード連結関係を調べて木構造を生成 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()); }
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; }
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); } } }
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); } } }
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); } } }
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); } } }
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); } } }
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); } } }