예제 #1
0
 /// <summary>
 /// Creates a QueryAtomContainer with the following settings:
 /// <c>QueryAtomContainer.Create(container,
 ///     ExprType.ELEMENT,
 ///     ExprType.IS_AROMATIC,
 ///     ExprType.ALIPHATIC_ORDER);
 /// </c>>
 /// </summary>
 /// <param name="container">The AtomContainer that stands as model</param>
 /// <returns>The new QueryAtomContainer created from container.</returns>
 public static QueryAtomContainer CreateAnyAtomForPseudoAtomQueryContainer(IAtomContainer container)
 {
     return(QueryAtomContainer.Create(container,
                                      ExprType.Element,
                                      ExprType.IsAromatic,
                                      ExprType.AliphaticOrder));
 }
예제 #2
0
        public static QueryAtomContainer CreateSymbolChargeIDQueryContainer(IAtomContainer container)
        {
            var queryContainer = new QueryAtomContainer();

            for (int i = 0; i < container.Atoms.Count; i++)
            {
                queryContainer.Atoms.Add(new SymbolChargeIDQueryAtom(container.Atoms[i]));
            }
            foreach (var bond in container.Bonds)
            {
                int index1 = container.Atoms.IndexOf(bond.Begin);
                int index2 = container.Atoms.IndexOf(bond.End);
                if (bond.IsAromatic)
                {
                    var qbond = new QueryBond(queryContainer.Atoms[index1],
                                              queryContainer.Atoms[index2],
                                              ExprType.IsAromatic);
                    queryContainer.Bonds.Add(qbond);
                }
                else
                {
                    QueryBond qbond = new QueryBond(queryContainer.Atoms[index1],
                                                    queryContainer.Atoms[index2],
                                                    ExprType.Order,
                                                    bond.Order.Numeric())
                    {
                        Order = bond.Order // backwards compatibility
                    };
                    queryContainer.Bonds.Add(qbond);
                }
            }
            return(queryContainer);
        }
