Skip to content

Commit

Permalink
Structure editor kind of complete, maybe ... perhaps
Browse files Browse the repository at this point in the history
  • Loading branch information
dominik-kopczynski committed Nov 29, 2023
1 parent 66a545a commit 6391afe
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 49 deletions.
82 changes: 64 additions & 18 deletions LipidCreator/StructureEditor/LipidStructure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public SPointF(Point p)
return new SPointF(p.X - r.X, p.Y - r.Y);
}

public static SPointF operator /(SPointF p, float f)
{
return new SPointF(p.X / f, p.Y / f);
}

public PointF pF()
{
return new PointF(X, Y);
Expand All @@ -94,7 +99,8 @@ public Point pI()
}


public class S {
public class S
{
public static string space(int n)
{
return new string(' ', 2 * n);
Expand Down Expand Up @@ -362,6 +368,7 @@ public Bond(Bond copy)

public Bond(LipidStructure _lipidStructure, XElement element)
{
lipidStructure = _lipidStructure;
id = Convert.ToInt32(element.Attribute("id").Value);
startId = Convert.ToInt32(element.Attribute("start").Value);
endId = Convert.ToInt32(element.Attribute("end").Value);
Expand All @@ -386,7 +393,7 @@ public Bond(LipidStructure _lipidStructure, XElement element)

public void toggleState()
{
if (lipidStructure.currentProjection == 0) return;
if (lipidStructure.currentProjection == 0 || !bondProjections.ContainsKey(lipidStructure.currentProjection)) return;

bondProjections[lipidStructure.currentProjection] = !bondProjections[lipidStructure.currentProjection];
lipidStructure.countNodeConnections();
Expand Down Expand Up @@ -438,6 +445,13 @@ public LipidStructureFragment(int i, string f, int c = 0)
charge = c;
}

public LipidStructureFragment(XElement element)
{
id = Convert.ToInt32(element.Attribute("id").Value);
fragmentName = element.Attribute("name").Value;
charge = Convert.ToInt32(element.Attribute("charge").Value);
}

public void toggleCharge()
{
charge = (charge >= maxCharge) ? minCharge : charge + 1;
Expand Down Expand Up @@ -483,8 +497,8 @@ public class LipidStructure
public HashSet<string> specialAtoms = new HashSet<string>(){"N", "O", "P", "S"};
public Dictionary<string, int> freeElectrons = new Dictionary<string, int>(){{"C", 4}, {"N", 3}, {"O", 2}, {"P", 3}, {"S", 2}};
public int projectionIds = 1;
public int currentNodeId = 0;
public int bondIDs = 0;
public int nodeIds = 0;
public int bondIds = 0;



Expand Down Expand Up @@ -525,20 +539,28 @@ public LipidStructure(string file_name, Form form)
graphics = form.CreateGraphics();

string documentType = doc.Elements().First().Name.LocalName;
if (documentType.Equals("CDXML")) loadCDXML(doc);
else if (documentType.Equals("LipidStructure")) loadLipidStructure(doc);
else throw new Exception("Unknown data format");

nodeFont = new Font("Arial", fontSize * factor);
decoratorFont = new Font("Arial", (float)(fontSize * factor * 0.5));
penEnabled = new Pen(Color.Black, factor);
penDisabled = new Pen(Color.FromArgb(180, 180, 180), factor);
penHidden = new Pen(Color.FromArgb(220, 220, 220), factor);
if (documentType.Equals("CDXML"))
{
loadCDXML(doc);
}
else if (documentType.Equals("LipidStructure"))
{
((LipidCreatorStructureEditor)form).structureFile = file_name;
loadLipidStructure(doc);
}
else
{
throw new Exception("Unknown data format");
}

currentProjection = 0;
computeBonds();
changeFragment();
countNodeConnections();

penEnabled = new Pen(Color.Black, factor);
penDisabled = new Pen(Color.FromArgb(180, 180, 180), factor);
penHidden = new Pen(Color.FromArgb(220, 220, 220), factor);
}


Expand All @@ -555,6 +577,7 @@ public void loadLipidStructure(XDocument doc)
StructureNode sn = new StructureNode(this, element);
idToNode.Add(sn.id, sn);
nodes.Add(sn);
nodeIds = Math.Max(nodeIds, sn.id + 1);
}

foreach (var element in doc.Element("LipidStructure").Elements().Where(el => el.Name.LocalName.Equals("AdditionalNodes")).Elements().Where(el => el.Name.LocalName.Equals("NodeID")))
Expand All @@ -577,6 +600,26 @@ public void loadLipidStructure(XDocument doc)
int id = Convert.ToInt32(element.Attribute("id").Value);
additionalBonds.Add(bond_dict[id]);
}



foreach (var element in doc.Element("LipidStructure").Elements().Where(el => el.Name.LocalName.Equals("PositiveFragments")).Elements().Where(el => el.Name.LocalName.Equals("LipidStructureFragment")))
{
LipidStructureFragment fragment = new LipidStructureFragment(element);
positiveFragments.Add(fragment.fragmentName, fragment);
}

foreach (var element in doc.Element("LipidStructure").Elements().Where(el => el.Name.LocalName.Equals("NegativeFragments")).Elements().Where(el => el.Name.LocalName.Equals("LipidStructureFragment")))
{
LipidStructureFragment fragment = new LipidStructureFragment(element);
negativeFragments.Add(fragment.fragmentName, fragment);
}

nodeFont = new Font("Arial", fontSize * factor);
decoratorFont = new Font("Arial", (float)(fontSize * factor * 0.5));

bondIds = bonds.Count + 1;
projectionIds = negativeFragments.Count + positiveFragments.Count + 1;
}


Expand Down Expand Up @@ -645,7 +688,7 @@ public void loadCDXML(XDocument doc)
idToNode.Add(nodeId, sn);
}

