Пример #1
0
        /// <summary>
        /// The method is a proton descriptor that evaluate if a proton is bonded to an aromatic system or if there is distance of 2 bonds.
        /// It is needed to call the addExplicitHydrogensToSatisfyValency method from the class tools.HydrogenAdder.
        /// </summary>
        /// <param name="atom">The <see cref="IAtom"/> for which the <see cref="Result"/> is requested</param>
        /// <returns>true if the proton is bonded to an aromatic atom.</returns>
        public Result Calculate(IAtom atom)
        {
            var clonedAtom = clonedAtomContainer.Atoms[container.Atoms.IndexOf(atom)];
            var neighboor  = clonedAtomContainer.GetConnectedAtoms(clonedAtom);
            var neighbour0 = neighboor.First();
            int isProtonInAromaticSystem = 0;

            if (atom.AtomicNumber.Equals(AtomicNumbers.H))
            {
                if (neighbour0.IsAromatic)
                {
                    isProtonInAromaticSystem = 1;
                }
                else
                {
                    var betaAtom = clonedAtomContainer.GetConnectedAtoms(neighbour0).LastOrDefault();
                    if (betaAtom != null)
                    {
                        if (betaAtom.IsAromatic)
                        {
                            isProtonInAromaticSystem = 2;
                        }
                        else
                        {
                            isProtonInAromaticSystem = 0;
                        }
                    }
                }
            }
            else
            {
                isProtonInAromaticSystem = 0;
            }
            return(new Result(isProtonInAromaticSystem));
        }
Пример #2
0
        /// <summary>
        /// The method returns if two atoms have pi-contact.
        /// </summary>
        /// <returns><see langword="true"/> if the atoms have pi-contact</returns>
        /// <param name="first">The first atom</param>
        /// <param name="second">The second atom</param>
        public Result Calculate(IAtom first, IAtom second)
        {
            var clonedFirst  = clonedContainer.Atoms[container.Atoms.IndexOf(first)];
            var clonedSecond = clonedContainer.Atoms[container.Atoms.IndexOf(second)];

            bool piContact = false;
            int  counter   = 0;
            var  detected  = acSet;

            var neighboorsFirst  = mol.GetConnectedAtoms(clonedFirst);
            var neighboorsSecond = mol.GetConnectedAtoms(clonedSecond);

            foreach (var detectedAC in detected)
            {
                if (detectedAC.Contains(clonedFirst) && detectedAC.Contains(clonedSecond))
                {
                    counter += 1;
                    break;
                }
                if (IsANeighboorsInAnAtomContainer(neighboorsFirst, detectedAC) &&
                    IsANeighboorsInAnAtomContainer(neighboorsSecond, detectedAC))
                {
                    counter += 1;
                    break;
                }
            }

            if (counter > 0)
            {
                piContact = true;
            }

            return(new Result(piContact));
        }
