public virtual void TestNumberOfUnplacedHeavyAtoms_IAtomContainer() { var ac = MakeAlphaPinene(); var count = new AtomPlacer3D().NumberOfUnplacedHeavyAtoms(ac); Assert.AreEqual(10, count); }
public virtual void TestNumberOfUnplacedHeavyAtoms_IAtomContainerWithExplicitHydrogens() { var ac = MakeMethaneWithExplicitHydrogens(); var count = new AtomPlacer3D().NumberOfUnplacedHeavyAtoms(ac); Assert.AreEqual(1, count); }
public void TestGetBondLengthValue_String_String() { var parser = CDK.SmilesParser; var smiles = "CCCCCC"; var molecule = parser.ParseSmiles(smiles); Assert.IsNotNull(molecule); ForceFieldConfigurator ffc = new ForceFieldConfigurator(); ffc.SetForceFieldConfigurator("mmff94"); AtomPlacer3D atomPlacer3d = new AtomPlacer3D(ffc.GetParameterSet()); ffc.AssignAtomTyps(molecule); string id1 = molecule.Atoms[1].AtomTypeName; string id2 = molecule.Atoms[2].AtomTypeName; string mmff94id1 = "C"; string mmff94id2 = "C"; Assert.AreNotSame(mmff94id1, id1); Assert.AreNotSame(mmff94id2, id2); double bondlength = atomPlacer3d.GetBondLengthValue(id1, id2); Assert.AreEqual(1.508, bondlength, 0.001); }
public void TestGetNextPlacedHeavyAtomWithUnplacedRingNeighbour_IAtomContainer() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer acyclicAlkane = TestMoleculeFactory.MakeAlkane(3); IAtomContainer cycloPentane = TestMoleculeFactory.MakeCyclopentane(); //TestMoleculeFactory does not set ISINRING flags for cyclic molecules Assert.AreEqual(false, cycloPentane.Atoms[0].IsInRing); foreach (var atom in cycloPentane.Atoms) { atom.IsInRing = true; } //acyclic molecule so null is expected foreach (var atom in acyclicAlkane.Atoms) { atom.IsPlaced = true; } Assert.IsNull(atmplacer.GetNextPlacedHeavyAtomWithUnplacedRingNeighbour(acyclicAlkane)); for (int j = 0; j < 3; j++) { cycloPentane.Atoms[j].IsPlaced = true; } Assert.AreEqual(cycloPentane.Atoms[2], atmplacer.GetNextPlacedHeavyAtomWithUnplacedRingNeighbour(cycloPentane)); }
public void TestGetUnplacedRingHeavyAtom_IAtomContainer_IAtom() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer molecule = TestMoleculeFactory.MakeCyclopentane(); foreach (var atom in molecule.Atoms) { atom.IsInRing = true; } for (int j = 0; j < 2; j++) { molecule.Atoms[j].IsPlaced = true; } IAtom atom0 = molecule.Atoms[0]; IAtom atom1 = molecule.Atoms[1]; IAtom natom = molecule.Atoms[4]; IAtom atom0pair = atmplacer.GetUnplacedRingHeavyAtom(molecule, atom0); IAtom atom1pair = atmplacer.GetUnplacedRingHeavyAtom(molecule, atom1); IAtom natompair = atmplacer.GetUnplacedRingHeavyAtom(molecule, natom); Assert.AreEqual(atom0pair, molecule.Atoms[4]); Assert.AreEqual(atom1pair, molecule.Atoms[2]); Assert.AreEqual(atom0.IsPlaced, true); foreach (var bond in molecule.Bonds) { if (bond.GetOther(molecule.Atoms[4]) != null && !bond.GetOther(molecule.Atoms[4]).IsPlaced) { natompair = bond.GetOther(molecule.Atoms[4]); } } Assert.AreEqual(natompair, molecule.Atoms[3]); }
public void TestFindHeavyAtomsInChain_IAtomContainer_IAtomContainer() { var filename = "NCDK.Data.MDL.allmol232.mol"; var ins = ResourceLoader.GetAsStream(filename); // TODO: shk3-cleanuptests: best to use the STRICT IO mode here var reader = new MDLV2000Reader(ins); var chemFile = reader.Read(builder.NewChemFile()); reader.Close(); var containersList = ChemFileManipulator.GetAllAtomContainers(chemFile); var ac = new Silent.AtomContainer(containersList.First()); AddExplicitHydrogens(ac); var chain = ac.Builder.NewAtomContainer(); for (int i = 16; i < 25; i++) { chain.Atoms.Add(ac.Atoms[i]); } chain.Atoms.Add(ac.Atoms[29]); chain.Atoms.Add(ac.Atoms[30]); int[] result = new AtomPlacer3D().FindHeavyAtomsInChain(ac, chain); Assert.AreEqual(16, result[0]); Assert.AreEqual(11, result[1]); }
public virtual void TestGetPlacedHeavyAtom_IAtomContainer_IAtom() { var ac = MakeAlphaPinene(); var acplaced = new AtomPlacer3D().GetPlacedHeavyAtom(ac, ac.Atoms[0]); Assert.IsNull(acplaced); ac.Atoms[1].IsPlaced = true; acplaced = new AtomPlacer3D().GetPlacedHeavyAtom(ac, ac.Atoms[0]); Assert.AreEqual(ac.Atoms[1], acplaced); }
public void TestAllHeavyAtomsPlaced_benzene() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer benzene = TestMoleculeFactory.MakeBenzene(); foreach (var atom in benzene.Atoms) { atom.IsPlaced = true; } Assert.IsTrue(atmplacer.AllHeavyAtomsPlaced(benzene)); }
public override void TestNumberOfUnplacedHeavyAtoms_IAtomContainer() { IAtomContainer molecule = TestMoleculeFactory.MakeAlkane(5); for (int i = 0; i < 3; i++) { (molecule.Atoms[i]).IsPlaced = true; } int placedAtoms = new AtomPlacer3D().NumberOfUnplacedHeavyAtoms(molecule); Assert.AreEqual(2, placedAtoms); }
public void TestIsHeavyAtom() { var ac = MakeMethaneWithExplicitHydrogens(); var carbon = ac.Atoms[0]; var hydrogen = ac.Atoms[1]; var placer = new AtomPlacer3D(); bool result = false; result = placer.IsHeavyAtom(carbon); Assert.IsTrue(result); result = placer.IsHeavyAtom(hydrogen); Assert.IsFalse(result); }
public void InvalidChain() { string input = "CCCCCC(CCCC)CCCC"; var sp = CDK.SmilesParser; var m = sp.ParseSmiles(input); ForceFieldConfigurator ffc = new ForceFieldConfigurator(); ffc.SetForceFieldConfigurator("mmff92"); ffc.AssignAtomTyps(m); AtomPlacer3D ap3d = new AtomPlacer3D(ffc.GetParameterSet()); ap3d.PlaceAliphaticHeavyChain(m, m); }
public void TestGetNextUnplacedHeavyAtomWithAliphaticPlacedNeighbour_IAtomContainer() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer cyclobutane = TestMoleculeFactory.MakeCyclobutane(); IAtomContainer acyclicAlkane = TestMoleculeFactory.MakeAlkane(6); foreach (var atom in cyclobutane.Atoms) { atom.IsInRing = true; } foreach (var atom in acyclicAlkane.Atoms) { atom.IsAliphatic = true; } for (int j = 0; j < 3; j++) { cyclobutane.Atoms[j].IsPlaced = true; } IAtom nextHeavyAtom = atmplacer.GetNextUnplacedHeavyAtomWithAliphaticPlacedNeighbour(cyclobutane); Assert.IsNull(nextHeavyAtom); foreach (var atom in cyclobutane.Atoms) { if (!atom.IsPlaced) { atom.IsPlaced = true; } } IAtom nextHeavyAtom2 = atmplacer.GetNextUnplacedHeavyAtomWithAliphaticPlacedNeighbour(cyclobutane); Assert.IsNull(nextHeavyAtom2); for (int k = 0; k < 3; k++) { acyclicAlkane.Atoms[k].IsPlaced = true; } IAtom nextSuchUnplacedHeavyAtom = atmplacer.GetNextUnplacedHeavyAtomWithAliphaticPlacedNeighbour(acyclicAlkane); Assert.AreEqual(acyclicAlkane.Atoms[3], nextSuchUnplacedHeavyAtom); foreach (var atom in acyclicAlkane.Atoms) { atom.IsPlaced = true; } nextSuchUnplacedHeavyAtom = atmplacer.GetNextUnplacedHeavyAtomWithAliphaticPlacedNeighbour(acyclicAlkane); Assert.IsNull(nextSuchUnplacedHeavyAtom); }
public void TestGetFarthestAtom_Point3d_IAtomContainer() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer molecule = TestMoleculeFactory.MakeBenzene(); molecule.Atoms[0].Point3D = new Vector3(0.0, 0.0, 0.0); molecule.Atoms[1].Point3D = new Vector3(1.0, 1.0, 1.0); molecule.Atoms[4].Point3D = new Vector3(3.0, 2.0, 1.0); molecule.Atoms[5].Point3D = new Vector3(4.0, 4.0, 4.0); IAtom farthestFromAtoma = atmplacer.GetFarthestAtom(molecule.Atoms[0].Point3D.Value, molecule); IAtom farthestFromAtomb = atmplacer.GetFarthestAtom(molecule.Atoms[4].Point3D.Value, molecule); Assert.AreEqual(molecule.Atoms[5], farthestFromAtoma); Assert.AreEqual(molecule.Atoms[0], farthestFromAtomb); }
public override void TestGetPlacedHeavyAtoms_IAtomContainer_IAtom() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer molecule = TestMoleculeFactory.MakeBenzene(); for (int j = 0; j < 3; j++) { (molecule.Atoms[j]).IsPlaced = true; } IAtomContainer placedAndConnectedTo1 = atmplacer.GetPlacedHeavyAtoms(molecule, molecule.Atoms[1]); IAtomContainer placedAndConnectedTo2 = atmplacer.GetPlacedHeavyAtoms(molecule, molecule.Atoms[2]); IAtomContainer placedAndConnectedTo4 = atmplacer.GetPlacedHeavyAtoms(molecule, molecule.Atoms[4]); Assert.AreEqual(2, placedAndConnectedTo1.Atoms.Count); Assert.AreEqual(1, placedAndConnectedTo2.Atoms.Count); Assert.AreEqual(0, placedAndConnectedTo4.Atoms.Count); }
public override void TestGetPlacedHeavyAtom_IAtomContainer_IAtom_IAtom() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer molecule = TestMoleculeFactory.MakeAlkane(7); for (int j = 0; j < 5; j++) { molecule.Atoms[j].IsPlaced = true; } IAtom atom2 = atmplacer.GetPlacedHeavyAtom(molecule, molecule.Atoms[1], molecule.Atoms[0]); IAtom atom3 = atmplacer.GetPlacedHeavyAtom(molecule, molecule.Atoms[2], molecule.Atoms[1]); IAtom nullAtom = atmplacer.GetPlacedHeavyAtom(molecule, molecule.Atoms[0], molecule.Atoms[1]); Assert.AreEqual(atom2, molecule.Atoms[2]); Assert.AreEqual(atom3, molecule.Atoms[3]); Assert.IsNull(nullAtom); }
public override void TestGeometricCenterAllPlacedAtoms_IAtomContainer() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer molecule = TestMoleculeFactory.MakeAlkane(2); foreach (var atom in molecule.Atoms) { atom.IsPlaced = true; } molecule.Atoms[0].Point3D = new Vector3(-1.0, 0.0, 0.0); molecule.Atoms[1].Point3D = new Vector3(1.0, 0.0, 0.0); Vector3 center = atmplacer.GeometricCenterAllPlacedAtoms(molecule); Assert.AreEqual(0.0, center.X, 0.01); Assert.AreEqual(0.0, center.Y, 0.01); Assert.AreEqual(0.0, center.Z, 0.01); }
public void TestGetNextPlacedHeavyAtomWithUnplacedAliphaticNeighbour_IAtomContainer() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer benzene = TestMoleculeFactory.MakeBenzene(); IAtomContainer acyclicAlkane = TestMoleculeFactory.MakeAlkane(5); foreach (var atom in benzene.Atoms) { atom.IsInRing = true; } foreach (var atom in acyclicAlkane.Atoms) { atom.IsAliphatic = true; } for (int j = 0; j < 3; j++) { benzene.Atoms[j].IsPlaced = true; } IAtom searchedatom1 = atmplacer.GetNextPlacedHeavyAtomWithUnplacedAliphaticNeighbour(benzene); Assert.IsNull(searchedatom1); foreach (var atom in benzene.Atoms) { if (!atom.IsPlaced) { atom.IsPlaced = true; } } IAtom searchedatom2 = atmplacer.GetNextPlacedHeavyAtomWithUnplacedAliphaticNeighbour(benzene); Assert.IsNull(searchedatom2); for (int k = 0; k < 3; k++) { acyclicAlkane.Atoms[k].IsPlaced = true; } IAtom nextAtom = atmplacer.GetNextPlacedHeavyAtomWithUnplacedAliphaticNeighbour(acyclicAlkane); Assert.AreEqual(acyclicAlkane.Atoms[2], nextAtom); }
public override void TestGetPlacedHeavyAtom_IAtomContainer_IAtom() { AtomPlacer3D atmplacer = new AtomPlacer3D(); IAtomContainer molecule = TestMoleculeFactory.MakeCyclohexane(); // For(IAtom a : m.Atoms) a.IsPlaced = true; for (int i = 0; i < 3; i++) { molecule.Atoms[i].IsPlaced = true; } IAtom atom1 = atmplacer.GetPlacedHeavyAtom(molecule, molecule.Atoms[0]); Assert.AreEqual(atom1, molecule.Atoms[1]); IAtom atom2 = atmplacer.GetPlacedHeavyAtom(molecule, molecule.Atoms[2]); Assert.AreEqual(atom2, molecule.Atoms[1]); IAtom atom3 = atmplacer.GetPlacedHeavyAtom(molecule, molecule.Atoms[4]); Assert.IsNull(atom3); }
public void TestGetAngleValue_String_String_String() { var parser = CDK.SmilesParser; var smiles = "CCCCCC"; var molecule = parser.ParseSmiles(smiles); Assert.IsNotNull(molecule); ForceFieldConfigurator ffc = new ForceFieldConfigurator(); ffc.SetForceFieldConfigurator("mmff94"); AtomPlacer3D atomPlacer3d = new AtomPlacer3D(ffc.GetParameterSet()); ffc.AssignAtomTyps(molecule); string id1 = molecule.Atoms[1].AtomTypeName; string id2 = molecule.Atoms[2].AtomTypeName; string id3 = molecule.Atoms[3].AtomTypeName; double anglev = atomPlacer3d.GetAngleValue(id1, id2, id3); Assert.AreEqual(109.608, anglev, 0.001); }
public virtual void TestGeometricCenterAllPlacedAtoms_IAtomContainer() { var ac = MakeAlphaPinene(); for (int i = 0; i < ac.Atoms.Count; i++) { ac.Atoms[i].IsPlaced = true; } ac.Atoms[0].Point3D = new Vector3(1.39, 2.04, 0); ac.Atoms[0].Point3D = new Vector3(2.02, 2.28, -1.12); ac.Atoms[0].Point3D = new Vector3(3.44, 2.80, -1.09); ac.Atoms[0].Point3D = new Vector3(3.91, 2.97, 0.35); ac.Atoms[0].Point3D = new Vector3(3.56, 1.71, 1.16); ac.Atoms[0].Point3D = new Vector3(2.14, 2.31, 1.29); ac.Atoms[0].Point3D = new Vector3(0, 1.53, 0); ac.Atoms[0].Point3D = new Vector3(2.83, 3.69, 1.17); ac.Atoms[0].Point3D = new Vector3(3.32, 4.27, 2.49); ac.Atoms[0].Point3D = new Vector3(2.02, 4.68, 0.35); var center = new AtomPlacer3D().GeometricCenterAllPlacedAtoms(ac); Assert.AreEqual(2.02, center.X, 0.01); Assert.AreEqual(4.68, center.Y, 0.01); Assert.AreEqual(0.35, center.Z, 0.01); }
/// <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> /// Layout all aliphatic chains with ZMatrix. /// </summary> /// <param name="startAtoms">AtomContainer of possible start atoms for a chain</param> private void PlaceLinearChains3D(IAtomContainer molecule, IAtomContainer startAtoms, AtomPlacer3D ap3d, AtomTetrahedralLigandPlacer3D atlp3d, AtomPlacer atomPlacer) { //Debug.WriteLine("****** PLACE LINEAR CHAINS ******"); IAtom dihPlacedAtom = null; IAtom thirdPlacedAtom = null; IAtomContainer longestUnplacedChain = molecule.Builder.NewAtomContainer(); if (startAtoms.Atoms.Count == 0) { //no branch points ->linear chain //Debug.WriteLine("------ LINEAR CHAIN - FINISH ------"); } else { for (int i = 0; i < startAtoms.Atoms.Count; i++) { //Debug.WriteLine("FOUND BRANCHED ALKAN"); //Debug.WriteLine("Atom NOT NULL:" + molecule.Atoms.IndexOf(startAtoms.GetAtomAt(i))); thirdPlacedAtom = ap3d.GetPlacedHeavyAtom(molecule, startAtoms.Atoms[i]); dihPlacedAtom = ap3d.GetPlacedHeavyAtom(molecule, thirdPlacedAtom, startAtoms.Atoms[i]); longestUnplacedChain.Atoms.Add(dihPlacedAtom); longestUnplacedChain.Atoms.Add(thirdPlacedAtom); longestUnplacedChain.Atoms.Add(startAtoms.Atoms[i]); longestUnplacedChain.Add(AtomPlacer.GetLongestUnplacedChain(molecule, startAtoms.Atoms[i])); SetAtomsToUnVisited(molecule); if (longestUnplacedChain.Atoms.Count < 4) { //di,third,sec //Debug.WriteLine("------ Single BRANCH METHYLTYP ------"); //break; } else { //Debug.WriteLine("LongestUnchainLength:"+longestUnplacedChain.Atoms.Count); ap3d.PlaceAliphaticHeavyChain(molecule, longestUnplacedChain); ap3d.ZMatrixChainToCartesian(molecule, true); SearchAndPlaceBranches(molecule, longestUnplacedChain, ap3d, atlp3d, atomPlacer); } longestUnplacedChain.RemoveAllElements(); }//for } //Debug.WriteLine("****** HANDLE ALIPHATICS END ******"); }
/// <summary> /// Search and place branches of a chain or ring. /// </summary> /// <param name="chain">AtomContainer if atoms in an aliphatic chain or ring system</param> private void SearchAndPlaceBranches(IAtomContainer molecule, IAtomContainer chain, AtomPlacer3D ap3d, AtomTetrahedralLigandPlacer3D atlp3d, AtomPlacer atomPlacer) { //Debug.WriteLine("****** SEARCH AND PLACE ****** Chain length: "+chain.Atoms.Count); IAtomContainer branchAtoms = molecule.Builder.NewAtomContainer(); IAtomContainer connectedAtoms = molecule.Builder.NewAtomContainer(); for (int i = 0; i < chain.Atoms.Count; i++) { var atoms = molecule.GetConnectedAtoms(chain.Atoms[i]); foreach (var atom in atoms) { if (!atom.AtomicNumber.Equals(AtomicNumbers.H) & !atom.IsPlaced & !atom.IsInRing) { connectedAtoms.Add(ap3d.GetPlacedHeavyAtoms(molecule, chain.Atoms[i])); try { SetBranchAtom(molecule, atom, chain.Atoms[i], connectedAtoms, ap3d, atlp3d); } catch (CDKException ex2) { Trace.TraceError($"SearchAndPlaceBranchERROR: Cannot find enough neighbour atoms due to {ex2.ToString()}"); throw new CDKException($"SearchAndPlaceBranchERROR: Cannot find enough neighbour atoms: {ex2.Message}", ex2); } branchAtoms.Atoms.Add(atom); connectedAtoms.RemoveAllElements(); } } }//for ac.getAtomCount PlaceLinearChains3D(molecule, branchAtoms, ap3d, atlp3d, atomPlacer); }
/// <summary> /// Sets a branch atom to a ring or aliphatic chain. /// </summary> /// <param name="unplacedAtom">The new branchAtom</param> /// <param name="atomA">placed atom to which the unplaced atom is connected</param> /// <param name="atomNeighbours">placed atomNeighbours of atomA</param> private static void SetBranchAtom(IAtomContainer molecule, IAtom unplacedAtom, IAtom atomA, IAtomContainer atomNeighbours, AtomPlacer3D ap3d, AtomTetrahedralLigandPlacer3D atlp3d) { //Debug.WriteLine("****** SET Branch Atom ****** >"+molecule.Atoms.IndexOf(unplacedAtom)); IAtomContainer noCoords = molecule.Builder.NewAtomContainer(); noCoords.Atoms.Add(unplacedAtom); Vector3 centerPlacedMolecule = ap3d.GeometricCenterAllPlacedAtoms(molecule); IAtom atomB = atomNeighbours.Atoms[0]; string atypeNameA = atomA.AtomTypeName; string atypeNameB = atomB.AtomTypeName; string atypeNameUnplaced = unplacedAtom.AtomTypeName; double length = ap3d.GetBondLengthValue(atypeNameA, atypeNameUnplaced); double angle = (ap3d.GetAngleValue(atypeNameB, atypeNameA, atypeNameUnplaced)) * Math.PI / 180; // Console.Out.WriteLine("A:"+atomA.Symbol+" "+atomA.AtomTypeName+ // " B:"+atomB.Symbol+" "+atomB.AtomTypeName // +" unplaced Atom:" // +unplacedAtom.AtomTypeName+" BL:"+length+" Angle:"+angle // +" FormalNeighbour:" // +atomA.FormalNeighbourCount+" HYB:"+atomA.getFlag // (CDKConstants.HYBRIDIZATION_SP2) // +" #Neigbhours:"+atomNeighbours.Atoms.Count); IAtom atomC = ap3d.GetPlacedHeavyAtom(molecule, atomB, atomA); Vector3[] branchPoints = atlp3d.Get3DCoordinatesForLigands(atomA, noCoords, atomNeighbours, atomC, (atomA.FormalNeighbourCount.Value - atomNeighbours.Atoms.Count), length, angle); double distance = 0; int farthestPoint = 0; for (int i = 0; i < branchPoints.Length; i++) { if (Math.Abs(Vector3.Distance(branchPoints[i], centerPlacedMolecule)) > Math.Abs(distance)) { distance = Vector3.Distance(branchPoints[i], centerPlacedMolecule); farthestPoint = i; } } int stereo = -1; IBond unplacedBond = molecule.GetBond(atomA, unplacedAtom); if (atomA.StereoParity != 0 || (unplacedBond.Stereo == BondStereo.Up || unplacedBond.Stereo == BondStereo.Down) && molecule.GetMaximumBondOrder(atomA) == BondOrder.Single) { if (atomNeighbours.Atoms.Count > 1) { stereo = AtomTetrahedralLigandPlacer3D.MakeStereocenter(atomA.Point3D.Value, molecule.GetBond(atomA, unplacedAtom), (atomNeighbours.Atoms[0]).Point3D.Value, (atomNeighbours.Atoms[1]).Point3D.Value, branchPoints); } } if (stereo != -1) { farthestPoint = stereo; } unplacedAtom.Point3D = branchPoints[farthestPoint]; unplacedAtom.IsPlaced = true; }
/// <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> /// 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); }