currentNodeId = Math.Max(currentNodeId, nodeId);
nodeIds = Math.Max(nodeIds, nodeId + 1);
}
catch(Exception ex){
Console.WriteLine(ex);
Expand Down Expand Up @@ -697,7 +740,7 @@ public void loadCDXML(XDocument doc)
// get the edge color
bool isDoubleBond = ((string)edge.Attribute("Order") != null) && edge.Attribute("Order").Value.ToString().Equals("2");

bond = new Bond(this, bondIDs++, idB, idE, isDoubleBond);
bond = new Bond(this, bondIds++, idB, idE, isDoubleBond);
bonds.Add(bond);
}
catch(Exception){}
Expand Down Expand Up @@ -728,6 +771,9 @@ public void loadCDXML(XDocument doc)
float offsetY = /* (float)form.Size.Height / 2.0f */ - midY * factor;


nodeFont = new Font("Arial", fontSize * factor);
decoratorFont = new Font("Arial", (float)(fontSize * factor * 0.5));

foreach (var node in nodes)
{
float x = node.position.X * factor + offsetX;
Expand Down Expand Up @@ -976,15 +1022,15 @@ public void addNode(SPointF pos)
float w = size.Width * 0.9f;
float h = size.Height * 0.9f;
RectangleF drawRect = new RectangleF(pos.X - w * 0.5f, pos.Y - h * 0.5f, w, h);
StructureNode sn = new StructureNode(this, ++currentNodeId, pos, drawRect, "C");
StructureNode sn = new StructureNode(this, nodeIds, pos, drawRect, "C");


int fragId = currentFragment.id;
sn.nodeProjections.Add(fragId, new NodeProjection(fragId == currentProjection ? NodeState.Enabled : NodeState.Hidden));

nodes.Add(sn);
additionalNodes.Add(sn);
idToNode.Add(currentNodeId, sn);
idToNode.Add(nodeIds++, sn);

computeBonds();
}
Expand Down Expand Up @@ -1012,7 +1058,7 @@ public StructureNode removeNode(StructureNode node)
public void addBond(StructureNode start, StructureNode end)
{
if (currentProjection == 0) return;
Bond bond = new Bond(this, bondIDs++, 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);
Expand Down
9 changes: 9 additions & 0 deletions LipidCreator/StructureEditor/StructureEditor.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

103 changes: 72 additions & 31 deletions LipidCreator/StructureEditor/StructureEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public partial class LipidCreatorStructureEditor : Form
public static double ELECTRON_REST_MASS = 0.00054857990946;
public const string FRAGMENT_LABEL = "fragment";
public bool semaphore = false;
public string structureFile = "";


public LipidCreatorStructureEditor()
Expand All @@ -39,11 +40,11 @@ public LipidCreatorStructureEditor()
InitializeComponent();
this.DoubleBuffered = true;

/*

using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = "c:\\";
openFileDialog.Filter = "txt files (*.cdxml)|*.cdxml|(*.stXL)|*.stXL";
openFileDialog.Filter = "chemdraw file (*.cdxml)|*.cdxml|structure file (*.stXL)|*.stXL";
openFileDialog.FilterIndex = 2;
openFileDialog.RestoreDirectory = true;

Expand All @@ -52,35 +53,46 @@ public LipidCreatorStructureEditor()
//Get the path of specified file
string filePath = openFileDialog.FileName;

try
{
lipidStructure = new LipidStructure(filePath, this);
}
catch
{
MessageBox.Show("An error happened, please speak with Dominik and explain how you caused the error.", "Error happened");
Environment.Exit(-1);
}
Console.WriteLine(filePath);
}
else
{
Environment.Exit(0);
}
}
*/


if (true)
foreach (var kvp in lipidStructure.positiveFragments)
{
string file = "foo.stXL";
lipidStructure = new LipidStructure(file, this);
positiveFragmentsListBox.Items.Add(kvp.Value.fragmentName);
}
else
{
string file = "/home/dominik/workspace/src/LipidCreator/LipidCreator/data/structures/PC genNeg.cdxml";
lipidStructure = new LipidStructure(file, this);
positiveFragmentsListBox.Items.Add("HG 164");
lipidStructure.addFragment("HG 164", true);

positiveFragmentsListBox.Items.Add("HG 181");
lipidStructure.addFragment("HG 181", true);

negativeFragmentsListBox.Items.Add("HG -OH");
lipidStructure.addFragment("HG -OH", false);


lipidStructure.serialize("foo.stXL");
foreach (var kvp in lipidStructure.negativeFragments)
{
negativeFragmentsListBox.Items.Add(kvp.Value.fragmentName);
}

/*
string file = "/home/dominik/workspace/src/LipidCreator/LipidCreator/data/structures/PC genNeg.cdxml";
lipidStructure = new LipidStructure(file, this);
positiveFragmentsListBox.Items.Add("HG 164");
lipidStructure.addFragment("HG 164", true);
positiveFragmentsListBox.Items.Add("HG 181");
lipidStructure.addFragment("HG 181", true);
negativeFragmentsListBox.Items.Add("HG -OH");
lipidStructure.addFragment("HG -OH", false);
*/

computeFragmentMass(null, null);
}

Expand Down Expand Up @@ -116,9 +128,8 @@ private void DrawScene(Graphics g)
if (currentBond != null)
{
Pen pen = new Pen(Color.DeepSkyBlue, 2);
int xb = (int)((currentBond.edgeSingle.start.X + currentBond.edgeSingle.end.X) * 0.5);
int yb = (int)((currentBond.edgeSingle.start.Y + currentBond.edgeSingle.end.Y) * 0.5);
g.DrawEllipse(pen, xb - cursorCircleRadius, yb - cursorCircleRadius, cursorCircleRadius * 2, cursorCircleRadius * 2);
SPointF p = (currentBond.edgeSingle.start + currentBond.edgeSingle.end) / 2.0f + lipidStructure.middlePoint;
g.DrawEllipse(pen, p.X - cursorCircleRadius, p.Y - cursorCircleRadius, cursorCircleRadius * 2, cursorCircleRadius * 2);
}
}