Пример #3
0
        /// <summary>
        /// Says if an atom is the end of a double bond configuration
        /// </summary>
        /// <param name="atom">The atom which is the end of configuration</param>
        /// <param name="container">The atomContainer the atom is in</param>
        /// <param name="parent">The atom we came from</param>
        /// <param name="doubleBondConfiguration">The array indicating where double bond
        ///     configurations are specified (this method ensures that there is
        ///     actually the possibility of a double bond configuration)</param>
        /// <returns>false=is not end of configuration, true=is</returns>
        private static bool IsEndOfDoubleBond(IAtomContainer container, IAtom atom, IAtom parent,
                                              bool[] doubleBondConfiguration)
        {
            var bondNumber = container.Bonds.IndexOf(container.GetBond(atom, parent));

            if (bondNumber == -1 ||
                doubleBondConfiguration.Length <= bondNumber ||
                !doubleBondConfiguration[bondNumber])
            {
                return(false);
            }

            int hcount = atom.ImplicitHydrogenCount ?? 0;

            int lengthAtom = container.GetConnectedAtoms(atom).Count() + hcount;

            hcount = parent.ImplicitHydrogenCount ?? 0;

            int lengthParent = container.GetConnectedAtoms(parent).Count() + hcount;

            if (container.GetBond(atom, parent) != null)
            {
                if (container.GetBond(atom, parent).Order == BondOrder.Double &&
                    (lengthAtom == 3 || (lengthAtom == 2 && atom.AtomicNumber.Equals(AtomicNumbers.N))) &&
                    (lengthParent == 3 || (lengthParent == 2 && parent.AtomicNumber.Equals(AtomicNumbers.N))))
                {
                    var   atoms = container.GetConnectedAtoms(atom);
                    IAtom one   = null;
                    IAtom two   = null;
                    foreach (var conAtom in atoms)
                    {
                        if (conAtom != parent && one == null)
                        {
                            one = conAtom;
                        }
                        else if (conAtom != parent && one != null)
                        {
                            two = conAtom;
                        }
                    }
                    string[] morgannumbers = MorganNumbersTools.GetMorganNumbersWithElementSymbol(container);
                    if ((one != null && two == null &&
                         atom.AtomicNumber.Equals(AtomicNumbers.N) &&
                         Math.Abs(GiveAngleBothMethods(parent, atom, one, true)) > Math.PI / 10) ||
                        (!atom.AtomicNumber.Equals(AtomicNumbers.N) &&
                         one != null && two != null &&
                         !morgannumbers[container.Atoms.IndexOf(one)].Equals(morgannumbers[container.Atoms.IndexOf(two)], StringComparison.Ordinal)))
                    {
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            return(false);
        }
Пример #4
0
        /// <summary>
        /// Says if an atom is the start of a double bond configuration
        /// </summary>
        /// <param name="a">The atom which is the start of configuration</param>
        /// <param name="container">The atomContainer the atom is in</param>
        /// <param name="parent">The atom we came from</param>
        /// <param name="doubleBondConfiguration">The array indicating where double bond
        ///     configurations are specified (this method ensures that there is
        ///     actually the possibility of a double bond configuration)</param>
        /// <returns>false=is not start of configuration, true=is</returns>
        private static bool IsStartOfDoubleBond(IAtomContainer container, IAtom a, IAtom parent, bool[] doubleBondConfiguration)
        {
            int hcount;

            hcount = a.ImplicitHydrogenCount ?? 0;

            int lengthAtom = container.GetConnectedAtoms(a).Count() + hcount;

            if (lengthAtom != 3 && (lengthAtom != 2 && !(a.AtomicNumber.Equals(AtomicNumbers.N))))
            {
                return(false);
            }
            var   atoms      = container.GetConnectedAtoms(a);
            IAtom one        = null;
            IAtom two        = null;
            bool  doubleBond = false;
            IAtom nextAtom   = null;

            foreach (var atom in atoms)
            {
                if (atom != parent && container.GetBond(atom, a).Order == BondOrder.Double &&
                    IsEndOfDoubleBond(container, atom, a, doubleBondConfiguration))
                {
                    doubleBond = true;
                    nextAtom   = atom;
                }
                if (atom != nextAtom && one == null)
                {
                    one = atom;
                }
                else if (atom != nextAtom && one != null)
                {
                    two = atom;
                }
            }
            string[] morgannumbers = MorganNumbersTools.GetMorganNumbersWithElementSymbol(container);
            if (one != null &&
                ((!a.AtomicNumber.Equals(AtomicNumbers.N) &&
                  two != null &&
                  !morgannumbers[container.Atoms.IndexOf(one)].Equals(morgannumbers[container.Atoms.IndexOf(two)], StringComparison.Ordinal) &&
                  doubleBond &&
                  doubleBondConfiguration[container.Bonds.IndexOf(container.GetBond(a, nextAtom))]) ||
                 (doubleBond && a.AtomicNumber.Equals(AtomicNumbers.N) &&
                  Math.Abs(GiveAngleBothMethods(nextAtom, a, parent, true)) > Math.PI / 10)))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #5
0
        /// <summary>
        /// Prepares for a breadth first search within the <see cref="IAtomContainer"/>. The actual
        /// recursion is done in <see cref="NextSphere"/>.
        /// </summary>
        /// <param name="root">The atom at which we start the search</param>
        /// <param name="addTreeNode"></param>
        /// <exception cref="CDKException"> If something goes wrong.</exception>
        private void BreadthFirstSearch(IAtom root, bool addTreeNode)
        {
            sphere = 0;
            TreeNode tempNode = null;
            var      conAtoms = atomContainer.GetConnectedAtoms(root);
            IBond    bond     = null;

            sphereNodes.Clear();
            sphereNodesWithAtoms.Clear();
            foreach (var atom in conAtoms)
            {
                try
                {
                    if (atom.AtomicNumber.Equals(AtomicNumbers.H))
                    {
                        continue;
                    }
                    bond = atomContainer.GetBond(root, atom);

                    // In the first sphere the atoms are labeled with their own atom
                    // atom as source
                    if (bond.IsAromatic)
                    {
                        tempNode = new TreeNode(this, atom.Symbol, new TreeNode(this, root.Symbol, null, root, (double)0, 0,
                                                                                (long)0), atom, 4, atomContainer.GetConnectedBonds(atom).Count(), 0);
                    }
                    else
                    {
                        tempNode = new TreeNode(
                            this, atom.Symbol,
                            new TreeNode(this, root.Symbol, null, root, (double)0, 0, (long)0), atom,
                            bond.Order.Numeric(), atomContainer.GetConnectedBonds(atom).Count(), 0);
                    }

                    sphereNodes.Add(tempNode);
                    if (!addTreeNode)
                    {
                        sphereNodesWithAtoms.Add(atom);
                    }

                    //                rootNode.childs.AddElement(tempNode);
                    atom.IsVisited = true;
                }
                catch (Exception exc)
                {
                    throw new CDKException("Error in HOSECodeGenerator->breadthFirstSearch.", exc);
                }
            }
            sphereNodes.Sort(new TreeNodeComparator());
            NextSphere(sphereNodes);
        }
Пример #6
0
        /// <summary>
        /// Get all the paths starting from an atom of length 0 up to the specified length.
        /// <para>This method returns a set of paths. Each path is a <see cref="IList{IAtom}"/> of atoms that make up the path (i.e. they are sequentially connected).</para>
        /// </summary>
        /// <param name="atomContainer">The molecule to consider</param>
        /// <param name="start">The starting atom</param>
        /// <param name="length">The maximum length of paths to look for</param>
        /// <returns>A <see cref="IList{T}"/> of <see cref="IList{T}"/> of <see cref="IAtom"/> containing the paths found</returns>
        public static IList <IList <IAtom> > GetPathsOfLengthUpto(IAtomContainer atomContainer, IAtom start, int length)
        {
            IList <IAtom>         curPath  = new List <IAtom>();
            List <IList <IAtom> > paths    = new List <IList <IAtom> >();
            List <IList <IAtom> > allpaths = new List <IList <IAtom> >();

            curPath.Add(start);
            paths.Add(curPath);
            allpaths.Add(curPath);
            for (int i = 0; i < length; i++)
            {
                IList <IList <IAtom> > tmpList = new List <IList <IAtom> >();
                foreach (var path in paths)
                {
                    curPath = path;
                    IAtom lastVertex = curPath[curPath.Count - 1];
                    var   neighbors  = atomContainer.GetConnectedAtoms(lastVertex);
                    foreach (var neighbor in neighbors)
                    {
                        List <IAtom> newPath = new List <IAtom>(curPath);
                        if (newPath.Contains(neighbor))
                        {
                            continue;
                        }
                        newPath.Add(neighbor);
                        tmpList.Add(newPath);
                    }
                }
                paths.Clear();
                paths.AddRange(tmpList);
                allpaths.AddRange(tmpList);
            }
            return(allpaths);
        }
Пример #7
0
        /// <summary>
        /// get the electrostatic potential of the neighbours of a atom.
        /// </summary>
        /// <param name="ac">The IAtomContainer to study</param>
        /// <param name="atom1">The position of the IAtom to study</param>
        /// <param name="ds"></param>
        /// <returns>The sum of electrostatic potential of the neighbours</returns>
        private double GetElectrostaticPotentialN(IAtomContainer ac, int atom1, double[] ds)
        {
            //        double CoulombForceConstant = 1/(4*Math.PI*8.81/*Math.Pow(10, -12)*/);
            double CoulombForceConstant = 0.048;
            double sum = 0.0;

            try
            {
                var atoms = ac.GetConnectedAtoms(ac.Atoms[atom1]);
                foreach (var atom in atoms)
                {
                    double    covalentradius = 0;
                    string    symbol         = atom.Symbol;
                    IAtomType type           = factory.GetAtomType(symbol);
                    covalentradius = type.CovalentRadius.Value;

                    double charge = ds[StepSize * atom1 + atom1 + 5];
                    Debug.WriteLine($"sum_({sum}) = CFC({CoulombForceConstant})*Charge({charge}/ret({covalentradius}");
                    sum += CoulombForceConstant * charge / (covalentradius * covalentradius);
                }
            }
            catch (CDKException e)
            {
                Debug.WriteLine(e);
            }

            return(sum);
        }
        private static List <List <int> > LabelAtoms(IAtomContainer atomCont)
        {
            List <List <int> > labelList = new List <List <int> >();

            for (int i = 0; i < atomCont.Atoms.Count; i++)
            {
                LabelContainer labelContainer = LabelContainer.Instance;
                List <int>     label          = new List <int>(7);
                //            label.SetSize(7);

                for (int a = 0; a < 7; a++)
                {
                    label.Insert(a, 0);
                }

                IAtom  refAtom   = atomCont.Atoms[i];
                string atom1Type = refAtom.Symbol;

                label[0] = labelContainer.GetLabelID(atom1Type);

                int countNeighbors = 1;
                var connAtoms      = atomCont.GetConnectedAtoms(refAtom);

                foreach (var negAtom in connAtoms)
                {
                    string atom2Type = negAtom.Symbol;
                    label[countNeighbors++] = labelContainer.GetLabelID(atom2Type);
                }

                BubbleSort(label);
                labelList.Add(label);
            }
            return(labelList);
        }
Пример #9
0
        /// <summary>
        /// Create initial invariant labeling corresponds to step 1
        /// </summary>
        /// <returns>List containing the</returns>
        private static List <InvPair> CreateInvarLabel(IAtomContainer atomContainer)
        {
            var           atoms = atomContainer.Atoms;
            StringBuilder inv;
            var           vect = new List <InvPair>();

            foreach (var a in atoms)
            {
                inv = new StringBuilder();
                var connectedAtoms = atomContainer.GetConnectedAtoms(a).ToReadOnlyList();
                inv.Append(connectedAtoms.Count + (a.ImplicitHydrogenCount ?? 0)); //Num connections
                inv.Append(connectedAtoms.Count);                                  //Num of non H bonds
                inv.Append(PeriodicTable.GetAtomicNumber(a.Symbol));

                double charge = a.Charge ?? 0;
                if (charge < 0) //Sign of charge
                {
                    inv.Append(1);
                }
                else
                {
                    inv.Append(0);                                //Absolute charge
                }
                inv.Append((int)Math.Abs((a.FormalCharge ?? 0))); //Hydrogen count
                inv.Append((a.ImplicitHydrogenCount ?? 0));
                vect.Add(new InvPair(long.Parse(inv.ToString(), NumberFormatInfo.InvariantInfo), a));
            }
            return(vect);
        }
Пример #10
0
        // FIXME: class JavaDoc should use <token>cdk-cite-BLA</token> for the CDK News article

        /// <summary>
        /// Tells if a certain bond is center of a valid double bond configuration.
        /// </summary>
        /// <param name="container">The atom container.</param>
        /// <param name="bond">The bond.</param>
        /// <returns>true=is a potential configuration, false=is not.</returns>
        public static bool IsValidDoubleBondConfiguration(IAtomContainer container, IBond bond)
        {
            //IAtom[] atoms = bond.GetAtoms();
            var   connectedAtoms = container.GetConnectedAtoms(bond.Begin);
            IAtom from           = null;

            foreach (var connectedAtom in connectedAtoms)
            {
                if (connectedAtom != bond.End)
                {
                    from = connectedAtom;
                }
            }
            bool[] array = new bool[container.Bonds.Count];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = true;
            }
            if (IsStartOfDoubleBond(container, bond.Begin, from, array) &&
                IsEndOfDoubleBond(container, bond.End, bond.Begin, array) &&
                !bond.IsAromatic)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
 /// <summary>
 /// Gets a randomly selected unsaturated atom from the set. If there are any, it will be from another
 /// container than exclusionAtom.
 /// </summary>
 /// <returns>The unsaturated atom.</returns>
 private IAtom GetAnotherUnsaturatedNode(IAtom exclusionAtom, IAtomContainer exclusionAtomContainer, IChemObjectSet <IAtomContainer> atomContainers)
 {
     foreach (var ac in atomContainers)
     {
         if (ac != exclusionAtomContainer)
         {
             int next = 0;//(int) (Math.Random() * ac.Atoms.Count);
             for (int f = next; f < ac.Atoms.Count; f++)
             {
                 var atom = ac.Atoms[f];
                 if (!satCheck.IsSaturated(atom, ac) && exclusionAtom != atom)
                 {
                     return(atom);
                 }
             }
         }
     }
     {
         var next = exclusionAtomContainer.Atoms.Count;//(int) (Math.random() * ac.getAtomCount());
         for (int f = 0; f < next; f++)
         {
             var atom = exclusionAtomContainer.Atoms[f];
             if (!satCheck.IsSaturated(atom, exclusionAtomContainer) &&
                 exclusionAtom != atom &&
                 !exclusionAtomContainer.GetConnectedAtoms(exclusionAtom).Contains(atom))
             {
                 return(atom);
             }
         }
     }
     return(null);
 }
Пример #12
0
 private static IAtomContainer RecomputeHydrogens(IAtomContainer mol, IAtomContainer atomContainer, List <IAtom> remove, CDKObjectMap map)
 {
     // Recompute hydrogen counts of neighbours of removed Hydrogens.
     foreach (var aRemove in remove)
     {
         // Process neighbours.
         foreach (var iAtom in atomContainer.GetConnectedAtoms(aRemove))
         {
             if (!map.TryGetValue(iAtom, out IAtom neighb))
             {
                 continue; // since for the case of H2, neight H has atom heavy atom neighbor
             }
             //Added by Asad
             if (!(neighb is IPseudoAtom))
             {
                 neighb.ImplicitHydrogenCount = (neighb.ImplicitHydrogenCount ?? 0) + 1;
             }
             else
             {
                 neighb.ImplicitHydrogenCount = 0;
             }
         }
     }
     return(mol);
 }
Пример #13
0
        public TargetProperties(IAtomContainer container)
        {
            int i = 0;

            atoms      = new Dictionary <IAtom, int>();
            atomsIndex = new Dictionary <int, IAtom>();
            connectedTargetAtomCountMap = new Dictionary <IAtom, int>();
            connectedTargetAtomListMap  = new Dictionary <IAtom, IReadOnlyList <IAtom> >();
            map = Arrays.CreateJagged <IBond>(container.Atoms.Count, container.Atoms.Count);
            foreach (var atom in container.Atoms)
            {
                int count = container.GetConnectedBonds(atom).Count();
                connectedTargetAtomCountMap[atom] = count;
                var list = container.GetConnectedAtoms(atom);
                if (list != null)
                {
                    connectedTargetAtomListMap[atom] = list.ToReadOnlyList();
                }
                else
                {
                    connectedTargetAtomListMap[atom] = new List <IAtom>();
                }
                atoms[atom]   = i;
                atomsIndex[i] = atom;
                i++;
            }

            foreach (var bond in container.Bonds)
            {
                map[atoms[bond.Begin]][atoms[bond.End]] = bond;
                map[atoms[bond.End]][atoms[bond.Begin]] = bond;
            }
        }
Пример #14
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);
        }
Пример #15
0
        private static void FixPyridineNOxides(IAtomContainer atomContainer, IRingSet ringSet)
        {
            //convert n(=O) to [n+][O-]
            for (int i = 0; i < atomContainer.Atoms.Count; i++)
            {
                var ai = atomContainer.Atoms[i];

                if (ai.AtomicNumber.Equals(AtomicNumbers.N) &&
                    (ai.FormalCharge == null || ai.FormalCharge == 0))
                {
                    if (InRingSet(ai, ringSet))
                    {
                        var ca = atomContainer.GetConnectedAtoms(ai);
                        foreach (var caj in ca)
                        {
                            if (caj.AtomicNumber.Equals(AtomicNumbers.O) &&
                                atomContainer.GetBond(ai, caj).Order == BondOrder.Double)
                            {
                                ai.FormalCharge  = 1;
                                caj.FormalCharge = -1;
                                atomContainer.GetBond(ai, caj).Order = BondOrder.Single;
                            }
                        } // end for (int j=0;j<ca.Count;j++)
                    }     // end if (InRingSet(ai,ringSet)) {
                }         // end if (ai.Symbol.Equals("N") && ai.FormalCharge==0)
            }             // end for (int i=0;i<atomContainer.Atoms.Count;i++)
        }
Пример #16
0
        /// <summary>
        /// Is the {@code atom} a suppressible hydrogen and can be represented as
        /// implicit. A hydrogen is suppressible if it is not an ion, not the major
        /// isotope (i.e. it is a deuterium or tritium atom) and is not molecular
        /// hydrogen.
        /// </summary>
        /// <param name="container"> the structure </param>
        /// <param name="atom">      an atom in the structure </param>
        /// <returns> the atom is a hydrogen and it can be suppressed (implicit) </returns>
        private static bool suppressibleHydrogen(IAtomContainer container, IAtom atom)
        {
            // is the atom a hydrogen
            if (!"H".Equals(atom.Symbol))
            {
                return(false);
            }
            // is the hydrogen an ion?
            if (GetFormalCharge(atom) != 0)
            {
                return(false);
            }
            // is the hydrogen deuterium / tritium?
            if (GetMassNumber(atom) != 1)
            {
                return(false);
            }
            // molecule hydrogen with implicit H?
            if (atom.ImplicitHydrogenCount != null && (int)atom.ImplicitHydrogenCount != 0)
            {
                return(false);
            }
            // molecule hydrogen
            List <IAtom> neighbors = container.GetConnectedAtoms(atom) as List <IAtom>;

            if (neighbors.Count == 1 && neighbors[0].Symbol.Equals("H"))
            {
                return(false);
            }
            // what about bridging hydrogens?
            // hydrogens with atom-atom mapping?
            return(true);
        }
Пример #17
0
 /// <summary>
 /// Constructor
 /// <param name="queryContainer">query atom container</param>
 /// <param name="template">query atom</param>
 /// <param name="blockedPositions">/// <param name="shouldMatchBonds">bond matching flag</param></param>
 /// </summary>
 public DefaultVFAtomMatcher(IAtomContainer queryContainer, IAtom template, int blockedPositions,
                             bool shouldMatchBonds)
     : this(queryContainer, template, shouldMatchBonds)
 {
     this.maximumNeighbors = CountImplicitHydrogens(template) + queryContainer.GetConnectedAtoms(template).Count()
                             - blockedPositions;
 }
Пример #18
0
        /// <summary>
        /// Says if an atom as a center of a square planar chirality.
        /// This method uses wedge bonds. 3D coordinates are not taken into account. If there
        /// are no wedge bonds around a potential stereo center, it will not be found.
        /// </summary>
        /// <param name="atom">The atom which is the center</param>
        /// <param name="container">The atomContainer the atom is in</param>
        /// <returns>true=is square planar, false=is not</returns>
        public static bool IsSquarePlanar(IAtomContainer container, IAtom atom)
        {
            var atoms = container.GetConnectedAtoms(atom);

            if (atoms.Count() != 4)
            {
                return(false);
            }
            var bonds = container.GetConnectedBonds(atom);
            int up    = 0;
            int down  = 0;

            foreach (var bond in bonds)
            {
                switch (bond.Stereo)
                {
                case BondStereo.None:
                    break;

                case BondStereo.Up:
                    up++;
                    break;

                case BondStereo.Down:
                    down++;
                    break;
                }
            }
            return(up == 2 && down == 2 && !StereosAreOpposite(container, atom));
        }
        /// <summary>
        /// The method is a proton descriptor that evaluates if a proton is joined to a conjugated system.
        /// </summary>
        /// <param name="atom">The <see cref="IAtom"/> for which the <see cref="Result"/> is requested</param>
        /// <returns><see langword="true"/> if the proton is bonded to a conjugated system</returns>
        public Result Calculate(IAtom atom)
        {
            var clonedAtom = clonedAtomContainer.Atoms[container.Atoms.IndexOf(atom)];

            bool isProtonInPiSystem = false;

            if (atom.AtomicNumber.Equals(AtomicNumbers.H))
            {
                var detected   = acSet.GetEnumerator();
                var neighboors = clonedAtomContainer.GetConnectedAtoms(clonedAtom);
                foreach (var neighboor in neighboors)
                {
                    while (detected.MoveNext())
                    {
                        var detectedAC = detected.Current;
                        if (detectedAC != null && detectedAC.Contains(neighboor))
                        {
                            isProtonInPiSystem = true;
                            break;
                        }
                    }
                }
            }
            return(new Result(isProtonInPiSystem));
        }
Пример #20
0
        /// <summary>
        /// Checks whether the P atom is in a PO environment.
        /// </summary>
        /// <remarks>
        /// This environment is noted in Kier &amp; Hall (1986), page 20
        /// </remarks>
        /// <param name="atom">The P atom in question</param>
        /// <param name="atomContainer">The molecule containing the P atom</param>
        /// <returns>The empirical delta V if present in the above environment, -1 otherwise</returns>
        private static double DeltavPhosphorous(IAtom atom, IAtomContainer atomContainer)
        {
            if (!atom.AtomicNumber.Equals(AtomicNumbers.P))
            {
                return(-1);
            }

            var connected  = atomContainer.GetConnectedAtoms(atom);
            int conditions = 0;

            if (connected.Count() == 4)
            {
                conditions++;
            }

            foreach (var connectedAtom in connected)
            {
                if (connectedAtom.AtomicNumber.Equals(AtomicNumbers.O) &&
                    atomContainer.GetBond(atom, connectedAtom).Order == BondOrder.Double)
                {
                    conditions++;
                }
                if (atomContainer.GetBond(atom, connectedAtom).Order == BondOrder.Single)
                {
                    conditions++;
                }
            }
            if (conditions == 5)
            {
                return(2.22);
            }
            return(-1);
        }
Пример #21
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
        /// 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 static void Add3DCoordinates1(IAtomContainer atomContainer)
        {
            // atoms without coordinates
            var noCoords = atomContainer.Builder.NewAtomContainer();
            // get vector of possible referenceAtoms?
            var refAtoms = atomContainer.Builder.NewAtomContainer();

            foreach (var atom in atomContainer.Atoms)
            {
                // is this atom without 3D coords, and has only one ligand?
                if (atom.Point3D == null)
                {
                    var connectedAtoms = atomContainer.GetConnectedAtoms(atom).ToReadOnlyList();
                    if (connectedAtoms.Count == 1)
                    {
                        var refAtom = connectedAtoms[0];
                        if (refAtom.Point3D != null)
                        {
                            refAtoms.Atoms.Add(refAtom);
                            // store atoms with no coords and ref atoms in a
                            // single container
                            noCoords.Atoms.Add(atom);
                            noCoords.Atoms.Add(refAtom);
                            // bond is required to extract ligands
                            noCoords.Bonds.Add(atomContainer.Builder.NewBond(atom, refAtom, BondOrder.Single));
                        }
                    }
                }
            }
            // now add coordinates to ligands of reference atoms
            // use default length of 1.0, which can be adjusted later
            double length = 1;
            var    angle  = TypicalTetrahedralAngle;

            foreach (var refAtom in refAtoms.Atoms)
            {
                var noCoordLigands = noCoords.GetConnectedAtoms(refAtom).ToReadOnlyList();
                var nLigands       = noCoordLigands.Count;
                var nwanted        = nLigands;
                var elementType    = refAtom.Symbol;
                // try to deal with lone pairs on small hetero
                switch (refAtom.AtomicNumber)
                {
                case AtomicNumbers.N:
                case AtomicNumbers.O:
                case AtomicNumbers.S:
                    nwanted = 3;
                    break;
                }
                var newPoints = Calculate3DCoordinatesForLigands(atomContainer, refAtom, nwanted, length, angle);
                for (int j = 0; j < nLigands; j++)
                {
                    var ligand   = noCoordLigands[j];
                    var newPoint = RescaleBondLength(refAtom, ligand, newPoints[j].Value);
                    ligand.Point3D = newPoint;
                }
            }
        }
Пример #22
0
        /// <summary>
        /// Says if an atom as a center of a tetrahedral chirality.
        /// This method uses wedge bonds. 3D coordinates are not taken into account. If there
        /// are no wedge bonds around a potential stereo center, it will not be found.
        /// </summary>
        /// <param name="atom">The atom which is the center</param>
        /// <param name="container">The atomContainer the atom is in</param>
        /// <param name="strict"></param>
        /// <returns>0=is not tetrahedral; &gt;1 is a certain depiction of
        ///     tetrahedrality (evaluated in parse chain)</returns>
        public static int IsTetrahedral(IAtomContainer container, IAtom atom, bool strict)
        {
            var atoms = container.GetConnectedAtoms(atom);

            if (atoms.Count() != 4)
            {
                return(0);
            }
            var bonds = container.GetConnectedBonds(atom);
            int up    = 0;
            int down  = 0;

            foreach (var bond in bonds)
            {
                switch (bond.Stereo)
                {
                case BondStereo.None:
                    break;

                case BondStereo.Up:
                    up++;
                    break;

                case BondStereo.Down:
                    down++;
                    break;
                }
            }
            if (up == 1 && down == 1)
            {
                return(1);
            }
            if (up == 2 && down == 2)
            {
                if (StereosAreOpposite(container, atom))
                {
                    return(2);
                }
                return(0);
            }
            if (up == 1 && down == 0 && !strict)
            {
                return(3);
            }
            if (down == 1 && up == 0 && !strict)
            {
                return(4);
            }
            if (down == 2 && up == 1 && !strict)
            {
                return(5);
            }
            if (down == 1 && up == 2 && !strict)
            {
                return(6);
            }
            return(0);
        }
Пример #23
0
        /// <summary>
        /// Place hydrogens connected to the provided atom <paramref name="atom"/> using the
        /// specified <paramref name="bondLength"/>.
        /// </summary>
        /// <param name="container">atom container</param>
        /// <param name="atom"></param>
        /// <param name="bondLength">bond length to user</param>
        /// <exception cref="ArgumentException">thrown if the <paramref name="atom"/> or
        /// <i>container</i> was null or the atom has connected atoms which have not been placed.</exception>
        public void PlaceHydrogens2D(IAtomContainer container, IAtom atom, double bondLength)
        {
            if (atom.Point2D == null)
            {
                throw new ArgumentException("cannot place hydrogens on atom without coordinates");
            }

            Debug.WriteLine("placing hydrogens connected to atom ", atom.Symbol, ": ", atom.Point2D);
            Debug.WriteLine($"bond length{bondLength}");

            AtomPlacer atomPlacer = new AtomPlacer
            {
                Molecule = container ?? throw new ArgumentException("cannot place hydrogens, no container provided")
            };

            var            connected = container.GetConnectedAtoms(atom);
            IAtomContainer placed    = container.Builder.NewAtomContainer();
            IAtomContainer unplaced  = container.Builder.NewAtomContainer();

            // divide connected atoms into those which are have and haven't been placed
            foreach (var conAtom in connected)
            {
                if (conAtom.Point2D == null)
                {
                    if (conAtom.AtomicNumber.Equals(AtomicNumbers.H))
                    {
                        unplaced.Atoms.Add(conAtom);
                    }
                    else
                    {
                        throw new ArgumentException("cannot place hydrogens, atom has connected non-hydrogens without coordinates");
                    }
                }
                else
                {
                    placed.Atoms.Add(conAtom);
                }
            }

            Debug.WriteLine("Atom placement before procedure:");
            Debug.WriteLine("Centre atom ", atom.Symbol, ": ", atom.Point2D);
            for (int i = 0; i < unplaced.Atoms.Count; i++)
            {
                Debug.WriteLine("H-" + i, ": ", unplaced.Atoms[i].Point2D);
            }

            Vector2 centerPlacedAtoms = GeometryUtil.Get2DCenter(placed);

            atomPlacer.DistributePartners(atom, placed, centerPlacedAtoms, unplaced, bondLength);

            Debug.WriteLine("Atom placement after procedure:");
            Debug.WriteLine($"Centre atom {atom.Symbol}: {atom.Point2D}");
            for (int i = 0; i < unplaced.Atoms.Count; i++)
            {
                Debug.WriteLine($"H-{i}: {unplaced.Atoms[i].Point2D}");
            }
        }
    }
Пример #24
0
        /// <summary>
        /// Obtain the ligands connected to the 'atom' excluding 'exclude'. This is
        /// mainly meant as a utility for double-bond labelling.
        /// </summary>
        /// <param name="atom">an atom</param>
        /// <param name="container">a structure to which 'atom' belongs</param>
        /// <param name="exclude">exclude this atom - can not be null</param>
        /// <returns>the ligands</returns>
        private static IEnumerable <ILigand> GetLigands(IAtom atom, IAtomContainer container, IAtom exclude)
        {
            var neighbors = container.GetConnectedAtoms(atom);

            var ligands = neighbors
                          .Where(neighbor => neighbor != exclude)
                          .Select(neighbor => new Ligand(container, new VisitedAtoms(), atom, neighbor));

            return(ligands);
        }
Пример #25
0
        private static double[] GetPathWeights(List <IList <IAtom> > pathList, IAtomContainer atomContainer)
        {
            var pathWts = new double[pathList.Count];

            for (int i = 0; i < pathList.Count; i++)
            {
                var p = pathList[i];
                pathWts[i] = 1.0;
                for (int j = 0; j < p.Count - 1; j++)
                {
                    var a  = p[j];
                    var b  = p[j + 1];
                    var n1 = atomContainer.GetConnectedAtoms(a).Count();
                    var n2 = atomContainer.GetConnectedAtoms(b).Count();
                    pathWts[i] /= Math.Sqrt(n1 * n2);
                }
            }
            return(pathWts);
        }
Пример #26
0
        private bool MatchMaximumNeighbors(IAtomContainer targetContainer, IAtom targetAtom)
        {
            if (maximumNeighbors == -1 || !IsBondMatchFlag)
            {
                return(true);
            }

            int maximumTargetNeighbors = targetContainer.GetConnectedAtoms(targetAtom).Count();

            return(maximumTargetNeighbors >= maximumNeighbors);
        }
Пример #27
0
 /// <summary>
 /// Finds an neighbor connected to 'atom' which is not 'exclude1'
 /// or 'exclude2'. If no neighbor exists - null is returned.
 /// </summary>
 /// <param name="container"> structure </param>
 /// <param name="atom">      atom to find a neighbor of </param>
 /// <param name="exclude1">  the neighbor should not be this atom </param>
 /// <param name="exclude2">  the neighbor should also not be this atom </param>
 /// <returns> a neighbor of 'atom', null if not found </returns>
 private static IAtom findOther(IAtomContainer container, IAtom atom, IAtom exclude1, IAtom exclude2)
 {
     foreach (IAtom neighbor in container.GetConnectedAtoms(atom) as List <IAtom> )
     {
         if (neighbor != exclude1 && neighbor != exclude2)
         {
             return(neighbor);
         }
     }
     return(null);
 }
Пример #28
0
        private static bool HasUnsetNeighbour(IAtom atom, IAtomContainer ac)
        {
            var atoms = ac.GetConnectedAtoms(atom);

            foreach (var curAtom in atoms)
            {
                if (!curAtom.IsPlaced)
                {//&& atoms[i].Point3D == null) {
                    return(true);
                }
            }
            return(false);
        }
Пример #29
0
        public static void FixSulphurH(IAtomContainer m)
        {
            // removes extra H's attached to sulphurs
            for (int i = 0; i <= m.Atoms.Count - 1; i++)
            {
                var a = m.Atoms[i];

                if (a.AtomicNumber.Equals(AtomicNumbers.S))
                {
                    var connectedAtoms = m.GetConnectedAtoms(a);

                    int bondOrderSum = 0;

                    foreach (var conAtom in connectedAtoms)
                    {
                        if (!conAtom.AtomicNumber.Equals(AtomicNumbers.H))
                        {
                            IBond bond = m.GetBond(a, conAtom);
                            if (bond.Order == BondOrder.Single)
                            {
                                bondOrderSum += 1;
                            }
                            else if (bond.Order == BondOrder.Double)
                            {
                                bondOrderSum += 2;
                            }
                            else if (bond.Order == BondOrder.Triple)
                            {
                                bondOrderSum += 3;
                            }
                            else if (bond.Order == BondOrder.Quadruple)
                            {
                                bondOrderSum += 4;
                            }
                        }
                    }

                    if (bondOrderSum > 1)
                    {
                        foreach (var conAtom in connectedAtoms)
                        {
                            if (conAtom.AtomicNumber.Equals(AtomicNumbers.H))
                            {
                                m.RemoveAtom(conAtom);
                            }
                        }
                    }
                }
            }
        }
Пример #30
0
        /// <summary>
        /// Returns a placed neighbouring atom of a central atom atomA, which is not atomB.
        /// </summary>
        /// <param name="atomA">central atom (Atom)</param>
        /// <param name="atomB">atom connected to atomA (Atom)</param>
        /// <param name="ac">molecule</param>
        /// <returns>returns a connected atom (Atom)</returns>
        private static IAtom GetPlacedHeavyAtomInAtomContainer(IAtom atomA, IAtom atomB, IAtomContainer ac)
        {
            var   atoms = ac.GetConnectedAtoms(atomA);
            IAtom atom  = null;

            foreach (var curAtom in atoms)
            {
                if (curAtom.IsPlaced && !curAtom.AtomicNumber.Equals(AtomicNumbers.H) && curAtom != atomB)
                {
                    return(curAtom);
                }
            }
            return(atom);
        }