예제 #1
0
        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];
                    }
                }
            }
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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);
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        /// <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));
            }
        }
예제 #9
0
        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);
        }
예제 #10
0
        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);
            }
        }
예제 #12
0
        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:
                    ;
                }
            }
        }
예제 #13
0
        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}");
        }
예제 #14
0
        /// <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());
        }
예제 #15
0
        /// <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;
                }
            }
        }
예제 #16
0
        /// <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;
                    }
                }
            }
        }
예제 #17
0
        /// <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);
        }
예제 #18
0
        /// <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);
        }