private void ProcessBondsBlock(int lineCount, IAtomContainer container) { for (int i = 0; i < lineCount; i++) { string line = input.ReadLine(); int atom1 = int.Parse(line.Substring(10, 3).Trim(), NumberFormatInfo.InvariantInfo) - 1; int atom2 = int.Parse(line.Substring(16, 3).Trim(), NumberFormatInfo.InvariantInfo) - 1; if (container.GetBond(container.Atoms[atom1], container.Atoms[atom2]) == null) { IBond bond = container.Builder.NewBond(container.Atoms[atom1], container.Atoms[atom2]); int order = int.Parse(line.Substring(23).Trim(), NumberFormatInfo.InvariantInfo); bond.Order = BondManipulator.CreateBondOrder((double)order); container.Bonds.Add(bond); } // else: bond already present; CTX store the bonds twice } }
public override void CharacterData(CMLStack xpath, XElement element) { string s = element.Value; if (isBond) { Debug.WriteLine($"CharData (bond): {s}"); var st = Strings.Tokenize(s); foreach (var border in st) { Debug.WriteLine($"new bond order: {border}"); // assume cdk bond object has already started // cdo.SetObjectProperty("Bond", "order", border); CurrentBond.Order = BondManipulator.CreateBondOrder(double.Parse(border, NumberFormatInfo.InvariantInfo)); } } else { base.CharacterData(xpath, element); } }
/// <summary> /// Generates a random structure based on the atoms in the given <see cref="IAtomContainer"/>. /// </summary> public IAtomContainer Generate() { int iteration = 0; bool structureFound = false; do { iteration++; atomContainer.RemoveAllElectronContainers(); bool bondFormed; do { bondFormed = false; foreach (var atom in atomContainer.Atoms) { if (!satCheck.IsSaturated(atom, atomContainer)) { var partner = GetAnotherUnsaturatedNode(atom); if (partner != null) { var cmax1 = satCheck.GetCurrentMaxBondOrder(atom, atomContainer); var cmax2 = satCheck.GetCurrentMaxBondOrder(partner, atomContainer); var max = Math.Min(cmax1, cmax2); var order = Math.Min(Math.Max(1.0, random.NextInt((int)Math.Round(max))), 3.0); Debug.WriteLine($"Forming bond of order {order}"); atomContainer.Bonds.Add(atomContainer.Builder.NewBond(atom, partner, BondManipulator.CreateBondOrder(order))); bondFormed = true; } } } } while (bondFormed); if (ConnectivityChecker.IsConnected(atomContainer) && satCheck.IsSaturated(atomContainer)) { structureFound = true; } } while (!structureFound && iteration < 20); Debug.WriteLine($"Structure found after #iterations: {iteration}"); return(atomContainer.Builder.NewAtomContainer(atomContainer)); }
/// <summary> /// Randomly chooses four atoms and alters the bonding /// pattern between them according to rules described /// in "Faulon, JCICS 1996, 36, 731". /// </summary> public virtual void Mutate(IAtomContainer ac) { Debug.WriteLine("RandomGenerator->Mutate() Start"); int nrOfAtoms = ac.Atoms.Count; int x1 = 0, x2 = 0, y1 = 0, y2 = 0; double a11 = 0, a12 = 0, a22 = 0, a21 = 0; double b11 = 0, lowerborder = 0, upperborder = 0; IAtom ax1 = null, ax2 = null, ay1 = null, ay2 = null; IBond b1 = null, b2 = null, b3 = null, b4 = null; int[] choices = new int[3]; int choiceCounter = 0; /* We need at least two non-zero bonds in order to be successful */ int nonZeroBondsCounter = 0; do { do { nonZeroBondsCounter = 0; /* Randomly choose four distinct atoms */ do { // this yields numbers between 0 and (nrOfAtoms - 1) x1 = (int)(random.NextDouble() * nrOfAtoms); x2 = (int)(random.NextDouble() * nrOfAtoms); y1 = (int)(random.NextDouble() * nrOfAtoms); y2 = (int)(random.NextDouble() * nrOfAtoms); Debug.WriteLine($"RandomGenerator->Mutate(): x1, x2, y1, y2: {x1}, {x2}, {y1}, {y2}"); } while (!(x1 != x2 && x1 != y1 && x1 != y2 && x2 != y1 && x2 != y2 && y1 != y2)); ax1 = ac.Atoms[x1]; ay1 = ac.Atoms[y1]; ax2 = ac.Atoms[x2]; ay2 = ac.Atoms[y2]; /* Get four bonds for these four atoms */ b1 = ac.GetBond(ax1, ay1); if (b1 != null) { a11 = BondManipulator.DestroyBondOrder(b1.Order); nonZeroBondsCounter++; } else { a11 = 0; } b2 = ac.GetBond(ax1, ay2); if (b2 != null) { a12 = BondManipulator.DestroyBondOrder(b2.Order); nonZeroBondsCounter++; } else { a12 = 0; } b3 = ac.GetBond(ax2, ay1); if (b3 != null) { a21 = BondManipulator.DestroyBondOrder(b3.Order); nonZeroBondsCounter++; } else { a21 = 0; } b4 = ac.GetBond(ax2, ay2); if (b4 != null) { a22 = BondManipulator.DestroyBondOrder(b4.Order); nonZeroBondsCounter++; } else { a22 = 0; } Debug.WriteLine($"RandomGenerator->Mutate()->The old bond orders: a11, a12, a21, a22: {a11}, {a12}, {a21}, {a22}"); } while (nonZeroBondsCounter < 2); /* Compute the range for b11 (see Faulons formulae for details) */ double[] cmax = { 0, a11 - a22, a11 + a12 - 3, a11 + a21 - 3 }; double[] cmin = { 3, a11 + a12, a11 + a21, a11 - a22 + 3 }; lowerborder = MathTools.Max(cmax); upperborder = MathTools.Min(cmin); /* Randomly choose b11 != a11 in the range max > r > min */ Debug.WriteLine("*** New Try ***"); Debug.WriteLine($"a11 = {a11}"); Debug.WriteLine($"upperborder = {upperborder}"); Debug.WriteLine($"lowerborder = {lowerborder}"); choiceCounter = 0; for (double f = lowerborder; f <= upperborder; f++) { if (f != a11) { choices[choiceCounter] = (int)f; choiceCounter++; } } if (choiceCounter > 0) { b11 = choices[(int)(random.NextDouble() * choiceCounter)]; } Debug.WriteLine($"b11 = {b11}"); } while (!(b11 != a11 && (b11 >= lowerborder && b11 <= upperborder))); var b12 = a11 + a12 - b11; var b21 = a11 + a21 - b11; var b22 = a22 - a11 + b11; if (b11 > 0) { if (b1 == null) { b1 = ac.Builder.NewBond(ax1, ay1, BondManipulator.CreateBondOrder(b11)); ac.Bonds.Add(b1); } else { b1.Order = BondManipulator.CreateBondOrder(b11); } } else if (b1 != null) { ac.Bonds.Remove(b1); } if (b12 > 0) { if (b2 == null) { b2 = ac.Builder.NewBond(ax1, ay2, BondManipulator.CreateBondOrder(b12)); ac.Bonds.Add(b2); } else { b2.Order = BondManipulator.CreateBondOrder(b12); } } else if (b2 != null) { ac.Bonds.Remove(b2); } if (b21 > 0) { if (b3 == null) { b3 = ac.Builder.NewBond(ax2, ay1, BondManipulator.CreateBondOrder(b21)); ac.Bonds.Add(b3); } else { b3.Order = BondManipulator.CreateBondOrder(b21); } } else if (b3 != null) { ac.Bonds.Remove(b3); } if (b22 > 0) { if (b4 == null) { b4 = ac.Builder.NewBond(ax2, ay2, BondManipulator.CreateBondOrder(b22)); ac.Bonds.Add(b4); } else { b4.Order = BondManipulator.CreateBondOrder(b22); } } else if (b4 != null) { ac.Bonds.Remove(b4); } Debug.WriteLine($"a11 a12 a21 a22: {a11} {a12} {a21} {a22}"); Debug.WriteLine($"b11 b12 b21 b22: {b11} {b12} {b21} {b22}"); }
/// <summary> /// Reads the bond atoms, order and stereo configuration. /// </summary> public void ReadBondBlock(IAtomContainer readData) { Trace.TraceInformation("Reading BOND block"); bool foundEND = false; while (!foundEND) { string command = ReadCommand(ReadLine()); if (string.Equals("END BOND", command, StringComparison.Ordinal)) { foundEND = true; } else { Debug.WriteLine($"Parsing bond from: {command}"); var tokenizer = Strings.Tokenize(command).GetEnumerator(); IBond bond = readData.Builder.NewBond(); // parse the index try { tokenizer.MoveNext(); string indexString = tokenizer.Current; bond.Id = indexString; } catch (Exception exception) { string error = "Error while parsing bond index"; Trace.TraceError(error); Debug.WriteLine(exception); throw new CDKException(error, exception); } // parse the order try { tokenizer.MoveNext(); string orderString = tokenizer.Current; int order = int.Parse(orderString, NumberFormatInfo.InvariantInfo); if (order >= 4) { Trace.TraceWarning("Query order types are not supported (yet). File a bug if you need it"); } else { bond.Order = BondManipulator.CreateBondOrder((double)order); } } catch (Exception exception) { string error = "Error while parsing bond index"; Trace.TraceError(error); Debug.WriteLine(exception); throw new CDKException(error, exception); } // parse index atom 1 try { tokenizer.MoveNext(); string indexAtom1String = tokenizer.Current; int indexAtom1 = int.Parse(indexAtom1String, NumberFormatInfo.InvariantInfo); IAtom atom1 = readData.Atoms[indexAtom1 - 1]; bond.Atoms.Add(atom1); // bond.Atoms[0] } catch (Exception exception) { string error = "Error while parsing index atom 1 in bond"; Trace.TraceError(error); Debug.WriteLine(exception); throw new CDKException(error, exception); } // parse index atom 2 try { tokenizer.MoveNext(); string indexAtom2String = tokenizer.Current; int indexAtom2 = int.Parse(indexAtom2String, NumberFormatInfo.InvariantInfo); IAtom atom2 = readData.Atoms[indexAtom2 - 1]; bond.Atoms.Add(atom2); // bond.Atoms[1] } catch (Exception exception) { string error = "Error while parsing index atom 2 in bond"; Trace.TraceError(error); Debug.WriteLine(exception); throw new CDKException(error, exception); } var endpts = new List <IAtom>(); string attach = null; // the rest are key=value fields if (command.IndexOf('=') != -1) { var options = ParseOptions(ExhaustStringTokenizer(tokenizer)); foreach (var key in options.Keys) { string value = options[key]; try { switch (key) { case "CFG": int configuration = int.Parse(value, NumberFormatInfo.InvariantInfo); if (configuration == 0) { bond.Stereo = BondStereo.None; } else if (configuration == 1) { bond.Stereo = BondStereo.Up; } else if (configuration == 2) { bond.Stereo = BondStereo.None; } else if (configuration == 3) { bond.Stereo = BondStereo.Down; } break; case "ENDPTS": string[] endptStr = value.Split(' '); // skip first value that is count for (int i = 1; i < endptStr.Length; i++) { endpts.Add(readData.Atoms[int.Parse(endptStr[i], NumberFormatInfo.InvariantInfo) - 1]); } break; case "ATTACH": attach = value; break; default: Trace.TraceWarning("Not parsing key: " + key); break; } } catch (Exception exception) { string error = "Error while parsing key/value " + key + "=" + value + ": " + exception.Message; Trace.TraceError(error); Debug.WriteLine(exception); throw new CDKException(error, exception); } } } // storing bond readData.Bonds.Add(bond); // storing positional variation if (string.Equals("ANY", attach, StringComparison.Ordinal)) { Sgroup sgroup = new Sgroup { Type = SgroupType.ExtMulticenter }; sgroup.Atoms.Add(bond.Begin); // could be other end? sgroup.Bonds.Add(bond); foreach (var endpt in endpts) { sgroup.Atoms.Add(endpt); } var sgroups = readData.GetCtabSgroups(); if (sgroups == null) { readData.SetCtabSgroups(sgroups = new List <Sgroup>(4)); } sgroups.Add(sgroup); } Debug.WriteLine($"Added bond: {bond}"); } } }
internal IAtomContainer Generate2(IChemObjectSet <IAtomContainer> atomContainers) { int iteration = 0; bool structureFound = false; do { iteration++; bool bondFormed; do { bondFormed = false; var atomContainersArray = atomContainers.ToList(); for (var atomContainersArrayIndex = 0; atomContainersArrayIndex < atomContainersArray.Count; atomContainersArrayIndex++) { var ac = atomContainersArray[atomContainersArrayIndex]; if (ac == null) { continue; } var atoms = ac.Atoms.ToList(); // ToList is required because some atoms are added to ac.Atoms in the loop. foreach (var atom in atoms) { if (!satCheck.IsSaturated(atom, ac)) { var partner = GetAnotherUnsaturatedNode(atom, ac, atomContainers); if (partner != null) { var toadd = AtomContainerSetManipulator.GetRelevantAtomContainer(atomContainers, partner); var cmax1 = satCheck.GetCurrentMaxBondOrder(atom, ac); var cmax2 = satCheck.GetCurrentMaxBondOrder(partner, toadd); var max = Math.Min(cmax1, cmax2); var order = Math.Min(Math.Max(1, max), 3); //(double)Math.Round(Math.Random() * max) Debug.WriteLine($"cmax1, cmax2, max, order: {cmax1}, {cmax2}, {max}, {order}"); if (toadd != ac) { var indexToRemove = atomContainersArray.IndexOf(toadd); if (indexToRemove != -1) { atomContainersArray[indexToRemove] = null; } atomContainers.Remove(toadd); ac.Add(toadd); } ac.Bonds.Add(ac.Builder.NewBond(atom, partner, BondManipulator.CreateBondOrder(order))); bondFormed = true; } } } } } while (bondFormed); if (atomContainers.Count == 1 && satCheck.IsSaturated(atomContainers[0])) { structureFound = true; } } while (!structureFound && iteration < 5); if (atomContainers.Count == 1 && satCheck.IsSaturated(atomContainers[0])) { structureFound = true; } if (!structureFound) { return(null); } return(atomContainers[0]); }
private static IAtomContainer Change(IAtomContainer ac, int x1, int y1, int x2, int y2, double b11, double b12, double b21, double b22) { IAtom ax1 = null, ax2 = null, ay1 = null, ay2 = null; IBond b1 = null, b2 = null, b3 = null, b4 = null; try { ax1 = ac.Atoms[x1]; ax2 = ac.Atoms[x2]; ay1 = ac.Atoms[y1]; ay2 = ac.Atoms[y2]; } catch (Exception exc) { Debug.WriteLine(exc); } b1 = ac.GetBond(ax1, ay1); b2 = ac.GetBond(ax1, ay2); b3 = ac.GetBond(ax2, ay1); b4 = ac.GetBond(ax2, ay2); if (b11 > 0) { if (b1 == null) { Debug.WriteLine("no bond " + x1 + "-" + y1 + ". Adding it with order " + b11); b1 = ac.Builder.NewBond(ax1, ay1, BondManipulator.CreateBondOrder(b11)); ac.Bonds.Add(b1); } else { b1.Order = BondManipulator.CreateBondOrder(b11); Debug.WriteLine("Setting bondorder for " + x1 + "-" + y1 + " to " + b11); } } else if (b1 != null) { ac.Bonds.Remove(b1); Debug.WriteLine("removing bond " + x1 + "-" + y1); } if (b12 > 0) { if (b2 == null) { Debug.WriteLine("no bond " + x1 + "-" + y2 + ". Adding it with order " + b12); b2 = ac.Builder.NewBond(ax1, ay2, BondManipulator.CreateBondOrder(b12)); ac.Bonds.Add(b2); } else { b2.Order = BondManipulator.CreateBondOrder(b12); Debug.WriteLine("Setting bondorder for " + x1 + "-" + y2 + " to " + b12); } } else if (b2 != null) { ac.Bonds.Remove(b2); Debug.WriteLine("removing bond " + x1 + "-" + y2); } if (b21 > 0) { if (b3 == null) { Debug.WriteLine("no bond " + x2 + "-" + y1 + ". Adding it with order " + b21); b3 = ac.Builder.NewBond(ax2, ay1, BondManipulator.CreateBondOrder(b21)); ac.Bonds.Add(b3); } else { b3.Order = BondManipulator.CreateBondOrder(b21); Debug.WriteLine("Setting bondorder for " + x2 + "-" + y1 + " to " + b21); } } else if (b3 != null) { ac.Bonds.Remove(b3); Debug.WriteLine("removing bond " + x2 + "-" + y1); } if (b22 > 0) { if (b4 == null) { Debug.WriteLine("no bond " + x2 + "-" + y2 + ". Adding it with order " + b22); b4 = ac.Builder.NewBond(ax2, ay2, BondManipulator.CreateBondOrder(b22)); ac.Bonds.Add(b4); } else { b4.Order = BondManipulator.CreateBondOrder(b22); Debug.WriteLine("Setting bondorder for " + x2 + "-" + y2 + " to " + b22); } } else if (b4 != null) { ac.Bonds.Remove(b4); Debug.WriteLine("removing bond " + x2 + "-" + y2); } return(ac); }