예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <summary>
        /// Positions the aliphatic substituents of a ring system
        /// </summary>
        /// <param name="rs">The RingSystem for which the substituents are to be laid out</param>
        /// <returns>A list of atoms that where laid out</returns>
        public IAtomContainer PlaceRingSubstituents(IRingSet rs, double bondLength)
        {
            Debug.WriteLine("RingPlacer.PlaceRingSubstituents() start");
            IRing          ring             = null;
            IAtom          atom             = null;
            IAtomContainer unplacedPartners = rs.Builder.NewAtomContainer();
            IAtomContainer sharedAtoms      = rs.Builder.NewAtomContainer();
            IAtomContainer primaryAtoms     = rs.Builder.NewAtomContainer();
            IAtomContainer treatedAtoms     = rs.Builder.NewAtomContainer();

            for (int j = 0; j < rs.Count; j++)
            {
                ring = (IRing)rs[j]; // Get the j-th Ring in RingSet rs
                for (int k = 0; k < ring.Atoms.Count; k++)
                {
                    unplacedPartners.RemoveAllElements();
                    sharedAtoms.RemoveAllElements();
                    primaryAtoms.RemoveAllElements();
                    atom = ring.Atoms[k];
                    var rings = rs.GetRings(atom);
                    var centerOfRingGravity = GeometryUtil.Get2DCenter(rings);
                    AtomPlacer.PartitionPartners(atom, unplacedPartners, sharedAtoms);
                    AtomPlacer.MarkNotPlaced(unplacedPartners);
                    try
                    {
                        for (int f = 0; f < unplacedPartners.Atoms.Count; f++)
                        {
                            Debug.WriteLine("placeRingSubstituents->unplacedPartners: "
                                            + (Molecule.Atoms.IndexOf(unplacedPartners.Atoms[f]) + 1));
                        }
                    }
                    catch (Exception)
                    {
                    }

                    treatedAtoms.Add(unplacedPartners);
                    if (unplacedPartners.Atoms.Count > 0)
                    {
                        AtomPlacer.DistributePartners(atom, sharedAtoms, centerOfRingGravity, unplacedPartners, bondLength);
                    }
                }
            }
            Debug.WriteLine("RingPlacer.PlaceRingSubstituents() end");
            return(treatedAtoms);
        }
예제 #3
0
        /// <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 ******");
        }
예제 #4
0
        /// <summary>
        /// Generate coordinates for all atoms which are singly bonded and have no
        /// coordinates. This is useful when hydrogens are present but have no coordinates.
        /// It knows about C, O, N, S only and will give tetrahedral or trigonal
        /// geometry elsewhere. Bond lengths are computed from covalent radii or taken
        /// out of a parameter set if available. Angles are tetrahedral or trigonal
        /// </summary>
        /// <param name="atomContainer">the set of atoms involved</param>
        // @cdk.keyword           coordinate calculation
        // @cdk.keyword           3D model
        public virtual void Add3DCoordinatesForSinglyBondedLigands(IAtomContainer atomContainer)
        {
            IAtom refAtom = null;
            IAtom atomC   = null;
            int   nwanted = 0;

            for (int i = 0; i < atomContainer.Atoms.Count; i++)
            {
                refAtom = atomContainer.Atoms[i];
                if (!refAtom.AtomicNumber.Equals(AtomicNumbers.H) && HasUnsetNeighbour(refAtom, atomContainer))
                {
                    IAtomContainer noCoords   = GetUnsetAtomsInAtomContainer(refAtom, atomContainer);
                    IAtomContainer withCoords = GetPlacedAtomsInAtomContainer(refAtom, atomContainer);
                    if (withCoords.Atoms.Count > 0)
                    {
                        atomC = GetPlacedHeavyAtomInAtomContainer(withCoords.Atoms[0], refAtom, atomContainer);
                    }
                    if (refAtom.FormalNeighbourCount == 0 && refAtom.AtomicNumber.Equals(AtomicNumbers.C))
                    {
                        nwanted = noCoords.Atoms.Count;
                    }
                    else if (refAtom.FormalNeighbourCount == 0 && !refAtom.AtomicNumber.Equals(AtomicNumbers.C))
                    {
                        nwanted = 4;
                    }
                    else
                    {
                        nwanted = refAtom.FormalNeighbourCount.Value - withCoords.Atoms.Count;
                    }
                    Vector3[] newPoints = Get3DCoordinatesForLigands(refAtom, noCoords, withCoords, atomC, nwanted,
                                                                     DefaultBondLengthH, -1);
                    for (int j = 0; j < noCoords.Atoms.Count; j++)
                    {
                        IAtom   ligand   = noCoords.Atoms[j];
                        Vector3 newPoint = RescaleBondLength(refAtom, ligand, newPoints[j]);
                        ligand.Point3D  = newPoint;
                        ligand.IsPlaced = true;
                    }

                    noCoords.RemoveAllElements();
                    withCoords.RemoveAllElements();
                }
            }
        }