예제 #1
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone = (LonePair)base.Clone(map);

            clone.atom = (IAtom)atom?.Clone(map);
            return(clone);
        }
예제 #2
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone = (SingleElectron)base.Clone(map);

            clone.atom = (IAtom)atom?.Clone(map);
            return(clone);
        }
예제 #3
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            FragmentAtom clone = (FragmentAtom)base.Clone(map);

            clone.Fragment   = (IAtomContainer)Fragment.Clone(map);
            clone.IsExpanded = IsExpanded;
            return(clone);
        }
예제 #4
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            ChemModel clone = (ChemModel)base.Clone(map);

            clone.setOfMolecules = (IChemObjectSet <IAtomContainer>)setOfMolecules?.Clone(map);
            clone.setOfReactions = (IReactionSet)setOfReactions?.Clone(map);
            clone.ringSet        = (IRingSet)ringSet?.Clone(map);
            clone.crystal        = (ICrystal)crystal?.Clone(map);
            return(clone);
        }
예제 #5
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone = (Mapping)base.Clone(map);

            clone.relation = new IAtom[relation.Length];
            for (var i = 0; i < relation.Length; i++)
            {
                clone.relation[i] = (IAtom)relation[i].Clone(map);
            }
            return(clone);
        }
예제 #6
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone = (ChemFile)base.Clone(map);

            clone.chemSequences = new List <IChemSequence>();
            foreach (var chemSequence in chemSequences)
            {
                clone.chemSequences.Add((IChemSequence)chemSequence.Clone());
            }
            return(clone);
        }
예제 #7
0
        /// <inheritdoc/>
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var reactionScheme = new List <IReactionScheme>();

            foreach (var scheme in Schemes)
            {
                reactionScheme.Add((IReactionScheme)scheme.Clone(map));
            }
            ReactionScheme clone = (ReactionScheme)base.Clone(map);

            clone.reactionScheme = reactionScheme;
            return(clone);
        }
예제 #8
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone_chemModels = new List <IChemModel>();

            foreach (var chemModel in chemModels)
            {
                clone_chemModels.Add((IChemModel)chemModel.Clone(map));
            }
            var clone = (ChemSequence)base.Clone(map);

            clone.chemModels = clone_chemModels;
            return(clone);
        }
예제 #9
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone = (ChemObjectSet <T>)base.Clone(map);

            clone.atomContainers = new List <T>(atomContainers.Count);
            clone.multipliers    = new List <double?>(atomContainers.Count);
            for (var i = 0; i < atomContainers.Count; i++)
            {
                clone.atomContainers.Add((T)atomContainers[i].Clone(map));
                clone.multipliers.Add(multipliers[i]);
            }
            return(clone);
        }
예제 #10
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clonedReactions = new List <IReaction>();

            foreach (var reaction in reactions)
            {
                clonedReactions.Add((IReaction)reaction.Clone(map));
            }
            var clone = (ReactionSet)base.Clone(map);

            clone.reactions = clonedReactions;
            return(clone);
        }
예제 #11
0
        public void TestMap_Map_Map()
        {
            IChemObjectBuilder builder = ChemObjectBuilder.Instance;

            IAtom c1 = builder.NewAtom("C");
            IAtom o2 = builder.NewAtom("O");
            IAtom n3 = builder.NewAtom("N");
            IAtom c4 = builder.NewAtom("C");
            IAtom h5 = builder.NewAtom("H");

            // new stereo element
            ITetrahedralChirality original = new TetrahedralChirality(c1, new IAtom[] { o2, n3, c4, h5 }, TetrahedralStereo.Clockwise);

            // clone the atoms and place in a map
            var   mapping = new CDKObjectMap();
            IAtom c1clone = (IAtom)c1.Clone();

            mapping.Set(c1, c1clone);
            IAtom o2clone = (IAtom)o2.Clone();

            mapping.Set(o2, o2clone);
            IAtom n3clone = (IAtom)n3.Clone();

            mapping.Set(n3, n3clone);
            IAtom c4clone = (IAtom)c4.Clone();

            mapping.Set(c4, c4clone);
            IAtom h5clone = (IAtom)h5.Clone();

            mapping.Set(h5, h5clone);

            // map the existing element a new element
            ITetrahedralChirality mapped = (ITetrahedralChirality)original.Clone(mapping);

            Assert.AreNotSame(original.ChiralAtom, mapped.ChiralAtom, "mapped chiral atom was the same as the original");
            Assert.AreSame(c1clone, mapped.ChiralAtom, "mapped chiral atom was not the clone");

            var originalLigands = original.Ligands;
            var mappedLigands   = mapped.Ligands;

            Assert.AreNotSame(originalLigands[0], mappedLigands[0], "first ligand was the same as the original");
            Assert.AreSame(o2clone, mappedLigands[0], "first mapped ligand was not the clone");
            Assert.AreNotSame(originalLigands[1], mappedLigands[1], "second ligand was the same as the original");
            Assert.AreSame(n3clone, mappedLigands[1], "second mapped ligand was not the clone");
            Assert.AreNotSame(originalLigands[2], mappedLigands[2], "third ligand was the same as the original");
            Assert.AreSame(c4clone, mappedLigands[2], "third mapped ligand was not the clone");
            Assert.AreNotSame(originalLigands[3], mappedLigands[3], "forth ligand was te same as the original");
            Assert.AreSame(h5clone, mappedLigands[3], "forth mapped ligand was not the clone");

            Assert.AreEqual(original.Stereo, mapped.Stereo, "stereo was not mapped");
        }
