diff --git a/LipidCreator/StructureEditor/LipidStructure.cs b/LipidCreator/StructureEditor/LipidStructure.cs index 5978ebc..8c0c439 100644 --- a/LipidCreator/StructureEditor/LipidStructure.cs +++ b/LipidCreator/StructureEditor/LipidStructure.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using System.Windows.Forms; using System.Drawing; using System.Collections.Generic; @@ -10,6 +11,14 @@ namespace LipidCreatorStructureEditor { public enum NodeState {Enabled, Disabled, Hidden}; + + public class S { + public static string space(int n) + { + return new string(' ', 2 * n); + } + } + public class NodeProjection { public PointF shift = new PointF(0, 0); @@ -42,6 +51,12 @@ public void prepareMove() { previousShift = new PointF(shift.X, shift.Y); } + + + public void serialize(StringBuilder sb, int id, int tabs = 0) + { + sb.Append(String.Format(S.space(tabs) + "\n", id, shift.X, shift.Y, nodeState)); + } } public class StructureNode @@ -113,7 +128,46 @@ public void toggleState() NodeProjection decoratorProjection = decorator.nodeProjections[lipidStructure.currentProjection]; decoratorProjection.nodeState = nodeProjections[lipidStructure.currentProjection].nodeState; } - lipidStructure.countNodeConnections(); + lipidStructure.computeBonds(); + } + + public void toggleAtom() + { + if (lipidStructure.currentProjection == 0 || !lipidStructure.additionalNodes.Contains(this)) return; + + switch(text) + { + case "C": text = "H"; break; + case "H": text = "N"; break; + case "N": text = "O"; break; + case "O": text = "P"; break; + case "P": text = "S"; break; + case "S": text = "C"; break; + default: break; + } + isCarbon = text.Equals("C"); + lipidStructure.computeBonds(); + } + + + public void serialize(StringBuilder sb, int tabs = 0) + { + sb.Append(String.Format(S.space(tabs) + "\n", text)); + if (decorators.Count > 0) + { + sb.Append(S.space(tabs + 1) + "\n"); + foreach (var decorator in decorators) decorator.serialize(sb, tabs + 2); + sb.Append(S.space(tabs + 1) + "\n"); + } + if (nodeProjections.Count > 0) + { + sb.Append(S.space(tabs + 1) + "\n"); + foreach (var kvp in nodeProjections) kvp.Value.serialize(sb, kvp.Key, tabs + 2); + sb.Append(S.space(tabs + 1) + "\n"); + } + sb.Append(S.space(tabs) + "\n"); } } @@ -136,11 +190,17 @@ public StructureEdge(StructureEdge copy) start = new PointF(copy.start.X, copy.start.Y); end = new PointF(copy.end.X, copy.end.Y); } + + public void serialize(StringBuilder sb, int tabs = 0) + { + sb.Append(S.space(tabs) + String.Format("\n", start.X, start.Y, end.X, end.Y)); + } } public class Bond { + public int id; public int startId; public int endId; public bool isDoubleBond = false; @@ -149,8 +209,9 @@ public class Bond public Dictionary bondProjections = new Dictionary(); public LipidStructure lipidStructure; - public Bond(LipidStructure _lipidStructure, int start, int end, bool doubleBond) + public Bond(LipidStructure _lipidStructure, int _id, int start, int end, bool doubleBond) { + id = _id; lipidStructure = _lipidStructure; startId = start; endId = end; @@ -159,6 +220,7 @@ public Bond(LipidStructure _lipidStructure, int start, int end, bool doubleBond) public Bond(Bond copy) { + id = copy.id; startId = copy.startId; endId = copy.endId; isDoubleBond = copy.isDoubleBond; @@ -182,6 +244,11 @@ public void toggleState() bondProjections[lipidStructure.currentProjection] = !bondProjections[lipidStructure.currentProjection]; lipidStructure.countNodeConnections(); } + + public void serialize(StringBuilder sb, int tabs = 0) + { + + } } @@ -205,6 +272,11 @@ public void toggleCharge() { charge = (charge >= maxCharge) ? minCharge : charge + 1; } + + public void serialize(StringBuilder sb, int tabs = 0) + { + + } } @@ -214,10 +286,11 @@ public class LipidStructure public List nodes = new List(); public HashSet additionalNodes = new HashSet(); public List bonds = new List(); - public List additionalBonds = new List(); + public HashSet additionalBonds = new HashSet(); + public Dictionary positiveFragments = new Dictionary(); + public Dictionary negativeFragments = new Dictionary(); + public Dictionary idToNode = new Dictionary(); - public float offsetX = 0; - public float offsetY = 0; public float factor = 2.5f; public float dbSpace = 1.5f; public float fontSize = 10.0f; @@ -234,15 +307,13 @@ public class LipidStructure public Graphics graphics; public int currentProjection; public LipidStructureFragment currentFragment = null; - public Dictionary positiveFragments = new Dictionary(); - public Dictionary negativeFragments = new Dictionary(); public Dictionary nodeConnectionsCount = new Dictionary(); public Dictionary nodeConnectionsHiddenCount = new Dictionary(); public HashSet specialAtoms = new HashSet(){"N", "O", "P", "S"}; public Dictionary freeElectrons = new Dictionary(){{"C", 4}, {"N", 3}, {"O", 2}, {"P", 3}, {"S", 2}}; public int projectionIds = 1; public int currentNodeId = 0; - + public int bondIDs = 0; public void parseXML(XElement element, List nodes, List edges) @@ -392,7 +463,7 @@ public LipidStructure(string file_name, Form form) // get the edge color bool isDoubleBond = ((string)edge.Attribute("Order") != null) && edge.Attribute("Order").Value.ToString().Equals("2"); - bond = new Bond(this, idB, idE, isDoubleBond); + bond = new Bond(this, bondIDs++, idB, idE, isDoubleBond); bonds.Add(bond); } catch(Exception){} @@ -419,8 +490,8 @@ public LipidStructure(string file_name, Form form) float midX = minX + (maxX - minX) / 2.0f; float midY = minY + (maxY - minY) / 2.0f; - offsetX = (float)form.Size.Width / 2.0f - midX * factor; - offsetY = (float)form.Size.Height / 2.0f - midY * factor; + float offsetX = (float)form.Size.Width / 2.0f - midX * factor; + float offsetY = (float)form.Size.Height / 2.0f - midY * factor; nodeFont = new Font("Arial", fontSize * factor); @@ -468,20 +539,81 @@ public LipidStructure(string file_name, Form form) foreach (var bond in bonds) bond.bondProjections.Add(0, bond.isDoubleBond); currentProjection = 0; - computeBonds(bonds); + computeBonds(); changeFragment(); countNodeConnections(); + + serialize("foo"); } + public void serialize(string file_name) + { + StringBuilder sb = new StringBuilder(); + sb.Append("\n"); + + // add node information + sb.Append(" \n"); + foreach (var node in nodes) node.serialize(sb, 2); + sb.Append(" \n"); + + // add additional node information + if (additionalNodes.Count > 0) + { + sb.Append(" \n"); + foreach (var node in additionalNodes) sb.Append(String.Format(" \n", node.id)); + sb.Append(" \n"); + } + + // add bond information + sb.Append(" \n"); + foreach (var bond in bonds) bond.serialize(sb, 2); + sb.Append(" \n"); + + // add additional bond information + if (additionalBonds.Count > 0) + { + sb.Append(" \n"); + foreach (var bond in additionalBonds) sb.Append(String.Format(" \n", bond.id)); + sb.Append(" \n"); + } + + // add positive fragments + if (positiveFragments.Count > 0) + { + sb.Append(" \n"); + foreach (var kvp in positiveFragments) kvp.Value.serialize(sb, 2); + sb.Append(" \n"); + } + + // add positive fragments + if (negativeFragments.Count > 0) + { + sb.Append(" \n"); + foreach (var kvp in negativeFragments) kvp.Value.serialize(sb, 2); + sb.Append(" \n"); + } + + + + sb.Append("\n"); + + Console.WriteLine(sb.ToString()); + } + + + public void addFragment(string fragmentName, bool isPositive) { int newProjectionId = projectionIds++; - if (isPositive) positiveFragments.Add(fragmentName, new LipidStructureFragment(newProjectionId, fragmentName)); - else negativeFragments.Add(fragmentName, new LipidStructureFragment(newProjectionId, fragmentName)); + + LipidStructureFragment newFragment = new LipidStructureFragment(newProjectionId, fragmentName, currentFragment != null ? currentFragment.charge : 0); + + if (isPositive) positiveFragments.Add(fragmentName, newFragment); + else negativeFragments.Add(fragmentName, newFragment); foreach (var node in nodes) { @@ -490,19 +622,7 @@ public void addFragment(string fragmentName, bool isPositive) } foreach (var bond in bonds) bond.bondProjections.Add(newProjectionId, bond.bondProjections[currentProjection]); - List bondsToAdd = new List(); - foreach (var bond in additionalBonds) - { - if (bond.bondProjections.ContainsKey(currentProjection)) - { - Bond newBond = new Bond(bond); - newBond.bondProjections.Add(newProjectionId, bond.bondProjections[currentProjection]); - bondsToAdd.Add(newBond); - } - } - foreach (Bond bond in bondsToAdd) additionalBonds.Add(bond); - computeBonds(additionalBonds); - countNodeConnections(); + computeBonds(); } @@ -530,10 +650,7 @@ public void removeFragment(string fragmentName, bool isPositive) foreach (var decorator in node.decorators) decorator.nodeProjections.Remove(projectionId); } foreach (var bond in bonds) bond.bondProjections.Remove(projectionId); - foreach (var bond in additionalBonds) - { - if (bond.bondProjections.ContainsKey(projectionId)) bond.bondProjections.Remove(projectionId); - } + if (currentProjection == projectionId) { currentProjection = 0; @@ -544,18 +661,11 @@ public void removeFragment(string fragmentName, bool isPositive) - public void computeBonds() - { - computeBonds(bonds); - computeBonds(additionalBonds); - countNodeConnections(); - } - - public void computeBonds(List checkBonds) + public void computeBonds() { List deleteBonds = new List(); - foreach (var bond in checkBonds) + foreach (var bond in bonds) { if (!idToNode.ContainsKey(bond.startId) || !idToNode.ContainsKey(bond.endId)) { @@ -568,7 +678,7 @@ public void computeBonds(List checkBonds) if (!nodeB.nodeProjections.ContainsKey(currentProjection) || !nodeE.nodeProjections.ContainsKey(currentProjection)) { - deleteBonds.Add(bond); + //deleteBonds.Add(bond); continue; } @@ -617,7 +727,13 @@ public void computeBonds(List checkBonds) bond.edgeSingle = new StructureEdge(new PointF(xB, yB), new PointF(xE, yE)); } - foreach (var bond in deleteBonds) checkBonds.Remove(bond); + foreach (var bond in deleteBonds) + { + bonds.Remove(bond); + if (additionalBonds.Contains(bond)) additionalBonds.Remove(bond); + } + + countNodeConnections(); } @@ -667,22 +783,25 @@ public StructureNode removeNode(StructureNode node) public void addBond(StructureNode start, StructureNode end) { if (currentProjection == 0) return; - Bond bond = new Bond(this, start.id, end.id, false); + Bond bond = new Bond(this, bondIDs++, start.id, end.id, false); bond.bondProjections.Add(currentProjection, false); + bonds.Add(bond); additionalBonds.Add(bond); - computeBonds(additionalBonds); - countNodeConnections(); + computeBonds(); } public void removeBond(Bond bond) { - if (currentProjection == 0) return; - if (!additionalBonds.Contains(bond)) return; - additionalBonds.Remove(bond); - computeBonds(additionalBonds); - countNodeConnections(); + if (currentProjection == 0|| !additionalBonds.Contains(bond) || !bond.bondProjections.ContainsKey(currentProjection)) return; + bond.bondProjections.Remove(currentProjection); + if (bond.bondProjections.Count == 0) + { + additionalBonds.Remove(bond); + bonds.Remove(bond); + } + computeBonds(); } @@ -729,24 +848,6 @@ public void countNodeConnections() foreach (var node in nodes) nodeConnectionsHiddenCount.Add(node.id, 0); foreach (var bond in bonds) - { - - StructureNode nodeB = idToNode[bond.startId]; - StructureNode nodeE = idToNode[bond.endId]; - NodeProjection proStart = nodeB.nodeProjections[currentProjection]; - NodeProjection proEnd = nodeE.nodeProjections[currentProjection]; - - if (proStart.nodeState == NodeState.Enabled && proEnd.nodeState == NodeState.Enabled) - { - nodeConnectionsCount[bond.startId] += bond.bondProjections[currentProjection] ? 2 : 1; - nodeConnectionsCount[bond.endId] += bond.bondProjections[currentProjection] ? 2 : 1; - } - if (proStart.nodeState != NodeState.Hidden && proEnd.nodeState != NodeState.Hidden){ - nodeConnectionsHiddenCount[bond.startId] += bond.bondProjections[currentProjection] ? 2 : 1; - nodeConnectionsHiddenCount[bond.endId] += bond.bondProjections[currentProjection] ? 2 : 1; - } - } - foreach (var bond in additionalBonds) { if (!bond.bondProjections.ContainsKey(currentProjection)) continue; @@ -804,6 +905,7 @@ public void drawEdges(Graphics g, Form form) foreach (var bond in bonds) { + if (!bond.bondProjections.ContainsKey(currentProjection)) continue; if (!idToNode[bond.startId].nodeProjections.ContainsKey(currentProjection) || !idToNode[bond.endId].nodeProjections.ContainsKey(currentProjection)) continue; @@ -824,29 +926,6 @@ public void drawEdges(Graphics g, Form form) g.DrawLine(pen, bond.edgeSingle.start, bond.edgeSingle.end); } } - - foreach (var bond in additionalBonds) - { - if (!bond.bondProjections.ContainsKey(currentProjection)) continue; - - NodeProjection proStart = idToNode[bond.startId].nodeProjections[currentProjection]; - NodeProjection proEnd = idToNode[bond.endId].nodeProjections[currentProjection]; - - if (!developmentView && (proStart.nodeState == NodeState.Hidden || proEnd.nodeState == NodeState.Hidden)) continue; - - Pen pen = penEnabled; - if (proStart.nodeState == NodeState.Hidden || proEnd.nodeState == NodeState.Hidden) pen = penHidden; - else if (proStart.nodeState == NodeState.Disabled || proEnd.nodeState == NodeState.Disabled) pen = penDisabled; - - if (bond.bondProjections[currentProjection]) - { - foreach (var edge in bond.edgesDouble) g.DrawLine(pen, edge.start, edge.end); - } - else - { - g.DrawLine(pen, bond.edgeSingle.start, bond.edgeSingle.end); - } - } releaseClipping(g, clippingGraphics); } @@ -861,34 +940,28 @@ public void drawNodes(Graphics g) drawFormat.Alignment = StringAlignment.Center; drawFormat.LineAlignment = StringAlignment.Center; - Dictionary> adjacentNodes = new Dictionary>(); foreach (var node in nodes) adjacentNodes.Add(node, new List()); foreach (var bond in bonds) { - NodeProjection proStart = idToNode[bond.startId].nodeProjections[currentProjection]; - NodeProjection proEnd = idToNode[bond.endId].nodeProjections[currentProjection]; - if (proStart.nodeState != NodeState.Hidden && proEnd.nodeState != NodeState.Hidden) - { - adjacentNodes[idToNode[bond.startId]].Add(idToNode[bond.endId]); - adjacentNodes[idToNode[bond.endId]].Add(idToNode[bond.startId]); - } - } - foreach (var bond in additionalBonds) - { - if (!bond.bondProjections.ContainsKey(currentProjection)) continue; - NodeProjection proStart = idToNode[bond.startId].nodeProjections[currentProjection]; - NodeProjection proEnd = idToNode[bond.endId].nodeProjections[currentProjection]; + if (!idToNode.ContainsKey(bond.startId) || !idToNode.ContainsKey(bond.endId)) continue; + + StructureNode nodeB = idToNode[bond.startId]; + StructureNode nodeE = idToNode[bond.endId]; + + if (!nodeB.nodeProjections.ContainsKey(currentProjection) || !nodeE.nodeProjections.ContainsKey(currentProjection) || !adjacentNodes.ContainsKey(nodeB) || ! adjacentNodes.ContainsKey(nodeE)) continue; + + NodeProjection proStart = nodeB.nodeProjections[currentProjection]; + NodeProjection proEnd = nodeE.nodeProjections[currentProjection]; if (proStart.nodeState != NodeState.Hidden && proEnd.nodeState != NodeState.Hidden) { - adjacentNodes[idToNode[bond.startId]].Add(idToNode[bond.endId]); - adjacentNodes[idToNode[bond.endId]].Add(idToNode[bond.startId]); + adjacentNodes[nodeB].Add(nodeE); + adjacentNodes[nodeE].Add(nodeB); } } - int minX = (1 << 30); int maxX = -(1 << 30); int minY = (1 << 30); diff --git a/LipidCreator/StructureEditor/StructureEditor.Designer.cs b/LipidCreator/StructureEditor/StructureEditor.Designer.cs index 452a393..23e0596 100644 --- a/LipidCreator/StructureEditor/StructureEditor.Designer.cs +++ b/LipidCreator/StructureEditor/StructureEditor.Designer.cs @@ -72,6 +72,7 @@ partial class LipidCreatorStructureEditor public ListBox negativeFragmentsListBox = new ListBox(); public Button actionChangeAtomState = new Button(); + public Button actionChangeAtom = new Button(); public Button actionChangeBondState = new Button(); public Button actionChangeGlobalCharge = new Button(); public Button actionDrawAtom = new Button(); @@ -100,6 +101,7 @@ partial class LipidCreatorStructureEditor public TextBox bb4Hydro = new TextBox(); public Label massLabel = new Label(); + public Label sumFormulaLabel = new Label(); public ComboBox adductComboBox = new ComboBox(); @@ -126,11 +128,17 @@ private void InitializeComponent() actionChangeAtomState.Location = new Point(10, 10); actionChangeAtomState.Click += actionChangeAtomStateClicked; + this.Controls.Add(actionChangeAtom); + actionChangeAtom.Size = new Size(120, 25); + actionChangeAtom.Text = "Change atom"; + actionChangeAtom.Location = new Point(10, actionChangeAtomState.Top + 35); + actionChangeAtom.Click += actionChangeAtomClicked; + this.Controls.Add(actionChangeBondState); actionChangeBondState.Size = new Size(120, 25); actionChangeBondState.Text = "Change bond state"; - actionChangeBondState.Location = new Point(10, actionChangeAtomState.Top + 35); + actionChangeBondState.Location = new Point(10, actionChangeAtom.Top + 35); actionChangeBondState.Click += actionChangeBondStateClicked; @@ -178,6 +186,7 @@ private void InitializeComponent() actionButtons.Add(actionChangeAtomState); + actionButtons.Add(actionChangeAtom); actionButtons.Add(actionChangeBondState); actionButtons.Add(actionDrawAtom); actionButtons.Add(actionDrawBond); @@ -252,6 +261,11 @@ private void InitializeComponent() massLabel.Location = new Point(200, 100); massLabel.Size = new Size(220, 25); + this.Controls.Add(sumFormulaLabel); + sumFormulaLabel.Location = new Point(200, 120); + sumFormulaLabel.Size = new Size(220, 25); + sumFormulaLabel.BringToFront(); + this.Controls.Add(bb2Carbon); diff --git a/LipidCreator/StructureEditor/StructureEditor.cs b/LipidCreator/StructureEditor/StructureEditor.cs index 925693a..ed1fdc9 100644 --- a/LipidCreator/StructureEditor/StructureEditor.cs +++ b/LipidCreator/StructureEditor/StructureEditor.cs @@ -4,12 +4,13 @@ using System.Collections.Generic; using System.Xml.Linq; using System.Linq; +using System.Text; using System.Drawing.Drawing2D; namespace LipidCreatorStructureEditor { public enum MouseState {MouseDefault, MouseDown, MouseDownMove}; - public enum Action {Idle, ChangeAtom, ChangeAtomSelect, ChangeBond, DrawAtom, DrawBond, RemoveAtom, RemoveBond, MoveAtom, MoveAtomSelect}; + public enum Action {Idle, ChangeAtomState, ChangeAtomSelect, ChangeBond, ChangeAtom, DrawAtom, DrawBond, RemoveAtom, RemoveBond, MoveAtom, MoveAtomSelect}; public partial class LipidCreatorStructureEditor : Form { @@ -69,7 +70,7 @@ private void DrawScene(Graphics g) var mouse = PointToClient(Cursor.Position); - if (((action == Action.ChangeAtom || action == Action.MoveAtom) && mouseState != MouseState.MouseDownMove) || action == Action.DrawBond || action == Action.DrawAtom || action == Action.RemoveAtom) + if (((action == Action.ChangeAtomState || action == Action.MoveAtom) && mouseState != MouseState.MouseDownMove) || action == Action.DrawBond || action == Action.DrawAtom || action == Action.RemoveAtom || action == Action.ChangeAtom) { if (currentNode != null && currentNode.nodeProjections.ContainsKey(lipidStructure.currentProjection)) { @@ -152,11 +153,16 @@ private void mouseUp(Object sender, MouseEventArgs e) switch (mouseState) { case MouseState.MouseDown: - if (action == Action.ChangeAtom && currentNode != null) + if (action == Action.ChangeAtomState && currentNode != null) { currentNode.toggleState(); updateStructure(); } + if (action == Action.ChangeAtom && currentNode != null) + { + currentNode.toggleAtom(); + updateStructure(); + } else if (action == Action.ChangeBond && currentBond != null) { currentBond.toggleState(); @@ -182,7 +188,7 @@ private void mouseUp(Object sender, MouseEventArgs e) } else if (action == Action.ChangeAtomSelect) { - action = Action.ChangeAtom; + action = Action.ChangeAtomState; } else if (action == Action.DrawAtom && currentNode == null) { @@ -193,7 +199,7 @@ private void mouseUp(Object sender, MouseEventArgs e) break; case MouseState.MouseDownMove: - if (action == Action.ChangeAtom && currentNode != null) + if (action == Action.ChangeAtomState && currentNode != null) { currentNode.toggleState(); updateStructure(); @@ -229,7 +235,7 @@ private void mouseUp(Object sender, MouseEventArgs e) } else if (action == Action.ChangeAtomSelect) { - action = Action.ChangeAtom; + action = Action.ChangeAtomState; var mouse = PointToClient(Cursor.Position); Point lower = new Point(Math.Min(startSelect.X, mouse.X), Math.Min(startSelect.Y, mouse.Y)); Point upper = new Point(Math.Max(startSelect.X, mouse.X), Math.Max(startSelect.Y, mouse.Y)); @@ -290,7 +296,7 @@ private void mouseDown(Object sender, MouseEventArgs e) mouseState = MouseState.MouseDown; if (currentNode == null) { - if (action == Action.ChangeAtom) + if (action == Action.ChangeAtomState) { startSelect = PointToClient(Cursor.Position); action = Action.ChangeAtomSelect; @@ -334,7 +340,7 @@ private void mouseMove(Object sender, MouseEventArgs e) PointF mouse = PointToClient(Cursor.Position); - if (action == Action.ChangeAtom || action == Action.MoveAtom || action == Action.DrawBond || action == Action.RemoveAtom) + if (action == Action.ChangeAtom || action == Action.ChangeAtomState || action == Action.MoveAtom || action == Action.DrawBond || action == Action.RemoveAtom) { double minDist = 1e10; foreach (var node in lipidStructure.nodes) @@ -383,18 +389,6 @@ private void mouseMove(Object sender, MouseEventArgs e) currentBond = bond; } } - foreach (var bond in lipidStructure.additionalBonds) - { - if (!bond.bondProjections.ContainsKey(lipidStructure.currentProjection)) continue; - double xb = (bond.edgeSingle.start.X + bond.edgeSingle.end.X) * 0.5; - double yb = (bond.edgeSingle.start.Y + bond.edgeSingle.end.Y) * 0.5; - double dist = Math.Pow(xb - mouse.X, 2) + Math.Pow(yb - mouse.Y, 2); - if (dist <= Math.Pow(10 + cursorCircleRadius, 2) && dist < minDistC) - { - minDistC = dist; - currentBond = bond; - } - } if (previousBond != currentBond) { @@ -471,7 +465,15 @@ private void buttonClicked(Button actionButton, Action newAction) private void actionChangeAtomStateClicked(Object sender, EventArgs e) { - buttonClicked(actionChangeAtomState, Action.ChangeAtom); + buttonClicked(actionChangeAtomState, Action.ChangeAtomState); + } + + + + + private void actionChangeAtomClicked(Object sender, EventArgs e) + { + buttonClicked(actionChangeAtom, Action.ChangeAtom); } @@ -844,6 +846,18 @@ private void computeFragmentMass(Object sender, EventArgs e) } mass += C * 12.0 + H * 1.007825035 + N * 14.0030740 + O * 15.99491463 + P * 30.973762 + S * 31.9720707; + Dictionary elements = new Dictionary(){{'C', C}, {'H', H}, {'N', N}, {'O', O}, {'P', P}, {'S', S}}; + StringBuilder formula = new StringBuilder(); + formula.Append("formula: "); + foreach (char chr in "CHNOPS") + { + int num = elements[chr]; + if (num <= 0) continue; + formula.Append(chr); + if (num > 1) formula.Append(num); + } + sumFormulaLabel.Text = formula.ToString(); + if (adductCharge != 0) mass = (mass - adductCharge * ELECTRON_REST_MASS) / Math.Abs(adductCharge); massLabel.Text = string.Format("m/z: {0:N6} Da", mass); }