Esempio n. 1
0
        public void Multicenter()
        {
            var state = new CxSmilesState {
                positionVar = new SortedDictionary <int, IList <int> >()
            };

            state.positionVar[0] = new[] { 4, 5, 6, 7 };
            state.positionVar[2] = new[] { 4, 6, 5, 7 };
            Assert.AreEqual(" |m:5:0.1.2.3,7:0.1.2.3|", CxSmilesGenerator.Generate(state, SmiFlavors.CxMulticenter, Array.Empty <int>(), new int[] { 7, 6, 5, 4, 3, 2, 1, 0 }));
        }
Esempio n. 2
0
        public void Sgroups()
        {
            CxSmilesState state = new CxSmilesState
            {
                sgroups = new List <CxSmilesState.PolymerSgroup>(1)
                {
                    new CxSmilesState.PolymerSgroup("n", new[] { 2, 3 }, "n", "ht"),
                    new CxSmilesState.PolymerSgroup("n", new[] { 5 }, "m", "ht")
                }
            };

            Assert.AreEqual(" |Sg:n:2:m:ht,Sg:n:4,5:n:ht|", CxSmilesGenerator.Generate(state, SmiFlavors.CxPolymer, Array.Empty <int>(), new int[] { 7, 6, 5, 4, 3, 2, 1, 0 }));
        }
Esempio n. 3
0
        public void Radicals()
        {
            CxSmilesState state = new CxSmilesState
            {
                atomRads = new SortedDictionary <int, CxSmilesState.Radical>
                {
                    [2] = CxSmilesState.Radical.Monovalent,
                    [6] = CxSmilesState.Radical.Monovalent,
                    [4] = CxSmilesState.Radical.Divalent
                }
            };

            Assert.AreEqual(" |^1:1,5,^2:3|", CxSmilesGenerator.Generate(state, SmiFlavors.CxSmiles, Array.Empty <int>(), new int[] { 7, 6, 5, 4, 3, 2, 1, 0 }));
        }
Esempio n. 4
0
        public void Coords2d()
        {
            CxSmilesState state = new CxSmilesState
            {
                atomCoords = new List <double[]>
                {
                    new double[] { 0, 1.5, 0 },
                    new double[] { 0, 3, 0 },
                    new double[] { 1.5, 1.5, 0 },
                }
            };

            Assert.AreEqual(" |(1.5,1.5,;,1.5,;,3,)|", CxSmilesGenerator.Generate(state, SmiFlavors.CxCoordinates, Array.Empty <int>(), new int[] { 1, 2, 0 }));
        }
Esempio n. 5
0
        public void EmptyCXSMILES()
        {
            CxSmilesState state = new CxSmilesState();

            Assert.AreEqual("", CxSmilesGenerator.Generate(state, SmiFlavors.CxSmiles, Array.Empty <int>(), Array.Empty <int>()));
        }
Esempio n. 6
0
        /// <summary>
        /// Create a SMILES for a reaction of the flavour specified in the constructor and
        /// write the output order to the provided array.
        /// </summary>
        /// <param name="reaction">CDK reaction instance</param>
        /// <param name="ordering">order of output</param>
        /// <returns>reaction SMILES</returns>
        public string Create(IReaction reaction, int[] ordering)
        {
            var reactants = reaction.Reactants;
            var agents    = reaction.Agents;
            var products  = reaction.Products;

            var reactantPart = reaction.Builder.NewAtomContainer();
            var agentPart    = reaction.Builder.NewAtomContainer();
            var productPart  = reaction.Builder.NewAtomContainer();

            var sgroups = new List <Sgroup>();

            foreach (var reactant in reactants)
            {
                reactantPart.Add(reactant);
                SafeAddSgroups(sgroups, reactant);
            }
            foreach (var agent in agents)
            {
                agentPart.Add(agent);
                SafeAddSgroups(sgroups, agent);
            }
            foreach (var product in products)
            {
                productPart.Add(product);
                SafeAddSgroups(sgroups, product);
            }

            var reactantOrder = new int[reactantPart.Atoms.Count];
            var agentOrder    = new int[agentPart.Atoms.Count];
            var productOrder  = new int[productPart.Atoms.Count];

            var expectedSize = reactantOrder.Length + agentOrder.Length + productOrder.Length;

            if (expectedSize != ordering.Length)
            {
                throw new CDKException($"Output ordering array does not have correct amount of space: {ordering.Length} expected: {expectedSize}");
            }

            // we need to make sure we generate without the CXSMILES layers
            string smi = Create(reactantPart, flavour & ~SmiFlavors.CxSmilesWithCoords, reactantOrder) + ">" +
                         Create(agentPart, flavour & ~SmiFlavors.CxSmilesWithCoords, agentOrder) + ">" +
                         Create(productPart, flavour & ~SmiFlavors.CxSmilesWithCoords, productOrder);

            // copy ordering back to unified array and adjust values
            var agentBeg = reactantOrder.Length;
            var agentEnd = reactantOrder.Length + agentOrder.Length;
            var prodEnd  = reactantOrder.Length + agentOrder.Length + productOrder.Length;

            System.Array.Copy(reactantOrder, 0, ordering, 0, agentBeg);
            System.Array.Copy(agentOrder, 0, ordering, agentBeg, agentEnd - agentBeg);
            System.Array.Copy(productOrder, 0, ordering, agentEnd, prodEnd - agentEnd);
            for (int i = agentBeg; i < agentEnd; i++)
            {
                ordering[i] += agentBeg;
            }
            for (int i = agentEnd; i < prodEnd; i++)
            {
                ordering[i] += agentEnd;
            }

            if (SmiFlavorTool.IsSet(flavour, SmiFlavors.CxSmilesWithCoords))
            {
                var unified = reaction.Builder.NewAtomContainer();
                unified.Add(reactantPart);
                unified.Add(agentPart);
                unified.Add(productPart);
                unified.SetCtabSgroups(sgroups);

                // base CXSMILES state information
                var cxstate = GetCxSmilesState(flavour, unified);

                int[] components = null;

                // extra state info on fragment grouping, specific to reactions
                if (SmiFlavorTool.IsSet(flavour, SmiFlavors.CxFragmentGroup))
                {
                    cxstate.fragGroups = new List <List <int> >();

                    // calculate the connected components
                    components = new ConnectedComponents(GraphUtil.ToAdjList(unified)).GetComponents();

                    // AtomContainerSet is ordered so this is safe, it was actually a set we
                    // would need some extra data structures
                    var tmp = new HashSet <int>();
                    int beg = 0, end = 0;
                    foreach (var mol in reactants)
                    {
                        end = end + mol.Atoms.Count;
                        tmp.Clear();
                        for (int i = beg; i < end; i++)
                        {
                            tmp.Add(components[i]);
                        }
                        if (tmp.Count > 1)
                        {
                            cxstate.fragGroups.Add(new List <int>(tmp));
                        }
                        beg = end;
                    }
                    foreach (var mol in agents)
                    {
                        end = end + mol.Atoms.Count;
                        tmp.Clear();
                        for (int i = beg; i < end; i++)
                        {
                            tmp.Add(components[i]);
                        }
                        if (tmp.Count > 1)
                        {
                            cxstate.fragGroups.Add(new List <int>(tmp));
                        }
                        beg = end;
                    }
                    foreach (var mol in products)
                    {
                        end = end + mol.Atoms.Count;
                        tmp.Clear();
                        for (int i = beg; i < end; i++)
                        {
                            tmp.Add(components[i]);
                        }
                        if (tmp.Count > 1)
                        {
                            cxstate.fragGroups.Add(new List <int>(tmp));
                        }
                        beg = end;
                    }
                }

                smi += CxSmilesGenerator.Generate(cxstate, flavour, components, ordering);
            }

            return(smi);
        }