Expand Down Expand Up @@ -198,6 +209,7 @@ private void mouseUp(Object sender, MouseEventArgs e)
}
else if (action == Action.ChangeBond && currentBond != null)
{
Console.WriteLine(currentBond);
currentBond.toggleState();
lipidStructure.computeBonds();
updateStructure();
Expand Down Expand Up @@ -239,7 +251,7 @@ private void mouseUp(Object sender, MouseEventArgs e)
}
else if (action == Action.ChangeBond && currentBond != null)
{
currentBond.toggleState();
currentBond.toggleState();
lipidStructure.computeBonds();
updateStructure();
}
Expand Down Expand Up @@ -413,9 +425,9 @@ private void mouseMove(Object sender, MouseEventArgs e)
double minDistC = 1e10;
foreach (var bond in lipidStructure.bonds)
{
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);
SPointF b = (bond.edgeSingle.start + bond.edgeSingle.end) / 2.0f + lipidStructure.middlePoint - mouse;

double dist = Math.Pow(b.X, 2) + Math.Pow(b.Y, 2);
if (dist <= Math.Pow(10 + cursorCircleRadius, 2) && dist < minDistC)
{
minDistC = dist;
Expand Down Expand Up @@ -596,7 +608,9 @@ private void positiveFragmentDoubleClicked(Object sender, EventArgs e)
string newFragmentName = InputBox.Show("Please write a new fragment name:", "New fragment name", currentFragmentName);
if (newFragmentName.Length == 0 || newFragmentName.Equals(currentFragmentName) || lipidStructure.positiveFragments.ContainsKey(newFragmentName)) return;

lipidStructure.positiveFragments.Add(newFragmentName, lipidStructure.positiveFragments[currentFragmentName]);
LipidStructureFragment fragment = lipidStructure.positiveFragments[currentFragmentName];
fragment.fragmentName = newFragmentName;
lipidStructure.positiveFragments.Add(newFragmentName, fragment);
lipidStructure.positiveFragments.Remove(currentFragmentName);
positiveFragmentsListBox.Items[selectedIndex] = newFragmentName;
}
Expand All @@ -614,7 +628,9 @@ private void negativeFragmentDoubleClicked(Object sender, EventArgs e)
string newFragmentName = InputBox.Show("Please write a new fragment name:", "New fragment name", currentFragmentName);
if (newFragmentName.Length == 0 || newFragmentName.Equals(currentFragmentName) || lipidStructure.negativeFragments.ContainsKey(newFragmentName)) return;

