示例#1
0
        /// <summary>
        /// Checks a carbon atom to see if it should be shown.
        /// </summary>
        /// <param name="carbonAtom">the carbon atom to check</param>
        /// <param name="container">the atom container</param>
        /// <param name="model">the renderer model</param>
        /// <returns>true if the carbon should be shown</returns>
        public virtual bool ShowCarbon(IAtom carbonAtom, IAtomContainer container, RendererModel model)
        {
            if (model.GetKekuleStructure())
            {
                return(true);
            }
            if (carbonAtom.FormalCharge != 0)
            {
                return(true);
            }
            int connectedBondCount = container.GetConnectedBonds(carbonAtom).Count();

            if (connectedBondCount < 1)
            {
                return(true);
            }
            if ((bool)model.GetShowEndCarbons() && connectedBondCount == 1)
            {
                return(true);
            }
            if (carbonAtom.GetProperty <bool>(ProblemMarker.ErrorMarker, false))
            {
                return(true);
            }
            if (container.GetConnectedSingleElectrons(carbonAtom).Any())
            {
                return(true);
            }
            return(false);
        }
示例#2
0
        public void TestSetAtomProperties_IAtomContainerSet_Object_Object()
        {
            string key   = "key";
            string value = "value";

            MoleculeSetManipulator.SetAtomProperties(som, key, value);
            Assert.AreEqual(value, atomInMol1.GetProperty <string>(key));
            Assert.AreEqual(value, atomInMol2.GetProperty <string>(key));
        }
示例#3
0
        public void TestSetAtomProperties_IChemModel_Object_Object()
        {
            string key   = "key";
            string value = "value";

            ChemModelManipulator.SetAtomProperties(chemModel, key, value);
            Assert.AreEqual(value, atomInMol1.GetProperty <string>(key));
            Assert.AreEqual(value, atomInMol2.GetProperty <string>(key));
        }
示例#4
0
        private static int AccessAtomMap(IAtom atom)
        {
            var mapidx = atom.GetProperty <int?>(CDKPropertyName.AtomAtomMapping);

            if (mapidx == null)
            {
                return(0);
            }
            return(mapidx.Value);
        }
示例#5
0
        /// <summary>
        /// Access the atom invariants for this atom. If the invariants have not been
        /// set an exception is thrown.
        /// </summary>
        /// <param name="atom">the atom to obtain the invariants of</param>
        /// <returns>the atom invariants for the atom</returns>
        /// <exception cref="NullReferenceException">thrown if the invariants were not set</exception>
        internal static SMARTSAtomInvariants Invariants(IAtom atom)
        {
            var inv = atom.GetProperty <SMARTSAtomInvariants>(SMARTSAtomInvariants.Key);

            if (inv == null)
            {
                throw new NullReferenceException("Missing SMARTSAtomInvariants - please compute these values before matching.");
            }
            return(inv);
        }
示例#6
0
        public object Visit(ASTReaction node, object data)
        {
            IAtomContainer query = new QueryAtomContainer(builder);

            for (int grpIdx = 0; grpIdx < node.JjtGetNumChildren(); grpIdx++)
            {
                int rollback = query.Atoms.Count;

                ASTGroup group = (ASTGroup)node.JjtGetChild(grpIdx);
                group.JjtAccept(this, query);

                // fill in the roles for newly create atoms
                if (group.Role != ReactionRoles.Any)
                {
                    IQueryAtom   roleQueryAtom = null;
                    ReactionRole?role          = null;

                    // use single instances
                    switch (group.Role)
                    {
                    case ReactionRoles.Reactant:
                        roleQueryAtom = ReactionRoleQueryAtom.RoleReactant;
                        role          = ReactionRole.Reactant;
                        break;

                    case ReactionRoles.Agent:
                        roleQueryAtom = ReactionRoleQueryAtom.RoleAgent;
                        role          = ReactionRole.Agent;
                        break;

                    case ReactionRoles.Product:
                        roleQueryAtom = ReactionRoleQueryAtom.RoleProduct;
                        role          = ReactionRole.Product;
                        break;
                    }

                    if (roleQueryAtom != null)
                    {
                        while (rollback < query.Atoms.Count)
                        {
                            IAtom org = query.Atoms[rollback];
                            IAtom rep = LogicalOperatorAtom.And(roleQueryAtom, (IQueryAtom)org);
                            // ensure AAM is propagated
                            rep.SetProperty(CDKPropertyName.AtomAtomMapping, org.GetProperty <int?>(CDKPropertyName.AtomAtomMapping));
                            rep.SetProperty(CDKPropertyName.ReactionRole, role);
                            AtomContainerManipulator.ReplaceAtomByAtom(query, org, rep);
                            rollback++;
                        }
                    }
                }
            }
            return(query);
        }
示例#7
0
        /// <summary>
        /// Convert an CDK <see cref="IAtom"/> to a Beam Atom. The symbol and implicit
        /// hydrogen count are not optional. If the symbol is not supported by the
        /// SMILES notation (e.g. 'R1') the element will automatically default to
        /// Unknown ('*').
        /// </summary>
        /// <param name="a">cdk Atom instance</param>
        /// <returns>a Beam atom</returns>
        /// <exception cref="NullReferenceException">the atom had an undefined symbol or implicit hydrogen count</exception>
        static Beam.IAtom ToBeamAtom(IAtom a, SmiFlavors flavour)
        {
            var    aromatic = SmiFlavorTool.IsSet(flavour, SmiFlavors.UseAromaticSymbols) && a.IsAromatic;
            var    charge   = a.FormalCharge;
            string symbol   = CheckNotNull(a.Symbol, "An atom had an undefined symbol");

            var element = Beam.Element.OfSymbol(symbol);

            if (element == null)
            {
                element = Beam.Element.Unknown;
            }

            var ab = aromatic ? AtomBuilder.Aromatic(element) : AtomBuilder.Aliphatic(element);

            // CDK leaves nulls on pseudo atoms - we need to check this special case
            var hCount = a.ImplicitHydrogenCount;

            if (element == Beam.Element.Unknown)
            {
                ab.NumOfHydrogens(hCount ?? 0);
            }
            else
            {
                ab.NumOfHydrogens(CheckNotNull(hCount, "One or more atoms had an undefined number of implicit hydrogens"));
            }

            if (charge.HasValue)
            {
                ab.Charge(charge.Value);
            }

            // use the mass number to specify isotope?
            if (SmiFlavorTool.IsSet(flavour, SmiFlavors.AtomicMass | SmiFlavors.AtomicMassStrict))
            {
                var massNumber = a.MassNumber;
                if (massNumber != null)
                {
                    ab.Isotope(massNumber.Value);
                }
            }

            var atomClass = a.GetProperty <int?>(CDKPropertyName.AtomAtomMapping);

            if (SmiFlavorTool.IsSet(flavour, SmiFlavors.AtomAtomMap) && atomClass != null)
            {
                ab.AtomClass(atomClass.Value);
            }

            return(ab.Build());
        }
