Пример #1
0
        private static T Get <T>(CDKObjectMap map, T obj) where T : IChemObject
        {
            if (map == null)
            {
                return(obj);
            }
            T val = map.Get(obj);

            if (val == null)
            {
                return(obj);
            }
            return(val);
        }
Пример #2
0
        /// <summary>
        /// Returns IAtomContainer without Hydrogen. If an AtomContainer has atom single atom which
        /// is atom Hydrogen then its not removed.
        /// </summary>
        /// <param name="atomContainer"></param>
        /// <returns>IAtomContainer without Hydrogen. If an AtomContainer has atom single atom which is atom Hydrogen then its not removed.</returns>
        public static IAtomContainer RemoveHydrogensExceptSingleAndPreserveAtomID(IAtomContainer atomContainer)
        {
            var map = new CDKObjectMap(); // maps original object to clones.

            if (atomContainer.Bonds.Count > 0)
            {
                var          mol    = (IAtomContainer)atomContainer.Clone(map);
                List <IAtom> remove = new List <IAtom>(); // lists removed Hs.
                foreach (var atom in atomContainer.Atoms)
                {
                    if (atom.AtomicNumber.Equals(AtomicNumbers.H))
                    {
                        remove.Add(atom);
                    }
                }
                foreach (var a in remove)
                {
                    mol.RemoveAtomAndConnectedElectronContainers(map.Get(a));
                }
                foreach (var atom in mol.Atoms.Where(n => !n.ImplicitHydrogenCount.HasValue))
                {
                    atom.ImplicitHydrogenCount = 0;
                }
                //            Recompute hydrogen counts of neighbours of removed Hydrogens.
                mol = RecomputeHydrogens(mol, atomContainer, remove, map);
                return(mol);
            }
            else
            {
                var mol = (IAtomContainer)atomContainer.Clone(map);
                if (string.Equals(atomContainer.Atoms[0].Symbol, "H", StringComparison.OrdinalIgnoreCase))
                {
                    Console.Error.WriteLine("WARNING: single hydrogen atom removal not supported!");
                }
                return(mol);
            }
        }
