Example #1
0
        public void CopySgroups2()
        {
            var sgroups = new List <Sgroup>();
            var replace = new CDKObjectMap();

            IAtom a1 = new Mock <IAtom>().Object;
            IAtom a2 = new Mock <IAtom>().Object;
            IBond b1 = new Mock <IBond>().Object;
            IBond b2 = new Mock <IBond>().Object;

            IAtom a1copy = new Mock <IAtom>().Object;
            IAtom a2copy = new Mock <IAtom>().Object;
            IBond b1copy = new Mock <IBond>().Object;
            IBond b2copy = new Mock <IBond>().Object;

            replace.Add(a1, a1copy);
            replace.Add(a2, a2copy);
            replace.Add(b1, b1copy);
            replace.Add(b2, b2copy);

            Sgroup sgroup = new Sgroup
            {
                Type      = SgroupType.CtabStructureRepeatUnit,
                Subscript = "n"
            };

            sgroup.Atoms.Add(a1);
            sgroup.Atoms.Add(a2);
            sgroup.Bonds.Add(b1);
            sgroup.Bonds.Add(b2);
            sgroups.Add(sgroup);
            var    copied       = SgroupManipulator.Copy(sgroups, replace);
            Sgroup copiedSgroup = copied[0];

            Assert.AreNotSame(sgroup, copiedSgroup);
            Assert.AreEqual(sgroup.Type, copiedSgroup.Type);
            Assert.AreEqual(sgroup.Subscript, copiedSgroup.Subscript);
            Assert.IsFalse(Compares.AreDeepEqual(sgroup.Atoms, copiedSgroup.Atoms));
            Assert.IsFalse(Compares.AreDeepEqual(sgroup.Bonds, copiedSgroup.Bonds));
            Assert.IsTrue(copiedSgroup.Atoms.Contains(a1copy));
            Assert.IsTrue(copiedSgroup.Atoms.Contains(a2copy));
            Assert.IsTrue(copiedSgroup.Bonds.Contains(b1copy));
            Assert.IsTrue(copiedSgroup.Bonds.Contains(b2copy));
        }
Example #2
0
 public override ICDKObject Clone(CDKObjectMap map)
 {
     if (map == null)
     {
         throw new ArgumentNullException(nameof(map));
     }
     if (map.TryGetValue(this, out IAtom clone))
     {
         return(clone);
     }
     clone = (Atom)base.Clone(map);
     map.Add(this, clone);
     return(clone);
 }
Example #3
0
File: Bond.tt.cs Project: qize/NCDK
        public override ICDKObject Clone(CDKObjectMap map)
        {
            if (map == null)
            {
                throw new ArgumentNullException(nameof(map));
            }

            if (map.TryGetValue(this, out IBond iclone))
            {
                return(iclone);
            }
            var clone = (Bond)base.Clone(map);

            // clone all the Atoms
            if (atoms != null)
            {
                clone.InitAtoms(atoms.Select(n => (IAtom)n?.Clone(map)));
            }
            map.Add(this, clone);
            return(clone);
        }
Example #4
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);
        }