示例#8
0
        public int[] GetCanonicalPermutation(IAtomContainer container)
        {
            CanonicalLabeler labeler = new CanonicalLabeler();

            labeler.CanonLabel(container);
            int n = container.Atoms.Count;

            int[] perm = new int[n];
            for (int i = 0; i < n; i++)
            {
                IAtom a = container.Atoms[i];
                int   x = (int)a.GetProperty <long>(InvPair.CanonicalLabelPropertyKey);
                perm[i] = x - 1;
            }
            return(perm);
        }
示例#9
0
            /// <summary>
            /// Access the canonical label for the given tree node's atom. If any component is null
            /// then <see cref="long.MinValue"/> is return thus sorting that object in lower order.
            /// </summary>
            /// <param name="node">a tree node to get the label from</param>
            /// <returns>canonical label value</returns>
            private static long Label(TreeNode node)
            {
                if (node == null)
                {
                    return(long.MinValue);
                }
                IAtom atom = node.Atom;

                if (atom == null)
                {
                    return(long.MinValue);
                }
                // cast can be removed in master
                long label = atom.GetProperty(InvPair.CanonicalLabelPropertyKey, long.MinValue);

                return(label);
            }
示例#10
0
        public override bool Matches(IAtom atom)
        {
            ReactionRole?atomRole = atom.GetProperty <ReactionRole?>(CDKPropertyName.ReactionRole);

            if (atomRole == null)
            {
                return(this.role == ReactionRoles.Any);
            }
            switch (atomRole.Value)
            {
            case ReactionRole.Reactant:
                return((this.role & ReactionRoles.Reactant) != 0);

            case ReactionRole.Agent:
                return((this.role & ReactionRoles.Agent) != 0);

            case ReactionRole.Product:
                return((this.role & ReactionRoles.Product) != 0);

            default:
                return(false);
            }
        }
