public void SaturateRingSystems(IAtomContainer atomContainer) { var rs0 = Cycles.FindSSSR(atomContainer.Builder.NewAtomContainer(atomContainer)).ToRingSet(); var ringSets = RingPartitioner.PartitionRings(rs0); IAtom atom = null; foreach (var rs in ringSets) { var containers = RingSetManipulator.GetAllAtomContainers(rs); foreach (var ac in containers) { var temp = new int[ac.Atoms.Count]; for (int g = 0; g < ac.Atoms.Count; g++) { atom = ac.Atoms[g]; temp[g] = atom.ImplicitHydrogenCount.Value; atom.ImplicitHydrogenCount = (atomContainer.GetConnectedBonds(atom).Count() - ac.GetConnectedBonds(atom).Count() - temp[g]); } Saturate(ac); for (int g = 0; g < ac.Atoms.Count; g++) { atom = ac.Atoms[g]; atom.ImplicitHydrogenCount = temp[g]; } } } }
/// <summary> /// Method assigns certain properties to an atom. Necessary for the atom type matching /// Properties: /// <list type="bullet"> /// <item>aromaticity</item> /// <item>ChemicalGroup (CDKChemicalRingGroupConstant)</item> /// <item> /// <item>SSSR</item> /// <item>Ring/Group, ringSize, aromaticity</item> /// <item>SphericalMatcher (HoSe Code)</item> /// </item> /// </list> /// </summary> /// <param name="molecule"></param> /// <param name="aromaticity"><see langword="true"/> if aromaticity should be calculated</param> /// <returns>sssrf ring set of the molecule</returns> public static IRingSet AssignAtomTypePropertiesToAtom(IAtomContainer molecule, bool aromaticity) { var sg = new SmilesGenerator(); Debug.WriteLine("assignAtomTypePropertiesToAtom Start ..."); string hoseCode = ""; var ringSetMolecule = Cycles.FindSSSR(molecule).ToRingSet(); Debug.WriteLine(ringSetMolecule); if (aromaticity) { try { Aromaticity.CDKLegacy.Apply(molecule); } catch (Exception cdk1) { Trace.TraceError($"AROMATICITYError: Cannot determine aromaticity due to: {cdk1.ToString()}"); } } for (int i = 0; i < molecule.Atoms.Count; i++) { // FIXME: remove casting var atom2 = molecule.Atoms[i]; //Atom aromatic is set by HueckelAromaticityDetector //Atom in ring? if (ringSetMolecule.Contains(atom2)) { var ringSetA = ringSetMolecule.Builder.NewRingSet(); ringSetA.AddRange(ringSetMolecule.GetRings(atom2)); RingSetManipulator.Sort(ringSetA); var sring = ringSetA.Last(); atom2.SetProperty(CDKPropertyName.PartOfRingOfSize, sring.RingSize); atom2.SetProperty( CDKPropertyName.ChemicalGroupConstant, RingSystemClassifier(sring, GetSubgraphSmiles(sring, molecule))); atom2.IsInRing = true; atom2.IsAliphatic = false; } else { atom2.SetProperty(CDKPropertyName.ChemicalGroupConstant, NotInRing); atom2.IsInRing = false; atom2.IsAliphatic = true; } try { hoseCode = hcg.GetHOSECode(molecule, atom2, 3); hoseCode = RemoveAromaticityFlagsFromHoseCode(hoseCode); atom2.SetProperty(CDKPropertyName.SphericalMatcher, hoseCode); } catch (CDKException ex1) { throw new CDKException($"Could not build HOSECode from atom {i} due to {ex1.ToString()}", ex1); } } return(ringSetMolecule); }
public virtual void saturateRingSystems(IAtomContainer atomContainer) { IRingSet rs = new SSSRFinder(atomContainer.Builder.newMolecule(atomContainer)).findSSSR(); System.Collections.ArrayList ringSets = RingPartitioner.partitionRings(rs); IAtomContainer ac = null; IAtom atom = null; int[] temp; for (int f = 0; f < ringSets.Count; f++) { rs = (IRingSet)ringSets[f]; ac = RingSetManipulator.getAllInOneContainer(rs); temp = new int[ac.AtomCount]; for (int g = 0; g < ac.AtomCount; g++) { atom = ac.getAtomAt(g); temp[g] = atom.getHydrogenCount(); atom.setHydrogenCount(atomContainer.getBondCount(atom) - ac.getBondCount(atom) - temp[g]); } saturate(ac); for (int g = 0; g < ac.AtomCount; g++) { atom = ac.getAtomAt(g); atom.setHydrogenCount(temp[g]); } } }
/// <summary> Uses precomputed set of ALL rings and performs an aromaticity detection /// based on Hueckels 4n + 2 rule. /// /// </summary> /// <param name="ringSet"> set of ALL rings /// </param> /// <param name="removeAromaticityFlags"> Leaves ChemObjects that are already marked as /// aromatic as they are /// </param> /// <param name="atomContainer"> AtomContainer to be searched for rings /// </param> /// <returns> True, if molecules contains an /// aromatic feature /// </returns> public static bool detectAromaticity(IAtomContainer atomContainer, IRingSet ringSet, bool removeAromaticityFlags) { bool foundSomething = false; if (removeAromaticityFlags) { for (int f = 0; f < atomContainer.AtomCount; f++) { atomContainer.getAtomAt(f).setFlag(CDKConstants.ISAROMATIC, false); } for (int f = 0; f < atomContainer.ElectronContainerCount; f++) { IElectronContainer electronContainer = atomContainer.getElectronContainerAt(f); if (electronContainer is IBond) { electronContainer.setFlag(CDKConstants.ISAROMATIC, false); } } for (int f = 0; f < ringSet.AtomContainerCount; f++) { ((IRing)ringSet.getAtomContainer(f)).setFlag(CDKConstants.ISAROMATIC, false); } } IRing ring = null; RingSetManipulator.sort(ringSet); for (int f = 0; f < ringSet.AtomContainerCount; f++) { ring = (IRing)ringSet.getAtomContainer(f); //logger.debug("Testing for aromaticity in ring no ", f); if (AromaticityCalculator.isAromatic(ring, atomContainer)) { ring.setFlag(CDKConstants.ISAROMATIC, true); for (int g = 0; g < ring.AtomCount; g++) { ring.getAtomAt(g).setFlag(CDKConstants.ISAROMATIC, true); } for (int g = 0; g < ring.ElectronContainerCount; g++) { IElectronContainer electronContainer = ring.getElectronContainerAt(g); if (electronContainer is IBond) { electronContainer.setFlag(CDKConstants.ISAROMATIC, true); } } foundSomething = true; //logger.debug("This ring is aromatic: ", f); } else { //logger.debug("This ring is *not* aromatic: ", f); } } return(foundSomething); }
/// <summary> /// Layout the molecule, starts with ring systems and than aliphatic chains. /// </summary> /// <param name="ringSetMolecule">ringSystems of the molecule</param> private void LayoutMolecule(IReadOnlyList <IRingSet> ringSetMolecule, IAtomContainer molecule, AtomPlacer3D ap3d, AtomTetrahedralLigandPlacer3D atlp3d, AtomPlacer atomPlacer) { //Debug.WriteLine("****** LAYOUT MOLECULE MAIN *******"); IAtomContainer ac = null; int safetyCounter = 0; IAtom atom = null; //Place rest Chains/Atoms do { safetyCounter++; atom = ap3d.GetNextPlacedHeavyAtomWithUnplacedRingNeighbour(molecule); if (atom != null) { //Debug.WriteLine("layout RingSystem..."); var unplacedAtom = ap3d.GetUnplacedRingHeavyAtom(molecule, atom); var ringSetA = GetRingSetOfAtom(ringSetMolecule, unplacedAtom); var ringSetAContainer = RingSetManipulator.GetAllInOneContainer(ringSetA); templateHandler.MapTemplates(ringSetAContainer, ringSetAContainer.Atoms.Count); if (CheckAllRingAtomsHasCoordinates(ringSetAContainer)) { } else { throw new IOException("RingAtomLayoutError: Not every ring atom is placed! Molecule cannot be layout. Sorry"); } Vector3 firstAtomOriginalCoord = unplacedAtom.Point3D.Value; Vector3 centerPlacedMolecule = ap3d.GeometricCenterAllPlacedAtoms(molecule); SetBranchAtom(molecule, unplacedAtom, atom, ap3d.GetPlacedHeavyAtoms(molecule, atom), ap3d, atlp3d); LayoutRingSystem(firstAtomOriginalCoord, unplacedAtom, ringSetA, centerPlacedMolecule, atom, ap3d); SearchAndPlaceBranches(molecule, ringSetAContainer, ap3d, atlp3d, atomPlacer); //Debug.WriteLine("Ready layout Ring System"); ringSetA = null; unplacedAtom = null; } else { //Debug.WriteLine("layout chains..."); SetAtomsToUnVisited(molecule); atom = ap3d.GetNextPlacedHeavyAtomWithUnplacedAliphaticNeighbour(molecule); if (atom != null) { ac = atom.Builder.NewAtomContainer(); ac.Atoms.Add(atom); SearchAndPlaceBranches(molecule, ac, ap3d, atlp3d, atomPlacer); ac = null; } } } while (!ap3d.AllHeavyAtomsPlaced(molecule) || safetyCounter > molecule.Atoms.Count); }
/// <summary> /// Fixes Aromaticity of the molecule /// i.e. need to find rings and aromaticity again since added H's /// <param name="mol"></param> /// </summary> public static void Configure(IAtomContainer mol) { // need to find rings and aromaticity again since added H's IRingSet ringSet = null; try { var arf = new AllRingsFinder(); ringSet = arf.FindAllRings(mol); } catch (Exception e) { Console.Out.WriteLine(e.StackTrace); } try { // figure out which atoms are in aromatic rings: var cdk = CDK.HydrogenAdder; ExtAtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(mol); cdk.AddImplicitHydrogens(mol); Aromaticity.CDKLegacy.Apply(mol); // figure out which rings are aromatic: RingSetManipulator.MarkAromaticRings(ringSet); // figure out which simple (non cycles) rings are aromatic: // only atoms in 6 membered rings are aromatic // determine largest ring that each atom is a part of foreach (var atom in mol.Atoms) { atom.IsAromatic = false; foreach (var ring in ringSet) { if (!ring.IsAromatic) { continue; } bool haveatom = ring.Contains(atom); //Debug.WriteLine("haveatom="+haveatom); if (haveatom && ring.Atoms.Count == 6) { atom.IsAromatic = true; } } } } catch (Exception e) { Console.Out.WriteLine(e.StackTrace); } }
private static IAtomContainer GetAllInOneContainer(IRingSet ringSet) { var resultContainer = ringSet.Builder.NewAtomContainer(); var containers = RingSetManipulator.GetAllAtomContainers(ringSet); foreach (var container in containers) { resultContainer.Add(container); } return(resultContainer); }
/// <summary> /// Generate rendering Element(s) for the current bond, including ring /// elements if this bond is part of a ring. /// </summary> /// <param name="currentBond">the bond to use when generating elements</param> /// <param name="model">the renderer model</param> /// <returns>one or more rendering elements</returns> public virtual IRenderingElement Generate(IBond currentBond, RendererModel model) { IRing ring = RingSetManipulator.GetHeaviestRing(ringSet, currentBond); if (ring != null) { return(GenerateRingElements(currentBond, ring, model)); } else { return(GenerateBond(currentBond, model)); } }
public void TestMapTemplates_IAtomContainer_Double() { var ac = TestMoleculeFactory.MakeBicycloRings(); var th3d = TemplateHandler3D.Instance; var ffc = new ForceFieldConfigurator(); ffc.SetForceFieldConfigurator("mm2"); var ringSetMolecule = ffc.AssignAtomTyps(ac); var ringSystems = RingPartitioner.PartitionRings(ringSetMolecule); var largestRingSet = RingSetManipulator.GetLargestRingSet(ringSystems); var largestRingSetContainer = RingSetManipulator.GetAllInOneContainer(largestRingSet); th3d.MapTemplates(largestRingSetContainer, largestRingSetContainer.Atoms.Count); for (int i = 0; i < ac.Atoms.Count; i++) { Assert.IsNotNull(ac.Atoms[i].Point3D); } ModelBuilder3DTest.CheckAverageBondLength(ac); }
private static double GetRingMatchScore(IList <Object> list) { double lScore = 0; List <IAtom> listMap = (List <IAtom>)list[0]; IAtomContainer ac = (IAtomContainer)list[1]; HanserRingFinder ringFinder = new HanserRingFinder(); IRingSet rRings = null; try { rRings = ringFinder.GetRingSet(ac); } catch (CDKException ex) { Trace.TraceError(ex.Message); } RingSetManipulator.Sort(rRings); // Console.Out.WriteLine("Ring length " + ); lScore = GetRingMatch(rRings, listMap); return(lScore); }
public void TestMapTemplatesCyclicMol2() { TemplateHandler3D tmphandler3d = TemplateHandler3D.Instance; string cyclicMolSmi = "CC(C)(C)NC(=O)C1CN(CCN1CC(CC(Cc1ccccc1)C(=O)NC1c2ccccc2CC1O)O)Cc1cccnc1"; IChemObjectBuilder builder = ChemObjectBuilder.Instance; SmilesParser smiparser = new SmilesParser(builder); var molecule = smiparser.ParseSmiles(cyclicMolSmi); ForceFieldConfigurator forcefconf = new ForceFieldConfigurator(); forcefconf.SetForceFieldConfigurator("mmff94"); IRingSet rings = forcefconf.AssignAtomTyps(molecule); var ringSystems = RingPartitioner.PartitionRings(rings); IRingSet largestRingSet = RingSetManipulator.GetLargestRingSet(ringSystems); IAtomContainer allAtomsInOneContainer = RingSetManipulator.GetAllInOneContainer(largestRingSet); tmphandler3d.MapTemplates(allAtomsInOneContainer, allAtomsInOneContainer.Atoms.Count); for (int j = 0; j < allAtomsInOneContainer.Atoms.Count; j++) { Assert.IsNotNull(allAtomsInOneContainer.Atoms[j].Point3D); } }
public static void FixAromaticityForXLogP(IAtomContainer m) { // need to find rings and aromaticity again since added H's IRingSet rs = null; try { AllRingsFinder arf = new AllRingsFinder(); rs = arf.FindAllRings(m); // SSSRFinder s = new SSSRFinder(m); // srs = s.FindEssentialRings(); } catch (Exception e) { Console.Out.WriteLine(e.StackTrace); } try { // figure out which atoms are in aromatic rings: AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(m); Aromaticity.CDKLegacy.Apply(m); // figure out which rings are aromatic: RingSetManipulator.MarkAromaticRings(rs); // figure out which simple (non cycles) rings are aromatic: // HueckelAromaticityDetector.DetectAromaticity(m, srs); } catch (Exception e) { Console.Out.WriteLine(e.StackTrace); } // only atoms in 6 membered rings are aromatic // determine largest ring that each atom is a part of for (int i = 0; i <= m.Atoms.Count - 1; i++) { m.Atoms[i].IsAromatic = false; for (int j = 0; j <= rs.Count - 1; j++) { //Debug.WriteLine(i+"\t"+j); IRing r = (IRing)rs[j]; if (!r.IsAromatic) { goto continue_jloop; } bool haveatom = r.Contains(m.Atoms[i]); //Debug.WriteLine("haveatom="+haveatom); if (haveatom && r.Atoms.Count == 6) { m.Atoms[i].IsAromatic = true; } continue_jloop: ; } } }
public static void ExtractUniqueRingSystemsFromFile(string dataFile) { Console.Out.WriteLine("****** EXTRACT UNIQUE RING SYSTEMS ******"); Console.Out.WriteLine($"From file: {dataFile}"); Dictionary <string, string> hashRingSystems = new Dictionary <string, string>(); SmilesGenerator smilesGenerator = new SmilesGenerator(); int counterRings = 0; int counterMolecules = 0; int counterUniqueRings = 0; IRingSet ringSet = null; string key = ""; IAtomContainer ac = null; string molfile = dataFile + "_UniqueRings"; try { using (var fout = new FileStream(molfile, FileMode.Create)) using (var mdlw = new MDLV2000Writer(fout)) { try { Console.Out.WriteLine("Start..."); using (var fin = new StreamReader(dataFile)) using (var imdl = new EnumerableSDFReader(fin, builder)) { Console.Out.WriteLine("Read File in.."); foreach (var m in imdl) { counterMolecules = counterMolecules + 1; IRingSet ringSetM = Cycles.FindSSSR(m).ToRingSet(); if (counterMolecules % 1000 == 0) { Console.Out.WriteLine("Molecules:" + counterMolecules); } if (ringSetM.Count > 0) { var ringSystems = RingPartitioner.PartitionRings(ringSetM); for (int i = 0; i < ringSystems.Count; i++) { ringSet = (IRingSet)ringSystems[i]; ac = builder.NewAtomContainer(); var containers = RingSetManipulator.GetAllAtomContainers(ringSet); foreach (var container in containers) { ac.Add(container); } counterRings = counterRings + 1; // Only connection is important for (int j = 0; j < ac.Atoms.Count; j++) { (ac.Atoms[j]).Symbol = "C"; } try { key = smilesGenerator.Create(builder.NewAtomContainer(ac)); } catch (CDKException e) { Trace.TraceError(e.Message); return; } if (hashRingSystems.ContainsKey(key)) { } else { counterUniqueRings = counterUniqueRings + 1; hashRingSystems[key] = "1"; try { mdlw.Write(builder.NewAtomContainer(ac)); } catch (Exception emdl) { if (!(emdl is ArgumentException || emdl is CDKException)) { throw; } } } } } } } } catch (Exception exc) { Console.Out.WriteLine($"Could not read Molecules from file {dataFile} due to: {exc.Message}"); } } } catch (Exception ex2) { Console.Out.WriteLine($"IOError:cannot write file due to: {ex2.ToString()}"); } Console.Out.WriteLine($"READY Molecules:{counterMolecules} RingSystems:{counterRings} UniqueRingsSystem:{counterUniqueRings}"); Console.Out.WriteLine($"HashtableKeys:{hashRingSystems.Count}"); }
/// <summary> /// Get all paths of lengths 0 to the specified length. /// /// This method will find all paths upto length N starting from each atom in the molecule and return the unique set /// of such paths. /// </summary> /// <param name="container">The molecule to search</param> /// <returns>A map of path strings, keyed on themselves</returns> private static int[] FindPaths(IAtomContainer container) { var walker = new ShortestPathWalker(container); // convert paths to hashes var paths = new List <int>(); int patternIndex = 0; foreach (var s in walker.GetPaths()) { var toHashCode = Strings.GetJavaHashCode(s); paths.Insert(patternIndex, toHashCode); patternIndex++; } // Add ring information IRingSet sssr = Cycles.FindEssential(container).ToRingSet(); RingSetManipulator.Sort(sssr); foreach (var ring in sssr) { var toHashCode = Strings.GetJavaHashCode(ring.Atoms.Count.ToString(NumberFormatInfo.InvariantInfo)); paths.Insert(patternIndex, toHashCode); patternIndex++; } // Check for the charges var l = new List <string>(); foreach (var atom in container.Atoms) { var charge = atom.FormalCharge ?? 0; if (charge != 0) { l.Add(atom.Symbol + charge.ToString(NumberFormatInfo.InvariantInfo)); } } { l.Sort(); var toHashCode = Lists.GetHashCode(l); paths.Insert(patternIndex, toHashCode); patternIndex++; } l = new List <string>(); // atom stereo parity foreach (var atom in container.Atoms) { var st = atom.StereoParity; if (st != StereoAtomParities.Undefined) { l.Add(atom.Symbol + st.ToString(NumberFormatInfo.InvariantInfo)); } } { l.Sort(); var toHashCode = Lists.GetHashCode(l); paths.Insert(patternIndex, toHashCode); patternIndex++; } if (container.SingleElectrons.Count > 0) { var radicalInformation = new StringBuilder(); radicalInformation.Append("RAD: ").Append(container.SingleElectrons.Count); paths.Insert(patternIndex, Strings.GetJavaHashCode(radicalInformation.ToString())); patternIndex++; } if (container.LonePairs.Count > 0) { var lpInformation = new StringBuilder(); lpInformation.Append("LP: ").Append(container.LonePairs.Count); paths.Insert(patternIndex, Strings.GetJavaHashCode(lpInformation.ToString())); patternIndex++; } return(paths.ToArray()); }
/// <summary> /// Layout the ring system, rotate and translate the template. /// </summary> /// <param name="originalCoord">coordinates of the placedRingAtom from the template</param> /// <param name="placedRingAtom">placedRingAtom</param> /// <param name="ringSet">ring system which placedRingAtom is part of</param> /// <param name="centerPlacedMolecule">the geometric center of the already placed molecule</param> /// <param name="atomB">placed neighbour atom of placedRingAtom</param> private static void LayoutRingSystem(Vector3 originalCoord, IAtom placedRingAtom, IRingSet ringSet, Vector3 centerPlacedMolecule, IAtom atomB, AtomPlacer3D ap3d) { //Debug.WriteLine("****** Layout ring System ******");Console.Out.WriteLine(">around atom:"+molecule.Atoms.IndexOf(placedRingAtom)); IAtomContainer ac = RingSetManipulator.GetAllInOneContainer(ringSet); Vector3 newCoord = placedRingAtom.Point3D.Value; Vector3 axis = new Vector3(atomB.Point3D.Value.X - newCoord.X, atomB.Point3D.Value.Y - newCoord.Y, atomB.Point3D.Value.Z - newCoord.Z); TranslateStructure(originalCoord, newCoord, ac); //Rotate Ringsystem to farthest possible point Vector3 startAtomVector = new Vector3(newCoord.X - atomB.Point3D.Value.X, newCoord.Y - atomB.Point3D.Value.Y, newCoord.Z - atomB.Point3D.Value.Z); IAtom farthestAtom = ap3d.GetFarthestAtom(placedRingAtom.Point3D.Value, ac); Vector3 farthestAtomVector = new Vector3(farthestAtom.Point3D.Value.X - newCoord.X, farthestAtom.Point3D.Value.Y - newCoord.Y, farthestAtom.Point3D.Value.Z - newCoord.Z); Vector3 n1 = Vector3.Cross(axis, farthestAtomVector); n1 = Vector3.Normalize(n1); double lengthFarthestAtomVector = farthestAtomVector.Length(); Vector3 farthestVector = startAtomVector; farthestVector = Vector3.Normalize(farthestVector); farthestVector *= startAtomVector.Length() + lengthFarthestAtomVector; double dotProduct = Vector3.Dot(farthestAtomVector, farthestVector); double angle = Math.Acos(dotProduct / (farthestAtomVector.Length() * farthestVector.Length())); Vector3 ringCenter = new Vector3(); for (int i = 0; i < ac.Atoms.Count; i++) { if (!(ac.Atoms[i].IsPlaced)) { ringCenter.X = (ac.Atoms[i].Point3D).Value.X - newCoord.X; ringCenter.Y = (ac.Atoms[i].Point3D).Value.Y - newCoord.Y; ringCenter.Z = (ac.Atoms[i].Point3D).Value.Z - newCoord.Z; ringCenter = AtomTetrahedralLigandPlacer3D.Rotate(ringCenter, n1, angle); ac.Atoms[i].Point3D = new Vector3(ringCenter.X + newCoord.X, ringCenter.Y + newCoord.Y, ringCenter.Z + newCoord.Z); //ac.GetAtomAt(i).IsPlaced = true; } } //Rotate Ring so that geometric center is max from placed center //Debug.WriteLine("Rotate RINGSYSTEM"); Vector3 pointRingCenter = GeometryUtil.Get3DCenter(ac); double distance = 0; double rotAngleMax = 0; angle = 1 / 180 * Math.PI; ringCenter = new Vector3(pointRingCenter.X, pointRingCenter.Y, pointRingCenter.Z); ringCenter.X = ringCenter.X - newCoord.X; ringCenter.Y = ringCenter.Y - newCoord.Y; ringCenter.Z = ringCenter.Z - newCoord.Z; for (int i = 1; i < 360; i++) { ringCenter = AtomTetrahedralLigandPlacer3D.Rotate(ringCenter, axis, angle); if (Vector3.Distance(centerPlacedMolecule, new Vector3(ringCenter.X, ringCenter.Y, ringCenter.Z)) > distance) { rotAngleMax = i; distance = Vector3.Distance(centerPlacedMolecule, new Vector3(ringCenter.X, ringCenter.Y, ringCenter.Z)); } } //rotate ring around axis with best angle rotAngleMax = (rotAngleMax / 180) * Math.PI; for (int i = 0; i < ac.Atoms.Count; i++) { if (!(ac.Atoms[i].IsPlaced)) { ringCenter.X = (ac.Atoms[i].Point3D).Value.X; ringCenter.Y = (ac.Atoms[i].Point3D).Value.Y; ringCenter.Z = (ac.Atoms[i].Point3D).Value.Z; ringCenter = AtomTetrahedralLigandPlacer3D.Rotate(ringCenter, axis, rotAngleMax); ac.Atoms[i].Point3D = new Vector3(ringCenter.X, ringCenter.Y, ringCenter.Z); ac.Atoms[i].IsPlaced = true; } } }
/// <summary> /// This function finds rings and uses aromaticity detection code to /// aromatize the molecule. /// </summary> /// <param name="mol">input molecule</param> public static void AromatizeMolecule(IAtomContainer mol) { // need to find rings and aromaticity again since added H's IRingSet ringSet = null; try { AllRingsFinder arf = new AllRingsFinder(); ringSet = arf.FindAllRings(mol); // SSSRFinder s = new SSSRFinder(atomContainer); // srs = s.FindEssentialRings(); } catch (Exception e) { Console.Out.WriteLine(e.StackTrace); } try { // figure out which atoms are in aromatic rings: // PrintAtoms(atomContainer); ExtAtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(mol); // PrintAtoms(atomContainer); Aromaticity.CDKLegacy.Apply(mol); // PrintAtoms(atomContainer); // figure out which rings are aromatic: RingSetManipulator.MarkAromaticRings(ringSet); // PrintAtoms(atomContainer); // figure out which simple (non cycles) rings are aromatic: // HueckelAromaticityDetector.DetectAromaticity(atomContainer, srs); } catch (Exception e) { Console.Out.WriteLine(e.StackTrace); } // only atoms in 6 membered rings are aromatic // determine largest ring that each atom is atom part of for (int i = 0; i <= mol.Atoms.Count - 1; i++) { mol.Atoms[i].IsAromatic = false; foreach (var ring in ringSet) { if (!ring.IsAromatic) { continue; } bool haveatom = ring.Contains(mol.Atoms[i]); //Debug.WriteLine("haveatom="+haveatom); if (haveatom && ring.Atoms.Count == 6) { mol.Atoms[i].IsAromatic = true; } } } }
/// <summary> /// Generate 3D coordinates with force field information. /// </summary> public IAtomContainer Generate3DCoordinates(IAtomContainer molecule, bool clone) { var originalAtomTypeNames = molecule.Atoms.Select(n => n.AtomTypeName).ToArray(); Debug.WriteLine("******** GENERATE COORDINATES ********"); foreach (var atom in molecule.Atoms) { atom.IsPlaced = false; atom.IsVisited = false; } //CHECK FOR CONNECTIVITY! Debug.WriteLine($"#atoms>{molecule.Atoms.Count}"); if (!ConnectivityChecker.IsConnected(molecule)) { throw new CDKException("Molecule is NOT connected, could not layout."); } // setup helper classes AtomPlacer atomPlacer = new AtomPlacer(); AtomPlacer3D ap3d = new AtomPlacer3D(parameterSet); AtomTetrahedralLigandPlacer3D atlp3d = new AtomTetrahedralLigandPlacer3D(parameterSet); if (clone) { molecule = (IAtomContainer)molecule.Clone(); } atomPlacer.Molecule = molecule; if (ap3d.NumberOfUnplacedHeavyAtoms(molecule) == 1) { Debug.WriteLine("Only one Heavy Atom"); ap3d.GetUnplacedHeavyAtom(molecule).Point3D = new Vector3(0.0, 0.0, 0.0); try { atlp3d.Add3DCoordinatesForSinglyBondedLigands(molecule); } catch (CDKException ex3) { Trace.TraceError($"PlaceSubstitutensERROR: Cannot place substitutents due to:{ex3.Message}"); Debug.WriteLine(ex3); throw new CDKException("PlaceSubstitutensERROR: Cannot place substitutents due to:" + ex3.Message, ex3); } return(molecule); } //Assing Atoms to Rings,Aliphatic and Atomtype IRingSet ringSetMolecule = ffc.AssignAtomTyps(molecule); IRingSet largestRingSet = null; int numberOfRingAtoms = 0; IReadOnlyList <IRingSet> ringSystems = null; if (ringSetMolecule.Count > 0) { if (templateHandler == null) { throw new CDKException("You are trying to generate coordinates for a molecule with rings, but you have no template handler set. Please do SetTemplateHandler() before generation!"); } ringSystems = RingPartitioner.PartitionRings(ringSetMolecule); largestRingSet = RingSetManipulator.GetLargestRingSet(ringSystems); IAtomContainer largestRingSetContainer = RingSetManipulator.GetAllInOneContainer(largestRingSet); numberOfRingAtoms = largestRingSetContainer.Atoms.Count; templateHandler.MapTemplates(largestRingSetContainer, numberOfRingAtoms); if (!CheckAllRingAtomsHasCoordinates(largestRingSetContainer)) { throw new CDKException("RingAtomLayoutError: Not every ring atom is placed! Molecule cannot be layout."); } SetAtomsToPlace(largestRingSetContainer); SearchAndPlaceBranches(molecule, largestRingSetContainer, ap3d, atlp3d, atomPlacer); largestRingSet = null; } else { //Debug.WriteLine("****** Start of handling aliphatic molecule ******"); IAtomContainer ac = AtomPlacer.GetInitialLongestChain(molecule); SetAtomsToUnVisited(molecule); SetAtomsToUnplaced(molecule); ap3d.PlaceAliphaticHeavyChain(molecule, ac); //ZMatrixApproach ap3d.ZMatrixChainToCartesian(molecule, false); SearchAndPlaceBranches(molecule, ac, ap3d, atlp3d, atomPlacer); } LayoutMolecule(ringSystems, molecule, ap3d, atlp3d, atomPlacer); //Debug.WriteLine("******* PLACE SUBSTITUENTS ******"); try { atlp3d.Add3DCoordinatesForSinglyBondedLigands(molecule); } catch (CDKException ex3) { Trace.TraceError($"PlaceSubstitutensERROR: Cannot place substitutents due to:{ex3.Message}"); Debug.WriteLine(ex3); throw new CDKException("PlaceSubstitutensERROR: Cannot place substitutents due to:" + ex3.Message, ex3); } // restore the original atom type names for (int i = 0; i < originalAtomTypeNames.Length; i++) { molecule.Atoms[i].AtomTypeName = originalAtomTypeNames[i]; } return(molecule); }
/// <summary> /// Method assigns atom types to atoms (calculates sssr and aromaticity) /// </summary> /// <returns>sssrf set</returns> /// <exception cref="CDKException"> Problems detecting aromaticity or making hose codes.</exception> public IRingSet AssignAtomTyps(IAtomContainer molecule) { IAtom atom = null; string hoseCode = ""; HOSECodeGenerator hcg = new HOSECodeGenerator(); int NumberOfRingAtoms = 0; IRingSet ringSetMolecule = Cycles.FindSSSR(molecule).ToRingSet(); bool isInHeteroRing = false; try { AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(molecule); Aromaticity.CDKLegacy.Apply(molecule); } catch (Exception cdk1) { throw new CDKException("AROMATICITYError: Cannot determine aromaticity due to: " + cdk1.Message, cdk1); } for (int i = 0; i < molecule.Atoms.Count; i++) { atom = molecule.Atoms[i]; if (ringSetMolecule.Contains(atom)) { NumberOfRingAtoms = NumberOfRingAtoms + 1; atom.IsInRing = true; atom.IsAliphatic = false; var ringSetA = ringSetMolecule.GetRings(atom).ToList(); RingSetManipulator.Sort(ringSetA); IRing sring = (IRing)ringSetA[ringSetA.Count - 1]; atom.SetProperty("RING_SIZE", sring.RingSize); foreach (var ring in ringSetA) { if (IsHeteroRingSystem(ring)) { break; } } } else { atom.IsAliphatic = true; atom.IsInRing = false; isInHeteroRing = false; } atom.SetProperty("MAX_BOND_ORDER", molecule.GetMaximumBondOrder(atom).Numeric()); try { hoseCode = hcg.GetHOSECode(molecule, atom, 3); //Debug.WriteLine("HOSECODE GENERATION: ATOM "+i+" HoseCode: "+hoseCode+" "); } catch (CDKException ex1) { Console.Out.WriteLine("Could not build HOSECode from atom " + i + " due to " + ex1.ToString()); throw new CDKException("Could not build HOSECode from atom " + i + " due to " + ex1.ToString(), ex1); } try { ConfigureAtom(atom, hoseCode, isInHeteroRing); } catch (CDKException ex2) { Console.Out.WriteLine("Could not final configure atom " + i + " due to " + ex2.ToString()); throw new CDKException("Could not final configure atom due to problems with force field", ex2); } } // IBond[] bond = molecule.Bonds; string bondType; foreach (var bond in molecule.Bonds) { //Debug.WriteLine("bond[" + i + "] properties : " + molecule.Bonds[i].GetProperties()); bondType = "0"; if (bond.Order == BondOrder.Single) { if ((bond.Begin.AtomTypeName.Equals("Csp2", StringComparison.Ordinal)) && ((bond.End.AtomTypeName.Equals("Csp2", StringComparison.Ordinal)) || (bond.End.AtomTypeName.Equals("C=", StringComparison.Ordinal)))) { bondType = "1"; } if ((bond.Begin.AtomTypeName.Equals("C=", StringComparison.Ordinal)) && ((bond.End.AtomTypeName.Equals("Csp2", StringComparison.Ordinal)) || (bond.End.AtomTypeName.Equals("C=", StringComparison.Ordinal)))) { bondType = "1"; } if ((bond.Begin.AtomTypeName.Equals("Csp", StringComparison.Ordinal)) && (bond.End.AtomTypeName.Equals("Csp", StringComparison.Ordinal))) { bondType = "1"; } } // molecule.Bonds[i].SetProperty("MMFF94 bond type", bondType); bond.SetProperty("MMFF94 bond type", bondType); //Debug.WriteLine("bond[" + i + "] properties : " + molecule.Bonds[i].GetProperties()); } return(ringSetMolecule); }