예제 #12
0
        /// <inheritdoc/>
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone = (AminoAcid)base.Clone(map);

            if (nTerminus != null)
            {
                clone.nTerminus = clone.atoms[this.atoms.IndexOf(nTerminus)];
            }
            if (cTerminus != null)
            {
                clone.cTerminus = clone.atoms[this.atoms.IndexOf(cTerminus)];
            }
            return(clone);
        }
예제 #13
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone = (BioPolymer)base.Clone(map);

            clone.strands = new Dictionary <string, IStrand>();
            foreach (var strandPair in strands)
            {
                string  name     = strandPair.Key;
                IStrand original = strandPair.Value;
                IStrand cloned   = (IStrand)original.Clone(map);
                clone.strands.Add(name, cloned);
            }
            return(clone);
        }
예제 #14
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone = (Strand)base.Clone(map);

            clone.monomers = new Dictionary <string, IMonomer>();
            foreach (var pair in monomers)
            {
                string   monomerName   = pair.Key;
                IMonomer monomer       = pair.Value;
                var      clonedMonomer = (IMonomer)monomer.Clone(map);
                clone.monomers.Add(monomerName, clonedMonomer);
            }
            return(clone);
        }
예제 #15
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);
 }
예제 #16
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);
        }
예제 #17
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));
        }
예제 #18
0
        public void TestMap_Map_Map_EmptyMapping()
        {
            IChemObjectBuilder builder = ChemObjectBuilder.Instance;

            IAtom c1 = builder.NewAtom("C");
            IAtom o2 = builder.NewAtom("O");
            IAtom n3 = builder.NewAtom("N");
            IAtom c4 = builder.NewAtom("C");
            IAtom h5 = builder.NewAtom("H");

            // new stereo element
            ITetrahedralChirality original = new TetrahedralChirality(c1, new IAtom[] { o2, n3, c4, h5 }, TetrahedralStereo.Clockwise);

            // map the existing element a new element - should through an IllegalArgumentException
            var map = new CDKObjectMap();
            ITetrahedralChirality mapped = (ITetrahedralChirality)original.Clone(map);

            Assert.AreSame(original.ChiralAtom, mapped.ChiralAtom);
        }
예제 #19
0
파일: Bond.tt.cs 프로젝트: 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);
        }
예제 #20
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone_reactants = (IChemObjectSet <IAtomContainer>)reactants.Clone(map);
            var clone_agents    = (IChemObjectSet <IAtomContainer>)agents.Clone(map);
            var clone_products  = (IChemObjectSet <IAtomContainer>)products.Clone(map);

            var clone_mappings = new List <IMapping>();

            foreach (var mapping in mappings)
            {
                clone_mappings.Add((IMapping)mapping.Clone(map));
            }

            var clone = (Reaction)base.Clone(map);

            clone.reactants = clone_reactants;
            clone.agents    = clone_agents;
            clone.products  = clone_products;
            clone.mappings  = clone_mappings;

            return(clone);
        }