示例#11
0
        /// <summary>
        ///  Configures an atom to a mmff94 based atom type
        /// </summary>
        /// <param name="atom">atom to be configured</param>
        /// <param name="hoseCode">the 4 sphere hose code of the atom</param>
        /// <returns>atom</returns>
        /// <exception cref="NoSuchAtomTypeException"> atomType is not known</exception>
        public IAtom ConfigureMMFF94BasedAtom(IAtom atom, string hoseCode, bool isInHetRing)
        {
            //Debug.WriteLine("****** Configure MMFF94 AtomType ******");
            MMFF94BasedAtomTypePattern atp = new MMFF94BasedAtomTypePattern();
            var    atomTypePattern         = atp.AtomTypePatterns;
            bool   atomTypeFlag            = false;
            string ID = "";

            hoseCode = RemoveAromaticityFlagsFromHoseCode(hoseCode);

            string[] ids = { "C",    "Csp2", "C=",   "Csp", "CO2M", "CNN+", "C%",   "CIM+", "CR4R", "CR3R", "CE4R", "Car",  "C5A",
                             "C5B",  "C5",   "HC",   "HO",  "HN",   "HOCO", "HN=C", "HN2",  "HOCC", "HOH",  "HOS",  "HN+",  "HO+", "HO=+",  "HP",
                             "O",    "O=",   "OX",   "OM",  "O+",   "O=+",  "OH2",  "Oar",  "N",    "N=C",  "NC=C", "NSP",  "=N=", "NAZT",  "N+",
                             "N2OX", "N3OX", "NC#N", "NO3", "N=O",  "NC=O", "NSO",  "N+=",  "NCN+", "NGD+", "NR%",  "NM",   "N5M", "NPYD",
                             "NPYL", "NPD+", "N5A",  "N5B", "NPOX", "N5OX", "N5+",  "N5",   "S",    "S=C",  ">SN",  "SO2",  "SX",  "SO2M",
                             "=SO",  "Sthi", "PTET", "P",   "-P=C", "F",    "CL",   "BR",   "I",    "SI",   "CL04", "FE+2", "FE+3","F-",    "CL-",
                             "BR-",  "LI+",  "NA+",  "K+",  "ZN+2", "CA+2", "CU+1", "CU+2", "MG+2", "Du" };

            if (atom is IPseudoAtom)
            {
                return(atom);
            }

            for (int j = 0; j < atomTypePattern.Count; j++)
            {
                var p   = atomTypePattern[j];
                var mat = p.Match(hoseCode);
                if (mat.Success)
                {
                    ID = ids[j];
                    if (j == 0)
                    {//csp3
                        if (atom.IsInRing)
                        {
                            p   = atomTypePattern[13];      //c beta heteroaromatic ring
                            mat = p.Match(hoseCode);
                            var p2   = atomTypePattern[12]; //c alpha heteroaromatic ring
                            var mat2 = p2.Match(hoseCode);
                            if (mat.Success && isInHetRing && atom.IsAromatic &&
                                atom.GetProperty <int>("RING_SIZE").Equals(5))
                            {
                                ID = ids[13];
                            }
                            else if (mat2.Success && isInHetRing && atom.IsAromatic &&
                                     atom.GetProperty <int>("RING_SIZE").Equals(5))
                            {
                                ID = ids[12];
                            }
                            else if (atom.GetProperty <int>("RING_SIZE").Equals(3) &&
                                     !atom.IsAromatic)
                            {
                                ID = ids[9];//sp3 3mem rings
                            }
                            else if (atom.GetProperty <int>("RING_SIZE").Equals(4) &&
                                     !atom.IsAromatic)
                            {
                                ID = ids[8];//sp3 4mem rings
                            }
                            else if (atom.IsAromatic && isInHetRing &&
                                     atom.GetProperty <int>("RING_SIZE").Equals(5))
                            {
                                ID = ids[14];//C in het 5 ring
                            }
                            else if (atom.IsAromatic)
                            {
                                ID = ids[11];//C in benzene, pyroll
                            }
                        }
                        else
                        {
                            p   = atomTypePattern[66];//S=C
                            mat = p.Match(hoseCode);
                            if (mat.Success)
                            {
                                ID = ids[66];
                            }
                        }
                    }
                    else if (j == 1)
                    {//csp2
                        if (atom.IsInRing)
                        {
                            if (atom.GetProperty <int>("RING_SIZE").Equals(4) &&
                                !atom.IsAromatic && !isInHetRing)
                            {
                                ID = ids[29];//C= in 4 ring
                            }
                        }
                    }
                    else if (j == 2)
                    {//csp2 C=Hetatom
                        if (atom.IsInRing && isInHetRing && atom.IsAromatic)
                        {
                            ID = ids[12];
                        }
                    }
                    else if (j == 36)
                    {//n sp3
                     //Amid
                        p   = atomTypePattern[48];
                        mat = p.Match(hoseCode);
                        if (mat.Success && !atom.IsInRing)
                        {
                            ID = ids[48];
                        }

                        p   = atomTypePattern[44];//sp3 n-oxide
                        mat = p.Match(hoseCode);
                        if (mat.Success)
                        {
                            ID = ids[44];
                        }

                        p   = atomTypePattern[56];//npyd
                        mat = p.Match(hoseCode);

                        if (atom.IsAromatic)
                        {//id in pyridin, pyrol etc...                        if (mat.Success && atom.IsAromatic && atom.GetProperty<int>("RING_SIZE").Equals(5)){
                            if (atom.GetProperty <int>("RING_SIZE").Equals(6) && mat.Success)
                            {
                                ID = ids[56];
                            }
                            else if (atom.GetProperty <int>("RING_SIZE").Equals(5) && mat.Success)
                            {
                                ID = ids[57];
                            }
                            else
                            {
                                ID = ids[64];
                            }
                        }

                        p   = atomTypePattern[61];//npyd
                        mat = p.Match(hoseCode);
                        if (atom.IsAromatic)
                        {//id in pyridin, pyrol etc...                        if (mat.Success && atom.IsAromatic && atom.GetProperty<int>("RING_SIZE").Equals(5)){
                            if (atom.GetProperty <int>("RING_SIZE").Equals(6) && mat.Success)
                            {
                                ID = ids[61];
                            }
                            else if (atom.GetProperty <int>("RING_SIZE").Equals(5) && mat.Success)
                            {
                                ID = ids[62];
                            }
                            else
                            {
                                ID = ids[43];
                            }
                        }

                        p   = atomTypePattern[45];//NC#N
                        mat = p.Match(hoseCode);
                        if (mat.Success)
                        {
                            ID = ids[45];
                        }
                    }
                    else if (j == 37)
                    {                              //N=C n in imine
                        p   = atomTypePattern[59]; //n beta heteroaromatic ring
                        mat = p.Match(hoseCode);
                        if (atom.IsInRing)
                        {
                            if (mat.Success && isInHetRing && atom.IsAromatic &&
                                atom.GetProperty <int>("RING_SIZE").Equals(5))
                            {
                                ID = ids[59];
                            }
                            else if (atom.IsAromatic &&
                                     atom.GetProperty <int>("RING_SIZE").Equals(6))
                            {
                                ID = ids[56];
                            }
                            else if (atom.IsAromatic &&
                                     atom.GetProperty <int>("RING_SIZE").Equals(5))
                            {
                                ID = ids[57];
                            }
                        }

                        p   = atomTypePattern[43];//N2OX
                        mat = p.Match(hoseCode);
                        if (mat.Success)
                        {
                            if (atom.IsAromatic &&
                                atom.GetProperty <int>("RING_SIZE").Equals(6))
                            {
                                ID = ids[61];//npox
                            }
                            else if (mat.Success && atom.IsAromatic &&
                                     atom.GetProperty <int>("RING_SIZE").Equals(5))
                            {
                                ID = ids[62];//n5ox
                            }
                            else
                            {
                                ID = ids[43];
                            }
                        }
                    }
                    else if (j == 43)
                    {//sp2 n oxide
                        if (atom.IsInRing && atom.IsAromatic &&
                            atom.GetProperty <int>("RING_SIZE").Equals(5))
                        {
                            ID = ids[62];
                        }
                        else if (atom.IsInRing && atom.IsAromatic &&
                                 atom.GetProperty <int>("RING_SIZE").Equals(6))
                        {
                            ID = ids[61];
                        }
                    }
                    else if (j == 40 || j == 41)
                    {//n in c=n=n or terminal n in azido
                        if (atom.IsInRing && atom.IsAromatic &&
                            atom.GetProperty <int>("RING_SIZE").Equals(5))
                        {
                            ID = ids[59];//aromatic N 5R alpha
                        }
                    }
                    else if (j == 50)
                    {//n+=
                        if (atom.IsInRing && atom.IsAromatic &&
                            atom.GetProperty <int>("RING_SIZE").Equals(5))
                        {
                            ID = ids[63];//n5+
                        }
                        else if (atom.IsInRing && atom.IsAromatic &&
                                 atom.GetProperty <int>("RING_SIZE").Equals(6))
                        {
                            ID = ids[58];//npd+
                        }
                    }
                    else if (j == 28)
                    {//O ->furan
                        if (atom.IsInRing && atom.IsAromatic &&
                            atom.GetProperty <int>("RING_SIZE").Equals(5))
                        {
                            ID = ids[35];
                        }
                    }
                    else if (j == 16)
                    {                              //H-object-> enol
                        p   = atomTypePattern[21]; //enol
                        mat = p.Match(hoseCode);
                        if (mat.Success)
                        {
                            ID = ids[21];
                        }
                        p   = atomTypePattern[18];//enol
                        mat = p.Match(hoseCode);
                        if (mat.Success)
                        {
                            ID = ids[18];
                        }
                    }
                    else if (j == 74)
                    {                              //P
                        p   = atomTypePattern[75]; //-P=C
                        mat = p.Match(hoseCode);
                        if (mat.Success)
                        {
                            ID = ids[75];
                        }
                    }

                    atomTypeFlag = true;
                    //Debug.WriteLine("Atom Symbol:" + atom.Symbol + " MATCH AtomType> " + ID + " HoseCode>" + hoseCode + " ");
                    break;
                } //IF
            }     //for end
            if (atomTypeFlag)
            {
                atomTypeFlag = false;
                return(SetAtom(atom, ID));
            }
            else
            {
                throw new NoSuchAtomTypeException("Atom is unkown: Symbol:" + atom.Symbol
                                                  + " does not MATCH AtomType. HoseCode:" + hoseCode);
            }
        }
