/// <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)); }
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); }
/// <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)); }
/// <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)); }
/// <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)); } }
/// <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); }
/// <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)); }
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); }