예제 #21
0
        public override ICDKObject Clone(CDKObjectMap map)
        {
            var clone = (Polymer)base.Clone(map);

            clone.monomers = new Dictionary <string, IMonomer>();
            foreach (var monomerInfo in monomers)
            {
                string   name     = monomerInfo.Key;
                IMonomer original = monomerInfo.Value;
                IMonomer cloned   = (IMonomer)original.Clone(map);
                clone.monomers.Add(name, cloned);
            }

            // update sgroups
            var sgroups = this.GetCtabSgroups();

            if (sgroups != null)
            {
                clone.SetCtabSgroups(SgroupManipulator.Copy(sgroups, map));
            }

            return(clone);
        }
예제 #22
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);
            }
        }
예제 #23
0
        /// <summary>
        /// Copy a collection of Sgroups, replacing any <see cref="IAtom"/>/<see cref="IBond"/>
        /// references with those present in the provided 'replace' map. If an empty
        /// replace map is provided (null or empty) the sgroups are simply
        /// duplicated. If an item is not present in the replacement map the original
        /// item is preserved.
        /// </summary>
        /// <example>
        /// <code>
        /// var replace = new Dictionary&lt;Sgroup, Sgroup&gt;();
        /// replace[orgAtom] = newAtom;
        /// replace[orgBond] = newBond;
        /// newSgroups = Copy(orgSgroups, replace);
        /// </code>
        /// </example>
        /// <param name="sgroups">collection of sgroups, can be null</param>
        /// <param name="replace">the replacement map, can be null</param>
        /// <returns>list of copied sgroups, null if sgroups input was null</returns>
        public static IList <Sgroup> Copy(IList <Sgroup> sgroups, CDKObjectMap replace)
        {
            if (sgroups == null)
            {
                return(null);
            }
            var sgroupMap = new Dictionary <Sgroup, Sgroup>();

            foreach (var sgroup in sgroups)
            {
                sgroupMap[sgroup] = new Sgroup();
            }
            foreach (var e in sgroupMap)
            {
                var orgSgroup = e.Key;
                var cpySgroup = e.Value;
                cpySgroup.Type = orgSgroup.Type;
                foreach (var atom in orgSgroup.Atoms)
                {
                    cpySgroup.Atoms.Add(Get(replace, atom));
                }
                foreach (var bond in orgSgroup.Bonds)
                {
                    cpySgroup.Bonds.Add(Get(replace, bond));
                }
                foreach (var parent in orgSgroup.Parents)
                {
                    cpySgroup.Parents.Add(sgroupMap[parent]);
                }
                foreach (var key in SgroupTool.SgroupKeyValues)
                {
                    switch (key)
                    {
                    case SgroupKey.CtabParentAtomList:
                    {
                        var orgVal = (ICollection <IAtom>)orgSgroup.GetValue(key);
                        if (orgVal != null)
                        {
                            var cpyVal = new List <IAtom>();
                            foreach (IAtom atom in orgVal)
                            {
                                cpyVal.Add(Get(replace, atom));
                            }
                            cpySgroup.PutValue(key, cpyVal);
                        }
                    }
                    break;

                    case SgroupKey.CtabBracket:
                    {
                        var orgVals = (ICollection <SgroupBracket>)orgSgroup.GetValue(key);
                        if (orgVals != null)
                        {
                            foreach (var bracket in orgVals)
                            {
                                cpySgroup.AddBracket(new SgroupBracket(bracket));
                            }
                        }
                    }
                    break;

                    default:
                        // primitive values, String, Integer are immutable
                        object val = orgSgroup.GetValue(key);
                        if (val != null)
                        {
                            cpySgroup.PutValue(key, val);
                        }
                        break;
                    }
                }
            }
            return(new List <Sgroup>(sgroupMap.Values));
        }
예제 #24
0
 public ICDKObject Clone(CDKObjectMap map) => this;
예제 #25
0
 public ICDKObject Clone(CDKObjectMap map)
 {
     throw new InvalidOperationException("not supported");
 }
예제 #26
0
 public ICDKObject Clone(CDKObjectMap map) => (ICDKObject)Clone();
예제 #27
0
 public ICDKObject Clone(CDKObjectMap map)
 {
     return((ImmutableAtomType)this.MemberwiseClone());
 }
예제 #28
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);
 }
예제 #29
0
 public override ICDKObject Clone(CDKObjectMap map)
 {
     return(base.Clone(map));
 }
예제 #30
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);
        }