示例#12
0
文件: Expr.cs 项目: roddickchen/NCDK
        /// <summary>
        /// Internal match methods - does not null check.
        /// </summary>
        /// <param name="type">the type</param>
        /// <param name="atom">the atom</param>
        /// <returns>the expression matches</returns>
        private bool Matches(ExprType type, IAtom atom, int stereo)
        {
            switch (type)
            {
            // predicates
            case ExprType.True:
                return(true);

            case ExprType.False:
                return(false);

            case ExprType.IsAromatic:
                return(atom.IsAromatic);

            case ExprType.IsAliphatic:
                return(!atom.IsAromatic);

            case ExprType.IsInRing:
                return(atom.IsInRing);

            case ExprType.IsInChain:
                return(!atom.IsInRing);

            case ExprType.IsHetero:
                return(!Eq(atom.AtomicNumber, 6) &&
                       !Eq(atom.AtomicNumber, 1));

            case ExprType.HasImplicitHydrogen:
                return(atom.ImplicitHydrogenCount != null &&
                       atom.ImplicitHydrogenCount > 0);

            case ExprType.HasIsotope:
                return(atom.MassNumber != null);

            case ExprType.HasUnspecifiedIsotope:
                return(atom.MassNumber == null);

            case ExprType.Unsaturated:
                foreach (var bond in atom.Bonds)
                {
                    if (bond.Order == BondOrder.Double)
                    {
                        return(true);
                    }
                }
                return(false);

            // value primitives
            case ExprType.Element:
                return(Eq(atom.AtomicNumber, value));

            case ExprType.AliphaticElement:
                return(!atom.IsAromatic &&
                       Eq(atom.AtomicNumber, value));

            case ExprType.AromaticElement:
                return(atom.IsAromatic &&
                       Eq(atom.AtomicNumber, value));

            case ExprType.ImplicitHCount:
                return(Eq(atom.ImplicitHydrogenCount, value));

            case ExprType.TotalHCount:
                if (atom.ImplicitHydrogenCount != null &&
                    atom.ImplicitHydrogenCount > value)
                {
                    return(false);
                }
                return(GetTotalHCount(atom) == value);

            case ExprType.Degree:
                return(atom.Bonds.Count == value);

            case ExprType.HeavyDegree:     // XXX: CDK quirk
                return(atom.Bonds.Count - (GetTotalHCount(atom) - atom.ImplicitHydrogenCount) == value);

            case ExprType.TotalDegree:
                int x = atom.Bonds.Count + Unbox(atom.ImplicitHydrogenCount);
                return(x == value);

            case ExprType.Valence:
                int v = Unbox(atom.ImplicitHydrogenCount);
                if (v > value)
                {
                    return(false);
                }
                foreach (var bond in atom.Bonds)
                {
                    if (!bond.Order.IsUnset())
                    {
                        v += bond.Order.Numeric();
                    }
                }
                return(v == value);

            case ExprType.Isotope:
                return(Eq(atom.MassNumber, value));

            case ExprType.FormalCharge:
                return(Eq(atom.FormalCharge, value));

            case ExprType.RingBondCount:
                if (!atom.IsInRing || atom.Bonds.Count < value)
                {
                    return(false);
                }
                int rbonds = 0;
                foreach (var bond in atom.Bonds)
                {
                    rbonds += bond.IsInRing ? 1 : 0;
                }
                return(rbonds == value);

            case ExprType.RingCount:
                return(atom.IsInRing && GetRingCount(atom) == value);

            case ExprType.RingSmallest:
                return(atom.IsInRing && IsInSmallRingSize(atom, value));

            case ExprType.RingSize:
                return(atom.IsInRing && IsInRingSize(atom, value));

            case ExprType.HeteroSubstituentCount:
                if (atom.Bonds.Count < value)
                {
                    return(false);
                }
                int q = 0;
                foreach (var bond in atom.Bonds)
                {
                    q += Matches(ExprType.IsHetero, bond.GetOther(atom), stereo) ? 1 : 0;
                }
                return(q == value);

            case ExprType.Insaturation:
                int db = 0;
                foreach (var bond in atom.Bonds)
                {
                    if (bond.Order == BondOrder.Double)
                    {
                        db++;
                    }
                }
                return(db == value);

            case ExprType.HybridisationNumber:
                var hyb = atom.Hybridization;
                if (hyb.IsUnset())
                {
                    return(false);
                }
                switch (value)
                {
                case 1:
                    return(hyb == Hybridization.SP1);

                case 2:
                    return(hyb == Hybridization.SP2);

                case 3:
                    return(hyb == Hybridization.SP3);

                case 4:
                    return(hyb == Hybridization.SP3D1);

                case 5:
                    return(hyb == Hybridization.SP3D2);

                case 6:
                    return(hyb == Hybridization.SP3D3);

                case 7:
                    return(hyb == Hybridization.SP3D4);

                case 8:
                    return(hyb == Hybridization.SP3D5);

                default:
                    return(false);
                }

            case ExprType.PeriodicGroup:
                return(Tools.PeriodicTable.GetGroup(atom.AtomicNumber) == value);

            case ExprType.Stereochemistry:
                return(stereo == UnknownStereo || stereo == value);

            case ExprType.ReactionRole:
                var role = atom.GetProperty <ReactionRole>(CDKPropertyName.ReactionRole);
                return(!role.IsUnset() && role.Ordinal() == value);

            case ExprType.And:
                return(left.Matches(left.type, atom, stereo) &&
                       right.Matches(right.type, atom, stereo));

            case ExprType.Or:
                return(left.Matches(left.type, atom, stereo) ||
                       right.Matches(right.type, atom, stereo));

            case ExprType.Not:
                return(!left.Matches(left.type, atom, stereo)
                       // XXX: ugly but needed, when matching stereo
                       || (stereo == UnknownStereo &&
                           (left.type == ExprType.Stereochemistry ||
                            left.type == ExprType.Or &&
                            left.left.type == ExprType.Stereochemistry)));

            case ExprType.Recursive:
                if (ptrn == null)
                {
                    ptrn = DfPattern.CreateSubstructureFinder(query);
                }
                return(ptrn.MatchesRoot(atom));

            default:
                throw new ArgumentException($"Cannot match AtomExpr, type={type}", nameof(type));
            }
        }
示例#13
0
 /// <summary>
 /// Access to the number of lone-pairs (specified as a property of the atom).
 /// </summary>
 /// <param name="atom">the atom to get the lone pairs from</param>
 /// <returns>number of lone pairs</returns>
 private static int LonePairCount(IAtom atom)
 {
     // XXX: LONE_PAIR_COUNT is not currently set!
     return(atom.GetProperty <int>(CDKPropertyName.LonePairCount, -1));
 }
示例#14
0
        /// <summary>
        /// Safely access the reaction role of an atom, returns <see cref="ReactionRole.None"/> if null.
        /// </summary>
        /// <param name="atom">atom</param>
        /// <returns>mapidx, None if undefined</returns>
        private static ReactionRole Role(IAtom atom)
        {
            ReactionRole role = atom.GetProperty <ReactionRole>(CDKPropertyName.ReactionRole, ReactionRole.None);

            return(role);
        }
示例#15
0
 public static string GetCIPDescriptor(this IAtom o)
 => o.GetProperty <string>(CIPDescriptorPropertyKey);