lipidStructure.negativeFragments.Add(newFragmentName, lipidStructure.negativeFragments[currentFragmentName]);
LipidStructureFragment fragment = lipidStructure.negativeFragments[currentFragmentName];
fragment.fragmentName = newFragmentName;
lipidStructure.negativeFragments.Add(newFragmentName, fragment);
lipidStructure.negativeFragments.Remove(currentFragmentName);
negativeFragmentsListBox.Items[selectedIndex] = newFragmentName;
}
Expand Down Expand Up @@ -668,6 +684,31 @@ public void updateStructure()



public void saveStructure(Object sender, EventArgs e)
{
if (structureFile.Length == 0)
{
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
saveFileDialog.InitialDirectory = "c:\\";
saveFileDialog.Filter = "structure file (*.stXL)|*.stXL";
saveFileDialog.FilterIndex = 0;
saveFileDialog.RestoreDirectory = true;
saveFileDialog.ShowDialog();

structureFile = saveFileDialog.FileName;
}
}

if (structureFile.Length > 0)
{
lipidStructure.serialize(structureFile);
MessageBox.Show("The structure was saved.", "Structure saved");
}
}



private void addPositiveFragment(Object sender, EventArgs e)
{
if (!lipidStructure.positiveFragments.ContainsKey(FRAGMENT_LABEL))
Expand Down

0 comments on commit 6391afe

Please sign in to comment.