//获取所有分支 private List <string> GetAllBranch(TreeNodes rootTree) { //获取所有的线 List <string> mrvBranch = new List <string>(); InitTreeWithDepth(rootTree); SearchAllBranch(rootTree, mrvBranch, 'a', 0); SortByLengthWithList(mrvBranch); return(mrvBranch); }
/// <summary> /// 绘图 /// </summary> /// <param name="rootTree"></param> /// <returns></returns> private MDocument WriteBrachTree(TreeNodes rootTree) { //获取所有分支 List <string> listBranch = GetAllBranch(rootTree); //开始遍历子节点 _ListTextPosition = new List <string>(); MDocument md = WriteBranchWithMD(listBranch); return(md); }
/// <summary> /// 找当前节点的最长路线(反向输出路线) /// </summary> /// <param name="node"></param> /// <param name="isRoots">用于判断当前分支是否是最长分支搜索</param> /// <returns></returns> private string GetMaxLengthRoute(TreeNodes node, bool isRoots, char index, int level) { node.IsSearch = true; if (node.Children.Count == 0) { return(node.Smiles + ";" + level + index); } int dept = -1; TreeNodes temp = new TreeNodes(); int i = 0; int tag_i = 0; foreach (var item in node.Children) { if (dept < item.MaxDepth) { dept = item.MaxDepth; temp = item; tag_i = i; } i++; } if (isRoots) { string str = string.Empty; int j = 0; foreach (var item in node.Children) { if (item.NodeID != temp.NodeID) { if (string.IsNullOrEmpty(str)) { str += item.Smiles + ";" + (level + 1) + Convert.ToChar('a' + j); } else { str += "," + item.Smiles + ";" + (level + 1) + Convert.ToChar('a' + j); } } j++; } if (DicBranchSmiles == null) { DicBranchSmiles = new Dictionary <int, string>(); } DicBranchSmiles.Add(temp.MaxDepth, str); } char childIndex = Convert.ToChar('a' + tag_i); return(GetMaxLengthRoute(temp, isRoots, childIndex, level + 1) + "," + node.Smiles + ";" + level + index); }
/// <summary> /// 绘图 /// </summary> /// <param name="rootTree"></param> /// <returns></returns> private MDocument WriteTree(TreeNodes rootTree) { MoleCulePostion mp = new MoleCulePostion(rootTree.Smiles); MDocument md = new MDocument(mp.Mol); //初始化树的叶子节点数量 InitTreeLeapNum(rootTree); //开始遍历子节点 _DicListTextPosition = new Dictionary <int, List <string> >(); _DicListTextPosition.Add(0, new List <string>()); //上 _DicListTextPosition.Add(1, new List <string>()); //中 _DicListTextPosition.Add(2, new List <string>()); //下 SearchChildNode(rootTree, md, mp, mp.Mol, 1); return(md); }
/// <summary> /// 返回整个路线列表 /// </summary> /// <param name="result"></param> /// <returns></returns> public string WriteToMrvWithAllRouteWithStr(string result) { //取根路线 List <TreeNodes> treeNodes = JsonConvert.DeserializeObject <List <TreeNodes> >(result); TreeNodes rootTree = new TreeNodes(); foreach (var item in treeNodes) { if (item.PID == 0) { rootTree = item; } } //树绘图 MDocument md = WriteTree(rootTree); return(MolExporter.exportToFormat(md, "mrv")); }
/// <summary> /// 初始化树的叶子节点数量 /// </summary> /// <param name="rootTree"></param> /// <returns></returns> private void InitTreeLeapNum(TreeNodes treeNode) { int num = 0; foreach (var item in treeNode.Children) { if (item.Children.Count == 0) { item.ChildLeapNum = 1; } else { InitTreeLeapNum(item); } num += item.ChildLeapNum; } treeNode.ChildLeapNum = num; }
/// <summary> /// 找到所有不存在重复分子的分支 /// </summary> /// <param name="node"></param> /// <param name="mrvBranch"></param> private void SearchAllBranch(TreeNodes node, List <string> mrvBranch, char index, int level) { if (node.IsSearch == false) { //找当前节点的最长路线 string route = GetMaxLengthRoute(node, node.PID == 0 ? true : false, index, level); if (route.Split(',').Count() > 1) { mrvBranch.Add(route); } node.IsSearch = true; } int i = 0; foreach (var item in node.Children) { SearchAllBranch(item, mrvBranch, Convert.ToChar('a' + i++), level + 1); } }
/// <summary> /// 初始化树所有节点的长度 /// </summary> /// <param name="rootTree"></param> private void InitTreeWithDepth(TreeNodes node) { if (node.Children.Count == 0) { node.MaxDepth = 1; return; } int childDept = -1; foreach (var item in node.Children) { InitTreeWithDepth(item); if (item.MaxDepth > childDept) { childDept = item.MaxDepth; } } node.MaxDepth = 1 + childDept; }
/// <summary> /// 返回文件流的mrv /// </summary> /// <param name="result"></param> /// <returns></returns> public MemoryStream WriteToMrvWithBranch(string result) { //取根路线 List <TreeNodes> treeNodes = JsonConvert.DeserializeObject <List <TreeNodes> >(result); TreeNodes rootTree = new TreeNodes(); foreach (var item in treeNodes) { if (item.PID == 0) { rootTree = item; } } //树绘图 MDocument md = WriteBrachTree(rootTree); MemoryStream stream = new MemoryStream(MolExporter.exportToBinFormat(md, "cdx")); return(stream); }
public TreeNodes(TreeNodes fatherNode, Reaction react) { //NodeID = nodeID; Smiles = react.smilesInCode; if (fatherNode != null) { father = fatherNode; //PID = father.NodeID; level = father.level + 1; searchedSmiles = father.searchedSmiles.ToList(); father.Children.Add(this); } reaction = react; CAS = react.cas; //MolPrice = react.MolPrice; //reaction = new ReturnList(); //reaction.reactionObject = new List<Reaction>(); //Reaction re = react; ////re.smilesInCode = react; //reaction.reactionObject.Add(re); searchedSmiles.Add(Smiles); }
/// <summary> /// 遍历子节点加入画图中 /// </summary> /// <param name="node">当前节点</param> /// <param name="md">画图对象</param> /// <param name="previousMp">前一个节点的位置坐标对象</param> /// <param name="RootMol">根mol</param> /// <param name="level">层级</param> private void SearchChildNode(TreeNodes node, MDocument md, MoleCulePostion previousMp, Molecule RootMol, int bracnchIndex) { double molLeftSpace = 0; int num = node.Children.Count; if (num == 1) { TreeNodes childNode = node.Children[0]; //绘制 MoleCulePostion mp = new MoleCulePostion(childNode.Smiles); molLeftSpace = mp.Center_x - mp.Left_x; SetMolPosition(mp, previousMp.Right_x + SpanceX + molLeftSpace, previousMp.Center_y); RootMol.fuse(mp.Mol); //写mol层次号 string txt = ReactionSteps.ToString() + "a"; _DicListTextPosition[bracnchIndex].Add(txt + "," + mp.Center_x + "," + (mp.Bottom_y - TxtspaceWithMolInY)); //划水平线 MPoint p1 = new MPoint(previousMp.Right_x + SpanceX * (0.5 - SpaceLineScale / 2), previousMp.Center_y); MPoint p2 = new MPoint(previousMp.Right_x + SpanceX * (0.5 + SpaceLineScale / 2), previousMp.Center_y); MRectangle arrow = new MRectangle(p1, p2); md.addObject(arrow); //写反应步次 md.addObject(CreateMTextBox((ReactionSteps++).ToString(), new MPoint(previousMp.Right_x + SpanceX * 0.5, previousMp.Center_y + ReactionIndexSpaceWithLine))); //遍历子集 SearchChildNode(childNode, md, mp, RootMol, bracnchIndex); } else if (num > 1) { WriteText(md, bracnchIndex); if (num % 2 == 0) { //对称式绘出节点位置 double topY = previousMp.Center_y; double bottomY = previousMp.Center_y; List <double> listHigh = new List <double>(); List <char> listChar = new List <char>(); for (int i = 0; i < num; i++) { listChar.Add((char)('a' + i)); } var list = node.Children; for (int i = 0; i < list.Count; i += 2) { //记录当前反应的步数 int curStep = ReactionSteps++; double tempY1 = list[i].ChildLeapNum * SpanceY; double tempY2 = list[i + 1].ChildLeapNum * SpanceY; topY += tempY1 > tempY2 ? tempY1 : tempY2; bottomY -= tempY1 > tempY2 ? tempY1 : tempY2; listHigh.Add(topY); listHigh.Add(bottomY); //上半部分 MoleCulePostion mp1 = new MoleCulePostion(list[i].Smiles); molLeftSpace = mp1.Center_x - mp1.Left_x; SetMolPosition(mp1, previousMp.Right_x + SpanceX + molLeftSpace, topY); RootMol.fuse(mp1.Mol); //写mol层次号 string txt1 = curStep.ToString() + listChar[num - (num / 2 + i / 2) - 1]; _DicListTextPosition[0].Add(txt1 + "," + mp1.Center_x + "," + (mp1.Bottom_y - TxtspaceWithMolInY)); //找子集 SearchChildNode(list[i], md, mp1, RootMol, 0); //下半部分 MoleCulePostion mp2 = new MoleCulePostion(list[i + 1].Smiles); molLeftSpace = mp2.Center_x - mp2.Left_x; SetMolPosition(mp2, previousMp.Right_x + SpanceX + molLeftSpace, bottomY); RootMol.fuse(mp2.Mol); //写mol层次号 string txt2 = curStep.ToString() + listChar[num / 2 + i / 2]; _DicListTextPosition[2].Add(txt2 + "," + mp2.Center_x + "," + (mp2.Bottom_y - TxtspaceWithMolInY)); //写反应步次 double startWithText = 0.5 - SpaceLineScale / 4; md.addObject(CreateMTextBox((curStep).ToString(), new MPoint(previousMp.Right_x + SpanceX * startWithText, previousMp.Center_y + ReactionIndexSpaceWithLine))); WriteBranchLine(previousMp.Right_x, previousMp.Center_y, listHigh, md); //找子集 SearchChildNode(list[i + 1], md, mp2, RootMol, 2); } } else { //记录当前反应的步数 int curStep = ReactionSteps++; double topY = previousMp.Center_y; double bottomY = previousMp.Center_y; List <double> listHigh = new List <double>(); List <char> listChar = new List <char>(); for (int i = 0; i < num; i++) { listChar.Add((char)('a' + i)); } var list = node.Children; //先绘画水平节点 MoleCulePostion mp = new MoleCulePostion(list[0].Smiles); molLeftSpace = mp.Center_x - mp.Left_x; SetMolPosition(mp, previousMp.Right_x + SpanceX + molLeftSpace, previousMp.Center_y); RootMol.fuse(mp.Mol); //写mol层次号 string txt = curStep.ToString() + listChar[num / 2]; _DicListTextPosition[1].Add(txt + "," + mp.Center_x + "," + (mp.Bottom_y - TxtspaceWithMolInY)); //找子集 SearchChildNode(list[0], md, mp, RootMol, 1); //分隔两侧间距 double high_mp = list[0].ChildLeapNum * SpanceY; topY += high_mp; bottomY -= high_mp; listHigh.Add(previousMp.Center_y); //两端节点 for (int i = 1; i < list.Count; i += 2) { double tempY1 = list[i].ChildLeapNum * SpanceY; double tempY2 = list[i + 1].ChildLeapNum * SpanceY; topY += tempY1 > tempY2 ? tempY1 : tempY2; bottomY -= tempY1 > tempY2 ? tempY1 : tempY2; listHigh.Add(topY); listHigh.Add(bottomY); //上半部分 MoleCulePostion mp1 = new MoleCulePostion(list[i].Smiles); molLeftSpace = mp1.Center_x - mp1.Left_x; SetMolPosition(mp1, previousMp.Right_x + SpanceX + molLeftSpace, topY); RootMol.fuse(mp1.Mol); //写mol层次号 string txt1 = curStep.ToString() + listChar[num / 2 - 1 - i / 2]; _DicListTextPosition[0].Add(txt1 + "," + mp1.Center_x + "," + (mp1.Bottom_y - TxtspaceWithMolInY)); //找子集 SearchChildNode(list[i], md, mp1, RootMol, 0); //下半部分 MoleCulePostion mp2 = new MoleCulePostion(list[i + 1].Smiles); molLeftSpace = mp2.Center_x - mp2.Left_x; SetMolPosition(mp2, previousMp.Right_x + SpanceX + molLeftSpace, bottomY); RootMol.fuse(mp2.Mol); //写mol层次号 string txt2 = curStep.ToString() + listChar[num / 2 + 1 + i / 2]; _DicListTextPosition[2].Add(txt2 + "," + mp2.Center_x + "," + (mp2.Bottom_y - TxtspaceWithMolInY)); //写反应步次 double startWithText = 0.5 - SpaceLineScale / 4; md.addObject(CreateMTextBox((curStep).ToString(), new MPoint(previousMp.Right_x + SpanceX * startWithText, previousMp.Center_y + ReactionIndexSpaceWithLine))); WriteBranchLine(previousMp.Right_x, previousMp.Center_y, listHigh, md); //找子集 SearchChildNode(list[i + 1], md, mp2, RootMol, 2); } } } else { WriteText(md, bracnchIndex); } }
// build treenodes from root private TreeNodes createTreeNodes() { // root Reaction reac = new Reaction(); reac.canMake = targetReactif.canMake; reac.smilesInCode = targetReactif.smilesInCode; reac.knownMol = targetReactif.knownMol; TreeNodes treeRoot = new TreeNodes(); treeRoot.reaction = reac; treeRoot.Smiles = reac.smilesInCode; treeRoot.Feasibility = ((reaction.HasRegioError != 0 || reaction.Retro.MayHaveError != 0) ? 1 : 0) + reaction.Retro.IncompatbleIDs.Count + reaction.Retro.UncertantIncompatbleIDs.Count; treeRoot.ComboRetroReactionID = reaction.Retro.ComboRetroReactionID; treeRoot.ComboRetroReactionIDs = reaction.Retro.ComboRetroReactionIDs; treeRoot.prodcdid = reaction.similCdid; treeRoot.RetroReactionID = reaction.Retro.RetroReactionID; treeRoot.RetroReactionIDs = reaction.Retro.RetroReactionIDs; treeRoot.fiabilityScore = reaction.Retro.fiabilityScore; treeRoot.needProtection = reaction.Retro.NeedProtection; treeRoot.reactionId = reaction.reactionID; //if (reaction.Retro.groupDetail != null && reaction.Retro.groupDetail.Count > 0) //{ // var mingroup = reaction.Retro.groupDetail.FirstOrDefault(); // treeRoot.testString = (((reaction.HasRegioError + reaction.Retro.MayHaveError) > 0 ? " regio" : "") + reaction.Retro.Frequency.ToString("0.0000") + " " + GroupInfo.groupNameDict[mingroup.Key] + " " + mingroup.Value.count + " " + mingroup.Value.Score.ToString("0.00")); //} //else //{ // treeRoot.testString = (((reaction.HasRegioError + reaction.Retro.MayHaveError) > 0 ? " regio" : "") + reaction.Retro.Frequency.ToString("0.0000")); //} //treeRoot.testString = reaction.similRank.ToString("0.00") + " " + reaction.Retro.fiabilityScore;//reaction.Retro.Count + " " + groupRank; //reaction.Retro.TotalCount + "-" + reaction.Retro.RetroTypeCount;// treeRoot.testString = ((reaction.Retro.IncompatbleIDs.Count + reaction.Retro.UncertantIncompatbleIDs.Count) > 0 ? "compat" : "") + ((reaction.HasRegioError + reaction.Retro.MayHaveError) > 0 ? " regio" : "") + ChoiseRank + "_" + RankIndexSimil + "|" + RankIndexScore; treeRoot.ChoiseRank = ChoiseRank; treeRoot.RankIndexSimil = RankIndexSimil; treeRoot.RankIndexScore = RankIndexScore; if (reaction.reactionObject != null) { foreach (var react in reaction.reactionObject) { Node current; if (react.currentChildNode != null && react.currentChildNode.useCurrent) { current = react.currentChildNode; react.currentChildNode.useCurrent = false; } else { current = react.BestChildNode; } if (current == null) { TreeNodes treeRoot1 = new TreeNodes(); treeRoot1.reaction = new Reaction(); treeRoot1.reaction.canMake = react.canMake; treeRoot1.reaction.MoleculeID = react.MoleculeID; treeRoot1.reaction.smilesInCode = react.smilesInCode; treeRoot1.Smiles = react.smilesInCode; treeRoot1.CAS = react.cas; if (treeRoot1.reaction.canMake == 1) { treeRoot1.reaction.MolPrice = react.MolPrice; } treeRoot1.reaction.HasSupplier = react.HasSupplier; treeRoot1.reaction.knownMol = react.knownMol; treeRoot.Children.Add(treeRoot1); continue; } Node child = current; treeRoot.Children.Add(child.createTreeNodes()); } } return(treeRoot); }