示例#16
0
        // Creates a CxSmilesState from a molecule with atom labels, repeat units, multi-center bonds etc
        private static CxSmilesState GetCxSmilesState(SmiFlavors flavour, IAtomContainer mol)
        {
            CxSmilesState state = new CxSmilesState
            {
                atomCoords = new List <double[]>(),
                coordFlag  = false
            };

            // set the atom labels, values, and coordinates,
            // and build the atom->idx map required by other parts
            var atomidx = new Dictionary <IAtom, int>();

            for (int idx = 0; idx < mol.Atoms.Count; idx++)
            {
                IAtom atom = mol.Atoms[idx];
                if (atom is IPseudoAtom)
                {
                    if (state.atomLabels == null)
                    {
                        state.atomLabels = new SortedDictionary <int, string>();
                    }

                    IPseudoAtom pseudo = (IPseudoAtom)atom;
                    if (pseudo.AttachPointNum > 0)
                    {
                        state.atomLabels[idx] = "_AP" + pseudo.AttachPointNum;
                    }
                    else
                    {
                        if (!"*".Equals(pseudo.Label, StringComparison.Ordinal))
                        {
                            state.atomLabels[idx] = pseudo.Label;
                        }
                    }
                }
                object comment = atom.GetProperty <object>(CDKPropertyName.Comment);
                if (comment != null)
                {
                    if (state.atomValues == null)
                    {
                        state.atomValues = new SortedDictionary <int, string>();
                    }
                    state.atomValues[idx] = comment.ToString();
                }
                atomidx[atom] = idx;

                var p2 = atom.Point2D;
                var p3 = atom.Point3D;

                if (SmiFlavorTool.IsSet(flavour, SmiFlavors.Cx2dCoordinates) && p2 != null)
                {
                    state.atomCoords.Add(new double[] { p2.Value.X, p2.Value.Y, 0 });
                    state.coordFlag = true;
                }
                else if (SmiFlavorTool.IsSet(flavour, SmiFlavors.Cx3dCoordinates) && p3 != null)
                {
                    state.atomCoords.Add(new double[] { p3.Value.X, p3.Value.Y, p3.Value.Z });
                    state.coordFlag = true;
                }
                else if (SmiFlavorTool.IsSet(flavour, SmiFlavors.CxCoordinates))
                {
                    state.atomCoords.Add(new double[3]);
                }
            }

            if (!state.coordFlag)
            {
                state.atomCoords = null;
            }

            // radicals
            if (mol.SingleElectrons.Count > 0)
            {
                state.atomRads = new SortedDictionary <int, CxSmilesState.Radical>();
                foreach (ISingleElectron radical in mol.SingleElectrons)
                {
                    // 0->1, 1->2, 2->3
                    if (!state.atomRads.TryGetValue(EnsureNotNull(atomidx[radical.Atom]), out CxSmilesState.Radical val))
                    {
                        val = CxSmilesState.Radical.Monovalent;
                    }
                    else if (val == CxSmilesState.Radical.Monovalent)
                    {
                        val = CxSmilesState.Radical.Divalent;
                    }
                    else if (val == CxSmilesState.Radical.Divalent)
                    {
                        val = CxSmilesState.Radical.Trivalent;
                    }
                    else if (val == CxSmilesState.Radical.Trivalent)
                    {
                        throw new ArgumentException("Invalid radical state, can not be more than trivalent");
                    }

                    state.atomRads[atomidx[radical.Atom]] = val;
                }
            }

            var sgroups = mol.GetCtabSgroups();

            if (sgroups != null)
            {
                state.sgroups     = new List <CxSmilesState.PolymerSgroup>();
                state.positionVar = new SortedDictionary <int, IList <int> >();
                foreach (Sgroup sgroup in sgroups)
                {
                    switch (sgroup.Type)
                    {
                    // polymer SRU
                    case SgroupType.CtabStructureRepeatUnit:
                    case SgroupType.CtabMonomer:
                    case SgroupType.CtabMer:
                    case SgroupType.CtabCopolymer:
                    case SgroupType.CtabCrossLink:
                    case SgroupType.CtabModified:
                    case SgroupType.CtabMixture:
                    case SgroupType.CtabFormulation:
                    case SgroupType.CtabAnyPolymer:
                    case SgroupType.CtabGeneric:
                    case SgroupType.CtabComponent:
                    case SgroupType.CtabGraft:
                        string supscript = (string)sgroup.GetValue(SgroupKey.CtabConnectivity);
                        state.sgroups.Add(new CxSmilesState.PolymerSgroup(GetSgroupPolymerKey(sgroup),
                                                                          ToAtomIdxs(sgroup.Atoms, atomidx),
                                                                          sgroup.Subscript,
                                                                          supscript));
                        break;

                    case SgroupType.ExtMulticenter:
                        IAtom        beg   = null;
                        List <IAtom> ends  = new List <IAtom>();
                        ISet <IBond> bonds = sgroup.Bonds;
                        if (bonds.Count != 1)
                        {
                            throw new ArgumentException("Multicenter Sgroup in inconsistent state!");
                        }
                        IBond bond = bonds.First();
                        foreach (IAtom atom in sgroup.Atoms)
                        {
                            if (bond.Contains(atom))
                            {
                                if (beg != null)
                                {
                                    throw new ArgumentException("Multicenter Sgroup in inconsistent state!");
                                }
                                beg = atom;
                            }
                            else
                            {
                                ends.Add(atom);
                            }
                        }
                        state.positionVar[EnsureNotNull(atomidx[beg])] =
                            ToAtomIdxs(ends, atomidx);
                        break;

                    case SgroupType.CtabAbbreviation:
                    case SgroupType.CtabMultipleGroup:
                        // display shortcuts are not output
                        break;

                    case SgroupType.CtabData:
                        // can be generated but currently ignored
                        break;

                    default:
                        throw new NotSupportedException("Unsupported Sgroup Polymer");
                    }
                }
            }

            return(state);
        }
示例#17
0
        // For substituents attached to macrocycles we may be able to point these in/out
        // of the ring
        private bool MacroCycleInversion(AtomPair pair)
        {
            foreach (var v in pair.seqAt)
            {
                IAtom atom = mol.Atoms[v];
                if (!atom.IsInRing || adjList[v].Length == 2)
                {
                    continue;
                }
                if (atom.GetProperty <object>(MacroCycleLayout.MACROCYCLE_ATOM_HINT) == null)
                {
                    continue;
                }
                var acyclic = new List <IBond>(2);
                var cyclic  = new List <IBond>(2);
                foreach (var w in adjList[v])
                {
                    IBond bond = bondMap[v, w];
                    if (bond.IsInRing)
                    {
                        cyclic.Add(bond);
                    }
                    else
                    {
                        acyclic.Add(bond);
                    }
                }
                if (cyclic.Count > 2)
                {
                    continue;
                }

                foreach (var bond in acyclic)
                {
                    if (bfix.Contains(bond))
                    {
                        continue;
                    }
                    Arrays.Fill(visited, false);
                    stackBackup.len = Visit(visited, stackBackup.xs, v, idxs[bond.GetOther(atom)], 0);

                    Vector2 a = atom.Point2D.Value;
                    Vector2 b = bond.GetOther(atom).Point2D.Value;

                    Vector2 perp = new Vector2(b.X - a.X, b.Y - a.Y);
                    perp = Vector2.Normalize(perp);
                    double score = congestion.Score();
                    BackupCoords(backup, stackBackup);

                    Reflect(stackBackup, new Vector2(a.X - perp.Y, a.Y + perp.X), new Vector2(a.X + perp.Y, a.Y - perp.X));
                    congestion.Update(visited, stackBackup.xs, stackBackup.len);

                    if (PercDiff(score, congestion.Score()) >= ImprovementPrecThreshold)
                    {
                        return(true);
                    }

                    RestoreCoords(stackBackup, backup);
                }
            }
            return(false);
        }