Пример #3
0
        /// <summary>
        /// Create a query from a molecule and a provided set of expressions. The
        /// molecule is converted and any features specified in the <paramref name="opts"/>
        /// will be matched.
        /// </summary>
        /// <remarks>
        /// A good starting point is the following options:
        /// <include file='IncludeExamples.xml' path='Comments/Codes[@id="NCDK.Isomorphisms.Matchers.QueryAtomContainer_Example.cs+Create1"]/*' />
        /// Specifying <see cref="ExprType.Degree"/> (or <see cref="ExprType.TotalDegree"/> +
        /// <see cref="ExprType.ImplicitHCount"/>) means the molecule will not match as a
        /// substructure.
        /// <include file='IncludeExamples.xml' path='Comments/Codes[@id="NCDK.Isomorphisms.Matchers.QueryAtomContainer_Example.cs+Create2"]/*' />
        /// The <see cref="ExprType.RingBondCount"/> property is useful for locking in
        /// ring systems. Specifying the ring bond count on benzene means it will
        /// not match larger ring systems (e.g. naphthalenee) but can still be
        /// substituted.
        /// <include file='IncludeExamples.xml' path='Comments/Codes[@id="NCDK.Isomorphisms.Matchers.QueryAtomContainer_Example.cs+Create3"]/*' />
        /// Note that <see cref="ExprType.FormalCharge"/>,
        /// <see cref="ExprType.ImplicitHCount"/>, and <see cref="ExprType.Isotope"/> are ignored
        /// if <see langword="null"/>. Explicitly setting these to zero (only required for Isotope from
        /// SMILES) forces their inclusion.
        /// <include file='IncludeExamples.xml' path='Comments/Codes[@id="NCDK.Isomorphisms.Matchers.QueryAtomContainer_Example.cs+Create4"]/*' />
        /// Please note not all <see cref="ExprType"/>s are currently supported, if you
        /// require a specific type that you think is useful please open an issue.
        /// </remarks>
        /// <param name="mol">the molecule</param>
        /// <param name="opts">set of the expr types to match</param>
        /// <returns>the query molecule</returns>
        public static QueryAtomContainer Create(IAtomContainer mol, params ExprType[] opts)
        {
            var optset  = new HashSet <ExprType>(opts);
            var query   = new QueryAtomContainer();
            var mapping = new CDKObjectMap();
            var stereos = new Dictionary <IChemObject, IStereoElement <IChemObject, IChemObject> >();

            foreach (var se in mol.StereoElements)
            {
                stereos[se.Focus] = se;
            }
            var qstereo = new List <IStereoElement <IChemObject, IChemObject> >();

            foreach (var atom in mol.Atoms)
            {
                var expr = new Expr();
                // isotope first
                if (optset.Contains(ExprType.Isotope) && atom.MassNumber != null)
                {
                    expr.And(new Expr(ExprType.Isotope, atom.MassNumber.Value));
                }
                if (atom.AtomicNumber != 0)
                {
                    if (atom.IsAromatic)
                    {
                        if (optset.Contains(ExprType.AromaticElement))
                        {
                            expr.And(new Expr(ExprType.AromaticElement,
                                              atom.AtomicNumber));
                        }
                        else
                        {
                            if (optset.Contains(ExprType.IsAromatic))
                            {
                                if (optset.Contains(ExprType.Element))
                                {
                                    expr.And(new Expr(ExprType.AromaticElement,
                                                      atom.AtomicNumber));
                                }
                                else
                                {
                                    expr.And(new Expr(ExprType.IsAromatic));
                                }
                            }
                            else if (optset.Contains(ExprType.Element))
                            {
                                expr.And(new Expr(ExprType.Element,
                                                  atom.AtomicNumber));
                            }
                        }
                    }
                    else
                    {
                        if (optset.Contains(ExprType.AliphaticElement))
                        {
                            expr.And(new Expr(ExprType.AliphaticElement,
                                              atom.AtomicNumber));
                        }
                        else
                        {
                            if (optset.Contains(ExprType.IsAliphatic))
                            {
                                if (optset.Contains(ExprType.Element))
                                {
                                    expr.And(new Expr(ExprType.AliphaticElement,
                                                      atom.AtomicNumber));
                                }
                                else
                                {
                                    expr.And(new Expr(ExprType.IsAliphatic));
                                }
                            }
                            else if (optset.Contains(ExprType.Element))
                            {
                                expr.And(new Expr(ExprType.Element,
                                                  atom.AtomicNumber));
                            }
                        }
                    }
                }
                if (optset.Contains(ExprType.Degree))
                {
                    expr.And(new Expr(ExprType.Degree, atom.Bonds.Count));
                }
                if (optset.Contains(ExprType.TotalDegree))
                {
                    expr.And(new Expr(ExprType.Degree, atom.Bonds.Count + atom.ImplicitHydrogenCount.Value));
                }
                if (optset.Contains(ExprType.IsInRing) ||
                    optset.Contains(ExprType.IsInChain))
                {
                    expr.And(new Expr(atom.IsInRing ? ExprType.IsInRing : ExprType.IsInChain));
                }
                if (optset.Contains(ExprType.ImplicitHCount))
                {
                    expr.And(new Expr(ExprType.ImplicitHCount));
                }
                if (optset.Contains(ExprType.RingBondCount))
                {
                    int rbonds = 0;
                    foreach (var bond in mol.GetConnectedBonds(atom))
                    {
                        if (bond.IsInRing)
                        {
                            rbonds++;
                        }
                    }
                    expr.And(new Expr(ExprType.RingBondCount, rbonds));
                }
                if (optset.Contains(ExprType.FormalCharge) && atom.FormalCharge != null)
                {
                    expr.And(new Expr(ExprType.FormalCharge, atom.FormalCharge.Value));
                }
                if (stereos.TryGetValue(atom, out IStereoElement <IChemObject, IChemObject> se) &&
                    se.Class == StereoClass.Tetrahedral &&
                    optset.Contains(ExprType.Stereochemistry))
                {
                    expr.And(new Expr(ExprType.Stereochemistry, (int)se.Configure));
                    qstereo.Add(se);
                }
                var qatom = new QueryAtom(expr);
                // backward compatibility for naughty methods that are expecting
                // these to be set for a query!
                if (optset.Contains(ExprType.Element) ||
                    optset.Contains(ExprType.AromaticElement) ||
                    optset.Contains(ExprType.AliphaticElement))
                {
                    qatom.Symbol = atom.Symbol;
                }
                if (optset.Contains(ExprType.AromaticElement) ||
                    optset.Contains(ExprType.IsAromatic))
                {
                    qatom.IsAromatic = atom.IsAromatic;
                }
                mapping.Add(atom, qatom);
                query.Atoms.Add(qatom);
            }
            foreach (var bond in mol.Bonds)
            {
                var expr = new Expr();
                if (bond.IsAromatic &&
                    (optset.Contains(ExprType.SingleOrAromatic) ||
                     optset.Contains(ExprType.DoubleOrAromatic) ||
                     optset.Contains(ExprType.IsAromatic)))
                {
                    expr.And(new Expr(ExprType.IsAromatic));
                }
                else if ((optset.Contains(ExprType.SingleOrAromatic) ||
                          optset.Contains(ExprType.DoubleOrAromatic) ||
                          optset.Contains(ExprType.AliphaticOrder)) && !bond.IsAromatic)
                {
                    expr.And(new Expr(ExprType.AliphaticOrder, bond.Order.Numeric()));
                }
                else if (bond.IsAromatic && optset.Contains(ExprType.IsAliphatic))
                {
                    expr.And(new Expr(ExprType.IsAliphatic));
                }
                else if (optset.Contains(ExprType.Order))
                {
                    expr.And(new Expr(ExprType.Order, bond.Order.Numeric()));
                }
                if (optset.Contains(ExprType.IsInRing) && bond.IsInRing)
                {
                    expr.And(new Expr(ExprType.IsInRing));
                }
                else if (optset.Contains(ExprType.IsInChain) && !bond.IsInRing)
                {
                    expr.And(new Expr(ExprType.IsInChain));
                }
                if (stereos.TryGetValue(bond, out IStereoElement <IChemObject, IChemObject> se) &&
                    optset.Contains(ExprType.Stereochemistry))
                {
                    expr.And(new Expr(ExprType.Stereochemistry, (int)se.Configure));
                    qstereo.Add(se);
                }
                var qbond = new QueryBond(mapping.Get(bond.Begin), mapping.Get(bond.End), expr);
                // backward compatibility for naughty methods that are expecting
                // these to be set for a query!
                if (optset.Contains(ExprType.AliphaticOrder) ||
                    optset.Contains(ExprType.Order))
                {
                    qbond.Order = bond.Order;
                }
                if (optset.Contains(ExprType.SingleOrAromatic) ||
                    optset.Contains(ExprType.DoubleOrAromatic) ||
                    optset.Contains(ExprType.IsAromatic))
                {
                    qbond.IsAromatic = bond.IsAromatic;
                }
                mapping.Add(bond, qbond);
                query.Bonds.Add(qbond);
            }
            foreach (var se in qstereo)
            {
                query.StereoElements.Add((IStereoElement <IChemObject, IChemObject>)se.Clone(mapping));
            }
            return(query);
        }