예제 #3
0
 /// <summary>
 /// Creates a <see cref="QueryAtomContainer"/> with the following settings:
 /// <c>QueryAtomContainer.Create(container,
 ///     ExprType.ELEMENT,
 ///     ExprType.FORMAL_CHARGE,
 ///     ExprType.IS_AROMATIC,
 ///     ExprType.ORDER);</c>
 /// </summary>
 /// <param name="container">The <see cref="IAtomContainer"/> that stands as model</param>
 /// <returns>The new <see cref="QueryAtomContainer"/> created from container.</returns>
 public static QueryAtomContainer CreateSymbolAndChargeQueryContainer(IAtomContainer container)
 {
     return(QueryAtomContainer.Create(container,
                                      ExprType.Element,
                                      ExprType.FormalCharge,
                                      ExprType.IsAromatic,
                                      ExprType.Order));
 }
        public void Test12DimethylBenzene()
        {
            var            builder  = CDK.Builder;
            IAtomContainer molecule = builder.NewAtomContainer();

            molecule.Atoms.Add(builder.NewAtom("C"));
            molecule.Atoms.Add(builder.NewAtom("C"));
            molecule.Atoms.Add(builder.NewAtom("C"));
            molecule.Atoms.Add(builder.NewAtom("C"));
            molecule.Atoms.Add(builder.NewAtom("C"));
            molecule.Atoms.Add(builder.NewAtom("C"));
            molecule.Atoms.Add(builder.NewAtom("C"));
            molecule.Atoms.Add(builder.NewAtom("C"));
            molecule.AddBond(molecule.Atoms[0], molecule.Atoms[1], BondOrder.Single);
            molecule.AddBond(molecule.Atoms[1], molecule.Atoms[2], BondOrder.Double);
            molecule.AddBond(molecule.Atoms[2], molecule.Atoms[3], BondOrder.Single);
            molecule.AddBond(molecule.Atoms[3], molecule.Atoms[4], BondOrder.Double);
            molecule.AddBond(molecule.Atoms[4], molecule.Atoms[5], BondOrder.Single);
            molecule.AddBond(molecule.Atoms[5], molecule.Atoms[0], BondOrder.Double);
            molecule.AddBond(molecule.Atoms[0], molecule.Atoms[6], BondOrder.Single);
            molecule.AddBond(molecule.Atoms[1], molecule.Atoms[7], BondOrder.Single);

            // 2,3-dimethyl-1,3-butadiene matches
            IAtomContainer query1 = builder.NewAtomContainer();

            query1.Atoms.Add(builder.NewAtom("C"));
            query1.Atoms.Add(builder.NewAtom("C"));
            query1.Atoms.Add(builder.NewAtom("C"));
            query1.Atoms.Add(builder.NewAtom("C"));
            query1.Atoms.Add(builder.NewAtom("C"));
            query1.Atoms.Add(builder.NewAtom("C"));
            query1.AddBond(query1.Atoms[0], query1.Atoms[1], BondOrder.Single);
            query1.AddBond(query1.Atoms[1], query1.Atoms[2], BondOrder.Double);
            query1.AddBond(query1.Atoms[3], query1.Atoms[0], BondOrder.Double);
            query1.AddBond(query1.Atoms[0], query1.Atoms[4], BondOrder.Single);
            query1.AddBond(query1.Atoms[1], query1.Atoms[5], BondOrder.Single);
            QueryAtomContainer queryContainer1 = QueryAtomContainerCreator.CreateSymbolAndBondOrderQueryContainer(query1);

            Assert.IsTrue(new UniversalIsomorphismTester().IsSubgraph(molecule, queryContainer1));

            // 2,3-dimethyl-2-butene does not match
            IAtomContainer query2 = builder.NewAtomContainer();

            query2.Atoms.Add(builder.NewAtom("C"));
            query2.Atoms.Add(builder.NewAtom("C"));
            query2.Atoms.Add(builder.NewAtom("C"));
            query2.Atoms.Add(builder.NewAtom("C"));
            query2.Atoms.Add(builder.NewAtom("C"));
            query2.Atoms.Add(builder.NewAtom("C"));
            query2.AddBond(query2.Atoms[0], query2.Atoms[1], BondOrder.Double);
            query2.AddBond(query2.Atoms[1], query2.Atoms[2], BondOrder.Single);
            query2.AddBond(query2.Atoms[3], query2.Atoms[0], BondOrder.Single);
            query2.AddBond(query2.Atoms[0], query2.Atoms[4], BondOrder.Single);
            query2.AddBond(query2.Atoms[1], query2.Atoms[5], BondOrder.Single);
            QueryAtomContainer queryContainer2 = QueryAtomContainerCreator.CreateSymbolAndBondOrderQueryContainer(query2);

            Assert.IsFalse(new UniversalIsomorphismTester().IsSubgraph(molecule, queryContainer2));
        }
예제 #5
0
 /// <summary>
 /// Creates a <see cref="QueryAtomContainer"/> with the following settings:
 /// <c>QueryAtomContainer.Create(container,
 ///     Expr.Type.ALIPHATIC_ELEMENT,
 ///     Expr.Type.AROMATIC_ELEMENT,
 ///     Expr.Type.IS_AROMATIC,
 ///     Expr.Type.ALIPHATIC_ORDER,
 ///     Expr.Type.STEREOCHEMISTRY);</c>
 /// </summary>
 /// <param name="container">The <see cref="IAtomContainer"/> that stands as model</param>
 /// <returns>The new <see cref="QueryAtomContainer"/> created from container.</returns>
 public static QueryAtomContainer CreateBasicQueryContainer(IAtomContainer container)
 {
     return(QueryAtomContainer.Create(container,
                                      ExprType.AliphaticElement,
                                      ExprType.AromaticElement,
                                      ExprType.IsAromatic,
                                      ExprType.AliphaticOrder,
                                      ExprType.Stereochemistry));
 }