Esempio n. 7
0
        /// <summary>
        /// Creates a SMILES string of the flavour specified as a parameter
        /// and write the output order to the provided array.
        /// </summary>
        /// <remarks>
        /// The output order allows one to arrange auxiliary atom data in the
        /// order that a SMILES string will be read. A simple example is seen below
        /// where 2D coordinates are stored with a SMILES string. This method
        /// forms the basis of CXSMILES.
        /// </remarks>
        /// <example>
        /// <include file='IncludeExamples.xml' path='Comments/Codes[@id="NCDK.Smiles.SmilesGenerator_Example.cs+Create_IAtomContainer_int_int"]/*' />
        /// </example>
        /// <param name="molecule">the molecule to write</param>
        /// <param name="order">array to store the output order of atoms</param>
        /// <returns>the SMILES string</returns>
        /// <exception cref="CDKException">a valid SMILES could not be created</exception>
        public static string Create(IAtomContainer molecule, SmiFlavors flavour, int[] order)
        {
            try
            {
                if (order.Length != molecule.Atoms.Count)
                {
                    throw new ArgumentException("the array for storing output order should be the same length as the number of atoms");
                }

                var g = CDKToBeam.ToBeamGraph(molecule, flavour);

                // apply the canonical labelling
                if (SmiFlavorTool.IsSet(flavour, SmiFlavors.Canonical))
                {
                    // determine the output order
                    var labels = Labels(flavour, molecule);

                    g = g.Permute(labels);

                    if ((flavour & SmiFlavors.AtomAtomMapRenumber) == SmiFlavors.AtomAtomMapRenumber)
                    {
                        g = Functions.RenumberAtomMaps(g);
                    }

                    if (!SmiFlavorTool.IsSet(flavour, SmiFlavors.UseAromaticSymbols))
                    {
                        g = g.Resonate();
                    }

                    if (SmiFlavorTool.IsSet(flavour, SmiFlavors.StereoCisTrans))
                    {
                        // FIXME: required to ensure canonical double bond labelling
                        g.Sort(new Graph.VisitHighOrderFirst());

                        // canonical double-bond stereo, output be C/C=C/C or C\C=C\C
                        // and we need to normalise to one
                        g = Functions.NormaliseDirectionalLabels(g);

                        // visit double bonds first, prefer C1=CC=C1 to C=1C=CC1
                        // visit hydrogens first
                        g.Sort(new Graph.VisitHighOrderFirst()).Sort(new Graph.VisitHydrogenFirst());
                    }

                    var smiles = g.ToSmiles(order);

                    // the SMILES has been generated on a reordered molecule, transform
                    // the ordering
                    var canorder = new int[order.Length];
                    for (int i = 0; i < labels.Length; i++)
                    {
                        canorder[i] = order[labels[i]];
                    }
                    System.Array.Copy(canorder, 0, order, 0, order.Length);

                    if (SmiFlavorTool.IsSet(flavour, SmiFlavors.CxSmilesWithCoords))
                    {
                        smiles += CxSmilesGenerator.Generate(GetCxSmilesState(flavour, molecule), flavour, null, order);
                    }

                    return(smiles);
                }
                else
                {
                    string smiles = g.ToSmiles(order);

                    if (SmiFlavorTool.IsSet(flavour, SmiFlavors.CxSmilesWithCoords))
                    {
                        smiles += CxSmilesGenerator.Generate(GetCxSmilesState(flavour, molecule), flavour, null, order);
                    }

                    return(smiles);
                }
            }
            catch (IOException e)
            {
                throw new CDKException(e.Message);
            }
        }