示例#18
0
        /// <summary>
        /// Attempt to reduce congestion through rotation of flippable bonds between
        /// congest pairs.
        /// </summary>
        /// <param name="pairs">congested pairs of atoms</param>
        void Rotate(ICollection <AtomPair> pairs)
        {
            // bond has already been tried in this phase so
            // don't need to test again
            var tried = new HashSet <IBond>();

            foreach (var pair in pairs)
            {
                foreach (var bond in pair.bndAt)
                {
                    // only try each bond once per phase and skip
                    if (!tried.Add(bond))
                    {
                        continue;
                    }
                    if (bfix.Contains(bond))
                    {
                        continue;
                    }

                    // those we have found to probably be symmetric
                    if (probablySymmetric.Contains(bond))
                    {
                        continue;
                    }

                    // can't rotate these
                    if (bond.Order != BondOrder.Single || bond.IsInRing)
                    {
                        continue;
                    }

                    IAtom beg    = bond.Begin;
                    IAtom end    = bond.End;
                    int   begIdx = idxs[beg];
                    int   endIdx = idxs[end];

                    // terminal
                    if (adjList[begIdx].Length == 1 || adjList[endIdx].Length == 1)
                    {
                        continue;
                    }

                    int begPriority = beg.GetProperty <int>(AtomPlacer.Priority);
                    int endPriority = end.GetProperty <int>(AtomPlacer.Priority);

                    Arrays.Fill(visited, false);
                    if (begPriority < endPriority)
                    {
                        stackBackup.len = VisitAdj(visited, stackBackup.xs, begIdx, endIdx);

                        // avoid moving fixed atoms
                        if (afix.Any())
                        {
                            int begCnt = NumFixedMoved(stackBackup.xs, stackBackup.len);
                            if (begCnt > 0)
                            {
                                Arrays.Fill(visited, false);
                                stackBackup.len = VisitAdj(visited, stackBackup.xs, endIdx, begIdx);
                                int endCnt = NumFixedMoved(stackBackup.xs, stackBackup.len);
                                if (endCnt > 0)
                                {
                                    continue;
                                }
                            }
                        }
                    }
                    else
                    {
                        stackBackup.len = VisitAdj(visited, stackBackup.xs, endIdx, begIdx);

                        // avoid moving fixed atoms
                        if (afix.Any())
                        {
                            int endCnt = NumFixedMoved(stackBackup.xs, stackBackup.len);
                            if (endCnt > 0)
                            {
                                Arrays.Fill(visited, false);
                                stackBackup.len = VisitAdj(visited, stackBackup.xs, begIdx, endIdx);
                                int begCnt = NumFixedMoved(stackBackup.xs, stackBackup.len);
                                if (begCnt > 0)
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    double min = congestion.Score();

                    BackupCoords(backup, stackBackup);
                    Reflect(stackBackup, beg, end);
                    congestion.Update(visited, stackBackup.xs, stackBackup.len);

                    double delta = min - congestion.Score();

                    // keep if decent improvement or improvement and resolves this overlap
                    if (delta > RotateDeltaThreshold ||
                        (delta > 1 && congestion.Contribution(pair.fst, pair.snd) < MinScore))
                    {
                        goto continue_Pair;
                    }
                    else
                    {
                        // almost no difference from flipping... bond is probably symmetric
                        // mark to avoid in future iterations
                        if (Math.Abs(delta) < 0.1)
                        {
                            probablySymmetric.Add(bond);
                        }

                        // restore
                        RestoreCoords(stackBackup, backup);
                        congestion.Update(visited, stackBackup.xs, stackBackup.len);
                        congestion.score = min;
                    }
                }
            }
continue_Pair:
            ;
        }
示例#19
0
        /// <summary>
        /// Read a Reaction from a file in MDL RXN format
        /// </summary>
        /// <returns>The Reaction that was read from the MDL file.</returns>
        private IReaction ReadReaction(IChemObjectBuilder builder)
        {
            IReaction reaction = builder.NewReaction();

            try
            {
                input.ReadLine(); // first line should be $RXN
                input.ReadLine(); // second line
                input.ReadLine(); // third line
                input.ReadLine(); // fourth line
            }
            catch (IOException exception)
            {
                Debug.WriteLine(exception);
                throw new CDKException("Error while reading header of RXN file", exception);
            }

            int reactantCount = 0;
            int productCount  = 0;
            int agentCount    = 0;

            try
            {
                string countsLine = input.ReadLine();

                // this line contains the number of reactants and products
                var tokenizer = Strings.Tokenize(countsLine).GetEnumerator();
                tokenizer.MoveNext();
                reactantCount = int.Parse(tokenizer.Current, NumberFormatInfo.InvariantInfo);
                Trace.TraceInformation("Expecting " + reactantCount + " reactants in file");
                tokenizer.MoveNext();
                productCount = int.Parse(tokenizer.Current, NumberFormatInfo.InvariantInfo);

                if (tokenizer.MoveNext())
                {
                    agentCount = int.Parse(tokenizer.Current, NumberFormatInfo.InvariantInfo);
                    // ChemAxon extension, technically BIOVIA now support this but
                    // not documented yet
                    if (ReaderMode == ChemObjectReaderMode.Strict && agentCount > 0)
                    {
                        throw new CDKException("RXN files uses agent count extension");
                    }
                }
                Trace.TraceInformation("Expecting " + productCount + " products in file");
            }
            catch (Exception exception)
            {
                if (exception is IOException | exception is FormatException)
                {
                    Debug.WriteLine(exception);
                    throw new CDKException("Error while counts line of RXN file", exception);
                }
                throw;
            }

            // now read the reactants
            try
            {
                for (int i = 1; i <= reactantCount; i++)
                {
                    var molFile = new StringBuilder();
                    input.ReadLine(); // announceMDLFileLine
                    string molFileLine = "";
                    do
                    {
                        molFileLine = input.ReadLine();
                        molFile.Append(molFileLine);
                        molFile.Append('\n');
                    } while (!string.Equals(molFileLine, "M  END", StringComparison.Ordinal));

                    // read MDL molfile content
                    // Changed this to mdlv2000 reader
                    MDLV2000Reader reader   = new MDLV2000Reader(new StringReader(molFile.ToString()), base.ReaderMode);
                    IAtomContainer reactant = (IAtomContainer)reader.Read(builder.NewAtomContainer());
                    reader.Close();

                    // add reactant
                    reaction.Reactants.Add(reactant);
                }
            }
            catch (CDKException)
            {
                // rethrow exception from MDLReader
                throw;
            }
            catch (Exception exception)
            {
                if (exception is IOException | exception is ArgumentException)
                {
                    Debug.WriteLine(exception);
                    throw new CDKException("Error while reading products", exception);
                }
                throw;
            }

            // now read the products
            try
            {
                for (int i = 1; i <= agentCount; i++)
                {
                    var molFile = new StringBuilder();
                    input.ReadLine(); // String announceMDLFileLine =
                    string molFileLine = "";
                    do
                    {
                        molFileLine = input.ReadLine();
                        molFile.Append(molFileLine);
                        molFile.Append('\n');
                    } while (!string.Equals(molFileLine, "M  END", StringComparison.Ordinal));

                    // read MDL molfile content
                    MDLV2000Reader reader  = new MDLV2000Reader(new StringReader(molFile.ToString()));
                    IAtomContainer product = (IAtomContainer)reader.Read(builder.NewAtomContainer());
                    reader.Close();

                    // add reactant
                    reaction.Agents.Add(product);
                }
            }
            catch (CDKException)
            {
                // rethrow exception from MDLReader
                throw;
            }
            catch (Exception exception)
            {
                if (exception is IOException | exception is ArgumentException)
                {
                    Debug.WriteLine(exception);
                    throw new CDKException("Error while reading reactant", exception);
                }
                throw;
            }

            // now read the products
            try
            {
                for (int i = 1; i <= productCount; i++)
                {
                    var molFile = new StringBuilder();
                    input.ReadLine(); // string announceMDLFileLine =
                    string molFileLine = "";
                    do
                    {
                        molFileLine = input.ReadLine();
                        molFile.Append(molFileLine);
                        molFile.Append('\n');
                    } while (!string.Equals(molFileLine, "M  END", StringComparison.Ordinal));

                    // read MDL molfile content
                    MDLV2000Reader reader  = new MDLV2000Reader(new StringReader(molFile.ToString()));
                    IAtomContainer product = (IAtomContainer)reader.Read(builder.NewAtomContainer());
                    reader.Close();

                    // add reactant
                    reaction.Products.Add(product);
                }
            }
            catch (CDKException)
            {
                // rethrow exception from MDLReader
                throw;
            }
            catch (Exception exception)
            {
                if (exception is IOException | exception is ArgumentException)
                {
                    Debug.WriteLine(exception);
                    throw new CDKException("Error while reading products", exception);
                }
                throw;
            }

            // now try to map things, if wanted
            Trace.TraceInformation("Reading atom-atom mapping from file");
            // distribute all atoms over two AtomContainer's
            IAtomContainer reactingSide = builder.NewAtomContainer();

            foreach (var molecule in reaction.Reactants)
            {
                reactingSide.Add(molecule);
            }
            IAtomContainer producedSide = builder.NewAtomContainer();

            foreach (var molecule in reaction.Products)
            {
                producedSide.Add(molecule);
            }

            // map the atoms
            int mappingCount = 0;

            //        IAtom[] reactantAtoms = reactingSide.GetAtoms();
            //        IAtom[] producedAtoms = producedSide.GetAtoms();
            for (int i = 0; i < reactingSide.Atoms.Count; i++)
            {
                for (int j = 0; j < producedSide.Atoms.Count; j++)
                {
                    IAtom eductAtom   = reactingSide.Atoms[i];
                    IAtom productAtom = producedSide.Atoms[j];
                    if (eductAtom.GetProperty <object>(CDKPropertyName.AtomAtomMapping) != null &&
                        eductAtom.GetProperty <object>(CDKPropertyName.AtomAtomMapping).Equals(
                            productAtom.GetProperty <object>(CDKPropertyName.AtomAtomMapping)))
                    {
                        reaction.Mappings.Add(builder.NewMapping(eductAtom, productAtom));
                        mappingCount++;
                        break;
                    }
                }
            }
            Trace.TraceInformation("Mapped atom pairs: " + mappingCount);

            return(reaction);
        }
示例#20
0
        /// <summary>
        /// Safely access the mapidx of an atom, returns 0 if null.
        /// </summary>
        /// <param name="atom">atom</param>
        /// <returns>mapidx, 0 if undefined</returns>
        private static int Mapidx(IAtom atom)
        {
            int mapidx = atom.GetProperty <int>(CDKPropertyName.AtomAtomMapping, 0);

            return(mapidx);
        }
示例#21
0
        /// <summary>
        /// Configures an atom to a mm2 based atom type
        /// </summary>
        /// <param name="atom">atom to be configured</param>
        /// <param name="hoseCode">the 4 sphere hose code of the atom</param>
        /// <returns>atom</returns>
        /// <exception cref="NoSuchAtomTypeException"> atomType is not known</exception>
        public IAtom ConfigureMM2BasedAtom(IAtom atom, string hoseCode, bool hetRing)
        {
            //Debug.WriteLine("CONFIGURE MM2 ATOM");
            MM2BasedAtomTypePattern atp = new MM2BasedAtomTypePattern();
            var    atomTypePattern      = atp.AtomTypePatterns;
            string ID           = "";
            bool   atomTypeFlag = false;

            if (atom is IPseudoAtom)
            {
                return(atom);
            }

            hoseCode = RemoveAromaticityFlagsFromHoseCode(hoseCode);

            string[] ids = { "C",   "Csp2", "C=",  "Csp", "HC",   "O",    "O=",  "N",    "Nsp2", "Nsp",  "F",    "CL",  "BR",   "I",   "S",  "S+",
                             ">SN", "SO2",  "SI",  "LP",  "HO",   "CR3R", "HN",  "HOCO", "P",    "B",    "BTET", "HN2", "C.",   "C+",  "GE", "SN",
                             "PB",  "SE",   "TE",  "D",   "NPYD", "CE3R", "N+",  "NPYL", "Oar",  "Sthi", "N2OX", "HS",  "=N=",  "NO3", "OM",
                             "HN+", "OR",   "Car", "HE",  "NE",   "AR",   "KR",  "XE",   "",     "",     "",     "MG",  "PTET", "FE",  "FE", "NI","NI",
                             "CO",  "CO",   "",    "",    "OX",   "OK",   "C++", "N=C",  "NPD+", "N+=",  "N2OX" };

            for (int j = 0; j < atomTypePattern.Count; j++)
            {
                Regex p   = atomTypePattern[j];
                var   mat = p.Match(hoseCode);
                if (mat.Success)
                {
                    ID = ids[j];
                    //CHECK Rings 1,2,8,9? Thiole 44? AZO 9? Radical - ? Amid 23/enol 21?
                    if (j == 0)
                    {
                        //csp3
                        if (atom.IsInRing)
                        {
                            if (atom.GetProperty <int>("RING_SIZE").Equals(3))
                            {
                                ID = ids[21];
                            }
                            else if (atom.GetProperty <int>("RING_SIZE").Equals(6) &&
                                     atom.IsAromatic)
                            {
                                ID = ids[1];
                            }
                            else if (atom.IsAromatic)
                            {
                                ID = ids[1];
                            }
                        }
                    }
                    else if (j == 1)
                    {
                        //csp2
                        if (atom.IsInRing)
                        {
                            if (atom.GetProperty <int>("RING_SIZE").Equals(6) &&
                                atom.IsAromatic)
                            {
                            }
                            else if (atom.GetProperty <int>("RING_SIZE").Equals(3))
                            {
                                ID = ids[37];
                            }
                            else
                            {
                                ID = ids[1];
                            }
                        }
                        p = atomTypePattern[2];
                        //COOH
                        mat = p.Match(hoseCode);
                        if (mat.Success && !atom.IsInRing)
                        {
                            ID = ids[2];
                        }
                    }
                    else if (j == 5)
                    {
                        //OH/Ether
                        if (atom.IsInRing)
                        {
                            if (atom.GetProperty <int>("RING_SIZE").Equals(3))
                            {
                                ID = ids[48];
                                //EPOXY
                            }
                            else if (atom.GetProperty <int>("RING_SIZE").Equals(5) &&
                                     atom.IsAromatic)
                            {
                                ID = ids[40];
                            }
                            else
                            {
                                ID = ids[5];
                            }
                        }
                    }
                    else if (j == 7)
                    {
                        //n sp3
                        if (atom.IsInRing && atom.IsAromatic)
                        {
                            if (atom.GetProperty <int>("RING_SIZE").Equals(5))
                            {
                                ID = ids[39];
                            }
                        }
                        //Amid
                        p   = atomTypePattern[77];
                        mat = p.Match(hoseCode);
                        if (mat.Success && !atom.IsInRing)
                        {
                            ID = ids[8];
                        }
                    }
                    else if (j == 8)
                    {
                        //nsp2
                        if (atom.IsInRing)
                        {
                            if (atom.GetProperty <int>("RING_SIZE").Equals(6))
                            {
                                ID = ids[36];
                            }
                        }
                        p = atomTypePattern[36];
                        //AZO
                        mat = p.Match(hoseCode);
                        if (mat.Success && !atom.IsInRing)
                        {
                            ID = ids[36];
                        }
                    }
                    else if (j == 43)
                    {
                        //h thiol
                        var d_tmp = atom.GetProperty <double>("MAX_BOND_ORDER");
                        if (d_tmp > 1)
                        {
                            ID = ids[4];
                        }
                    }
                    else if (j == 20)
                    {
                        //h alcohol,ether
                        p = atomTypePattern[76];
                        //Enol
                        mat = p.Match(hoseCode);
                        if (mat.Success && !atom.IsInRing)
                        {
                            ID = ids[27];
                        }
                        p = atomTypePattern[23];
                        //COOH
                        mat = p.Match(hoseCode);
                        if (mat.Success && !atom.IsInRing)
                        {
                            ID = ids[23];
                        }
                    }
                    else if (j == 22)
                    {
                        p = atomTypePattern[75];
                        //Amid
                        mat = p.Match(hoseCode);
                        if (mat.Success)
                        {
                            ID = ids[27];
                        }
                    }

                    atomTypeFlag = true;
                    //Debug.WriteLine("Atom Symbol:" + atom.Symbol + " MATCH AtomType> " + ID + " HoseCode>" + hoseCode + " ");
                    break;
                } //IF
            }     //for end
            if (atomTypeFlag)
            {
                atomTypeFlag = false;
                return(SetAtom(atom, ID));
            }
            else
            {
                throw new NoSuchAtomTypeException("Atom is unkown: Symbol:" + atom.Symbol
                                                  + " does not MATCH AtomType. HoseCode:" + hoseCode);
            }
        }
示例#22
0
        /// <summary>
        /// Converts an 'inlined' reaction stored in a molecule back to a reaction.
        /// </summary>
        /// <param name="mol">molecule to convert</param>
        /// <returns>reaction</returns>
        /// <seealso cref="ToMolecule(IReaction)"/>
        public static IReaction ToReaction(IAtomContainer mol)
        {
            if (mol == null)
            {
                throw new ArgumentException("Null molecule provided");
            }
            var bldr = mol.Builder;
            var rxn  = bldr.NewReaction();

            rxn.SetProperties(mol.GetProperties());
            rxn.Id = mol.Id;

            var components = new Dictionary <int, IAtomContainer>();

            // split atoms
            foreach (var atom in mol.Atoms)
            {
                var role   = atom.GetProperty <ReactionRole?>(CDKPropertyName.ReactionRole);
                var grpIdx = atom.GetProperty <int?>(CDKPropertyName.ReactionGroup);

                if (role == null || role.Value == ReactionRole.None)
                {
                    throw new ArgumentException("Atom " + mol.Atoms.IndexOf(atom) + " had undefined role");
                }
                if (grpIdx == null)
                {
                    throw new ArgumentException("Atom " + mol.Atoms.IndexOf(atom) + " had no reaction group id");
                }

                // new component, and add to appropriate role
                if (!components.TryGetValue(grpIdx.Value, out IAtomContainer comp))
                {
                    components[grpIdx.Value] = comp = bldr.NewAtomContainer();
                    switch (role)
                    {
                    case ReactionRole.Reactant:
                        rxn.Reactants.Add(comp);
                        break;

                    case ReactionRole.Product:
                        rxn.Products.Add(comp);
                        break;

                    case ReactionRole.Agent:
                        rxn.Agents.Add(comp);
                        break;
                    }
                }

                comp.Atoms.Add(atom);
            }

            // split bonds
            foreach (var bond in mol.Bonds)
            {
                var beg    = bond.Begin;
                var end    = bond.End;
                var begIdx = beg.GetProperty <int?>(CDKPropertyName.ReactionGroup);
                var endIdx = end.GetProperty <int?>(CDKPropertyName.ReactionGroup);
                if (begIdx == null || endIdx == null)
                {
                    throw new ArgumentException("Bond " + mol.Bonds.IndexOf(bond) + " had atoms with no reaction group id");
                }
                if (!begIdx.Equals(endIdx))
                {
                    throw new ArgumentException("Bond " + mol.Bonds.IndexOf(bond) + " had atoms with different reaction group id");
                }
                components[begIdx.Value].Bonds.Add(bond);
            }

            // split stereochemistry
            foreach (var se in mol.StereoElements)
            {
                IAtom focus = null;
                switch (se)
                {
                case ITetrahedralChirality tc:
                    focus = tc.ChiralAtom;
                    break;

                case IDoubleBondStereochemistry ds:
                    focus = ds.StereoBond.Begin;
                    break;

                case ExtendedTetrahedral et:
                    focus = et.Focus;
                    break;
                }
                if (focus == null)
                {
                    throw new ArgumentException("Stereochemistry had no focus");
                }
                var grpIdx = focus.GetProperty <int>(CDKPropertyName.ReactionGroup);
                components[grpIdx].StereoElements.Add(se);
            }

            foreach (var se in mol.SingleElectrons)
            {
                var grpIdx = se.Atom.GetProperty <int>(CDKPropertyName.ReactionGroup);
                components[grpIdx].SingleElectrons.Add(se);
            }

            foreach (var lp in mol.LonePairs)
            {
                var grpIdx = lp.Atom.GetProperty <int>(CDKPropertyName.ReactionGroup);
                components[grpIdx].LonePairs.Add(lp);
            }

            return(rxn);
        }