예제 #6
0
 /// <summary>
 /// Creates a QueryAtomContainer with the following settings:
 /// <c>
 /// // aromaticity = true
 /// QueryAtomContainer.Create(container, ExprType.IS_AROMATIC);
 /// // aromaticity = false
 /// QueryAtomContainer.Create(container);
 /// </c>
 /// </summary>
 /// <remarks>
 /// This method thus allows the user to search based only on connectivity.
 /// </remarks>
 /// <param name="container">The AtomContainer that stands as the model</param>
 /// <param name="aromaticity">option flag</param>
 /// <returns>The new QueryAtomContainer</returns>
 public static QueryAtomContainer CreateAnyAtomAnyBondContainer(IAtomContainer container, bool aromaticity)
 {
     if (aromaticity)
     {
         return(QueryAtomContainer.Create(container, ExprType.IsAromatic));
     }
     else
     {
         return(QueryAtomContainer.Create(container));
     }
 }
예제 #7
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);
        }
예제 #8
0
 /// <summary>
 /// Creates a <see cref="QueryAtomContainer"/> with the following settings:
 /// <c>QueryAtomContainer.Create(container,
 ///     ExprType.ELEMENT,
 ///     ExprType.ORDER);</c>
 /// </summary>
 /// <param name="container">The AtomContainer that stands as model</param>
 /// <returns>The new QueryAtomContainer created from container.</returns>
 public static QueryAtomContainer CreateSymbolAndBondOrderQueryContainer(IAtomContainer container)
 {
     return(QueryAtomContainer.Create(container,
                                      ExprType.Element,
                                      ExprType.Order));
 }
예제 #9
0
        public static IAtomContainer SuppressQueryHydrogens(IAtomContainer mol)
        {
            // pre-checks
            foreach (var atom in mol.Atoms)
            {
                if (!(AtomRef.Deref(atom) is QueryAtom))
                {
                    throw new ArgumentException("Non-query atoms found!", nameof(mol));
                }
            }
            foreach (var bond in mol.Bonds)
            {
                if (!(BondRef.Deref(bond) is QueryBond))
                {
                    throw new ArgumentException("Non-query bonds found!", nameof(mol));
                }
            }

            var plainHydrogens = new CDKObjectMap();

            foreach (var atom in mol.Atoms)
            {
                int hcnt = 0;
                foreach (var nbor in mol.GetConnectedAtoms(atom))
                {
                    var qnbor = (QueryAtom)AtomRef.Deref(nbor);
                    if (mol.GetConnectedBonds(nbor).Count() == 1 &&
                        IsSimpleHydrogen(qnbor.Expression))
                    {
                        hcnt++;
                        plainHydrogens.Set(nbor, atom);
                    }
                }
                if (hcnt > 0)
                {
                    var qatom = (QueryAtom)AtomRef.Deref(atom);
                    var e     = qatom.Expression;
                    var hexpr = new Expr();
                    for (int i = 0; i < hcnt; i++)
                    {
                        hexpr.And(new Expr(ExprType.TotalHCount, i).Negate());
                    }
                    e.And(hexpr);
                }
            }

            // nothing to do
            if (!plainHydrogens.Any())
            {
                return(mol);
            }

            var res = new QueryAtomContainer();

            foreach (var atom in mol.Atoms)
            {
                if (!plainHydrogens.ContainsKey(atom))
                {
                    res.Atoms.Add(atom);
                }
            }
            foreach (var bond in mol.Bonds)
            {
                if (!plainHydrogens.ContainsKey(bond.Begin) &&
                    !plainHydrogens.ContainsKey(bond.End))
                {
                    res.Bonds.Add(bond);
                }
            }
            foreach (var se in mol.StereoElements)
            {
                res.StereoElements.Add((IStereoElement <IChemObject, IChemObject>)se.Clone(plainHydrogens));
            }

            return(res);
        }