Esempio n. 1
0
        private static IStereoElement <IChemObject, IChemObject> NewExtendedTetrahedral(int u, Graph g, IAtom[] atoms)
        {
            var terminals = FindExtendedTetrahedralEnds(g, u);
            var xs        = new int[] { -1, terminals[0], -1, terminals[1] };

            int n = 0;

            foreach (var e in g.GetEdges(terminals[0]))
            {
                if (e.Bond.Order == 1)
                {
                    xs[n++] = e.Other(terminals[0]);
                }
            }
            n = 2;
            foreach (var e in g.GetEdges(terminals[1]))
            {
                if (e.Bond.Order == 1)
                {
                    xs[n++] = e.Other(terminals[1]);
                }
            }

            Array.Sort(xs);

            TetrahedralStereo stereo = g.ConfigurationOf(u).Shorthand == Beam.Configuration.Clockwise ? TetrahedralStereo.Clockwise : TetrahedralStereo.AntiClockwise;

            return(new ExtendedTetrahedral(atoms[u], new IAtom[] { atoms[xs[0]], atoms[xs[1]], atoms[xs[2]], atoms[xs[3]] }, stereo));
        }
Esempio n. 2
0
        public void S_penta_2_3_diene_expl_h()
        {
            var m = new AtomContainer();

            m.Atoms.Add(new Atom("C"));
            m.Atoms.Add(new Atom("C"));
            m.Atoms.Add(new Atom("C"));
            m.Atoms.Add(new Atom("C"));
            m.Atoms.Add(new Atom("C"));
            m.Atoms.Add(new Atom("H"));
            m.Atoms.Add(new Atom("H"));
            m.AddBond(m.Atoms[0], m.Atoms[1], BondOrder.Single);
            m.AddBond(m.Atoms[1], m.Atoms[2], BondOrder.Double);
            m.AddBond(m.Atoms[2], m.Atoms[3], BondOrder.Double);
            m.AddBond(m.Atoms[3], m.Atoms[4], BondOrder.Single);
            m.AddBond(m.Atoms[1], m.Atoms[5], BondOrder.Single);
            m.AddBond(m.Atoms[3], m.Atoms[6], BondOrder.Single);

            var atoms   = new int[][] { new[] { 0, 5, 6, 4 }, new[] { 5, 0, 6, 4 }, new[] { 5, 0, 4, 6 }, new[] { 0, 5, 4, 6 }, new[] { 4, 6, 5, 0 }, new[] { 4, 6, 0, 5 }, new[] { 6, 4, 0, 5 }, new[] { 6, 4, 5, 0 }, };
            var stereos = new TetrahedralStereo[] { TetrahedralStereo.Clockwise, TetrahedralStereo.AntiClockwise, TetrahedralStereo.Clockwise, TetrahedralStereo.AntiClockwise, TetrahedralStereo.Clockwise, TetrahedralStereo.AntiClockwise, TetrahedralStereo.Clockwise, TetrahedralStereo.AntiClockwise };

            for (int i = 0; i < atoms.Length; i++)
            {
                var element = new ExtendedTetrahedral(m.Atoms[2], new IAtom[] { m.Atoms[atoms[i][0]], m.Atoms[atoms[i][1]], m.Atoms[atoms[i][2]], m.Atoms[atoms[i][3]] }, stereos[i]);
                m.SetStereoElements(new[] { element });

                Assert.AreEqual("CC(=[C@]=C(C)[H])[H]", Convert(m, SmiFlavors.Stereo).ToSmiles());
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Creates a new data model for chirality for the CIP rules.
        /// </summary>
        /// <param name="chiralAtom">The <see cref="IAtom"/> that is actually chiral.</param>
        /// <param name="ligands">An array with exactly four <see cref="ILigand"/>s.</param>
        /// <param name="stereo">A indication of clockwise or anticlockwise orientation of the atoms.</param>
        /// <seealso cref="TetrahedralStereo"/>
        public LigancyFourChirality(IAtom chiralAtom, IEnumerable <ILigand> ligands, TetrahedralStereo stereo)
        {
            var _ligands = ligands.ToList();

            if (_ligands.Count != 4)
            {
                throw new ArgumentException($"Count of {nameof(ligands)} should be 4.", nameof(ligands));
            }
            this.ChiralAtom = chiralAtom;
            this.ligands    = _ligands;
            this.Stereo     = stereo;
        }
Esempio n. 4
0
        static void AssertTetrahedralCenter(IStereoElement <IChemObject, IChemObject> element,
                                            IAtom focus,
                                            TetrahedralStereo winding,
                                            params IAtom[] neighbors)
        {
            Assert.IsInstanceOfType(element, typeof(ITetrahedralChirality));
            ITetrahedralChirality actual = (ITetrahedralChirality)element;

            Assert.AreSame(focus, actual.ChiralAtom);
            Assert.AreEqual(winding, actual.Stereo);
            Assert.IsTrue(Compares.AreDeepEqual(neighbors, actual.Ligands));
        }
Esempio n. 5
0
 /// <summary>
 /// Get inverted conformation,
 /// </summary>
 /// <remarks>
 /// <see cref="Invert(TetrahedralStereo)"/> of <see cref="Clockwise"/> == <see cref="AntiClockwise"/>
 /// <see cref="Invert(TetrahedralStereo)"/> of <see cref="AntiClockwise"/> == <see cref="Clockwise"/>
 /// </remarks>
 /// <returns>The inverse conformation</returns>
 public static TetrahedralStereo Invert(this TetrahedralStereo value)
 {
     if (value == Clockwise)
     {
         return(AntiClockwise);
     }
     if (value == AntiClockwise)
     {
         return(Clockwise);
     }
     return(value);
 }
Esempio n. 6
0
        public static StereoConfigurations ToConfiguration(this TetrahedralStereo value)
        {
            switch (value)
            {
            case AntiClockwise:
                return(StereoConfigurations.Left);

            case Clockwise:
                return(StereoConfigurations.Right);

            default:
                throw new System.ArgumentException("Unknown enum value: " + value);
            }
        }
Esempio n. 7
0
        // why it does not work? [TestMethod()]
        public void S_penta_2_3_diene_expl_h()
        {
            var m = builder.NewAtomContainer();

            m.Atoms.Add(builder.NewAtom("CH3"));
            m.Atoms.Add(builder.NewAtom("C"));
            m.Atoms.Add(builder.NewAtom("C"));
            m.Atoms.Add(builder.NewAtom("C"));
            m.Atoms.Add(builder.NewAtom("CH3"));
            m.Atoms.Add(builder.NewAtom("H"));
            m.Atoms.Add(builder.NewAtom("H"));
            m.AddBond(m.Atoms[0], m.Atoms[1], BondOrder.Single);
            m.AddBond(m.Atoms[1], m.Atoms[2], BondOrder.Double);
            m.AddBond(m.Atoms[2], m.Atoms[3], BondOrder.Double);
            m.AddBond(m.Atoms[3], m.Atoms[4], BondOrder.Single);
            m.AddBond(m.Atoms[1], m.Atoms[5], BondOrder.Single);
            m.AddBond(m.Atoms[3], m.Atoms[6], BondOrder.Single);

            int[][] atoms = new int[][]
            {
                new[] { 0, 5, 6, 4 }, new[] { 5, 0, 6, 4 },
                new[] { 5, 0, 4, 6 }, new[] { 0, 5, 4, 6 },
                new[] { 4, 6, 5, 0 }, new[] { 4, 6, 0, 5 },
                new[] { 6, 4, 0, 5 }, new[] { 6, 4, 5, 0 },
            };
            var stereos = new TetrahedralStereo[]
            {
                TetrahedralStereo.Clockwise, TetrahedralStereo.Clockwise, TetrahedralStereo.Clockwise, TetrahedralStereo.AntiClockwise,
                TetrahedralStereo.Clockwise, TetrahedralStereo.AntiClockwise, TetrahedralStereo.Clockwise, TetrahedralStereo.Clockwise,
            };

            for (int i = 0; i < atoms.Length; i++)
            {
                var element = new ExtendedTetrahedral(
                    m.Atoms[2],
                    new IAtom[] {
                    m.Atoms[atoms[i][0]],
                    m.Atoms[atoms[i][1]],
                    m.Atoms[atoms[i][2]],
                    m.Atoms[atoms[i][3]]
                },
                    stereos[i]);
                m.SetStereoElements(new[] { element });

                var generator = factory.GetInChIGenerator(m);
                Assert.AreEqual("InChI=1S/C5H8/c1-3-5-4-2/h3-4H,1-2H3/t5-/m1/s1", generator.InChI);
            }
        }
Esempio n. 8
0
 /// <summary>
 /// Get the parity (-1,+1) of the tetrahedral configuration.
 /// </summary>
 /// <param name="stereo">configuration</param>
 /// <returns>the parity</returns>
 private static int Parity(TetrahedralStereo stereo)
 {
     return(stereo == TetrahedralStereo.Clockwise ? 1 : -1);
 }
Esempio n. 9
0
 public ITetrahedralChirality NewTetrahedralChirality(IAtom chiralAtom, IReadOnlyList <IAtom> ligandAtoms, TetrahedralStereo chirality) => (ITetrahedralChirality) new TetrahedralChirality(chiralAtom, ligandAtoms, chirality)
 {
     Builder = this
 };
Esempio n. 10
0
        /// <summary>
        /// Reads atoms, bonds etc from atom container and converts to format
        /// InChI library requires, then places call for the library to generate
        /// the InChI.
        /// </summary>
        /// <param name="atomContainer">AtomContainer to generate InChI for.</param>
        /// <param name="ignore"></param>
        private void GenerateInChIFromCDKAtomContainer(IAtomContainer atomContainer, bool ignore)
        {
            this.ReferringAtomContainer = atomContainer;

            // Check for 3d coordinates
            bool all3d = true;
            bool all2d = true;

            foreach (var atom in atomContainer.Atoms)
            {
                if (all3d && atom.Point3D == null)
                {
                    all3d = false;
                }
                if (all2d && atom.Point2D == null)
                {
                    all2d = false;
                }
            }

            var atomMap = new Dictionary <IAtom, NInchiAtom>();

            foreach (var atom in atomContainer.Atoms)
            {
                // Get coordinates
                // Use 3d if possible, otherwise 2d or none
                double x, y, z;
                if (all3d)
                {
                    var p = atom.Point3D.Value;
                    x = p.X;
                    y = p.Y;
                    z = p.Z;
                }
                else if (all2d)
                {
                    var p = atom.Point2D.Value;
                    x = p.X;
                    y = p.Y;
                    z = 0.0;
                }
                else
                {
                    x = 0.0;
                    y = 0.0;
                    z = 0.0;
                }

                // Chemical element symbol
                var el = atom.Symbol;

                // Generate InChI atom
                var iatom = Input.Add(new NInchiAtom(x, y, z, el));
                atomMap[atom] = iatom;

                // Check if charged
                var charge = atom.FormalCharge.Value;
                if (charge != 0)
                {
                    iatom.Charge = charge;
                }

                // Check whether isotopic
                var isotopeNumber = atom.MassNumber;
                if (isotopeNumber != null)
                {
                    iatom.IsotopicMass = isotopeNumber.Value;
                }

                // Check for implicit hydrogens
                // atom.HydrogenCount returns number of implicit hydrogens, not
                // total number
                // Ref: Posting to cdk-devel list by Egon Willighagen 2005-09-17
                int?implicitH = atom.ImplicitHydrogenCount;

                // set implicit hydrogen count, -1 tells the inchi to determine it
                iatom.ImplicitH = implicitH ?? -1;

                // Check if radical
                int count = atomContainer.GetConnectedSingleElectrons(atom).Count();
                if (count == 0)
                {
                    // TODO - how to check whether singlet or undefined multiplicity
                }
                else if (count == 1)
                {
                    iatom.Radical = INCHI_RADICAL.Doublet;
                }
                else if (count == 2)
                {
                    iatom.Radical = INCHI_RADICAL.Triplet;
                }
                else
                {
                    throw new CDKException("Unrecognised radical type");
                }
            }

            // Process bonds
            var bondMap = new Dictionary <IBond, NInchiBond>();

            foreach (var bond in atomContainer.Bonds)
            {
                // Assumes 2 centre bond
                var at0 = atomMap[bond.Begin];
                var at1 = atomMap[bond.End];

                // Get bond order
                INCHI_BOND_TYPE order;
                var             bo = bond.Order;
                if (!ignore && bond.IsAromatic)
                {
                    order = INCHI_BOND_TYPE.Altern;
                }
                else if (bo == BondOrder.Single)
                {
                    order = INCHI_BOND_TYPE.Single;
                }
                else if (bo == BondOrder.Double)
                {
                    order = INCHI_BOND_TYPE.Double;
                }
                else if (bo == BondOrder.Triple)
                {
                    order = INCHI_BOND_TYPE.Triple;
                }
                else
                {
                    throw new CDKException("Failed to generate InChI: Unsupported bond type");
                }

                // Create InChI bond
                var ibond = new NInchiBond(at0, at1, order);
                bondMap[bond] = ibond;
                Input.Add(ibond);

                // Check for bond stereo definitions
                var stereo = bond.Stereo;
                // No stereo definition
                if (stereo == BondStereo.None)
                {
                    ibond.BondStereo = INCHI_BOND_STEREO.None;
                }
                // Bond ending (fat end of wedge) below the plane
                else if (stereo == BondStereo.Down)
                {
                    ibond.BondStereo = INCHI_BOND_STEREO.Single1Down;
                }
                // Bond ending (fat end of wedge) above the plane
                else if (stereo == BondStereo.Up)
                {
                    ibond.BondStereo = INCHI_BOND_STEREO.Single1Up;
                }
                // Bond starting (pointy end of wedge) below the plane
                else if (stereo == BondStereo.DownInverted)
                {
                    ibond.BondStereo = INCHI_BOND_STEREO.Single2Down;
                }
                // Bond starting (pointy end of wedge) above the plane
                else if (stereo == BondStereo.UpInverted)
                {
                    ibond.BondStereo = INCHI_BOND_STEREO.Single2Up;
                }
                else if (stereo == BondStereo.EOrZ)
                {
                    ibond.BondStereo = INCHI_BOND_STEREO.DoubleEither;
                }
                else if (stereo == BondStereo.UpOrDown)
                {
                    ibond.BondStereo = INCHI_BOND_STEREO.Single1Either;
                }
                else if (stereo == BondStereo.UpOrDownInverted)
                {
                    ibond.BondStereo = INCHI_BOND_STEREO.Single2Either;
                }
                // Bond with undefined stereochemistry
                else if (stereo == BondStereo.None)
                {
                    if (order == INCHI_BOND_TYPE.Single)
                    {
                        ibond.BondStereo = INCHI_BOND_STEREO.Single1Either;
                    }
                    else if (order == INCHI_BOND_TYPE.Double)
                    {
                        ibond.BondStereo = INCHI_BOND_STEREO.DoubleEither;
                    }
                }
            }

            // Process tetrahedral stereo elements
            foreach (var stereoElem in atomContainer.StereoElements)
            {
                if (stereoElem is ITetrahedralChirality chirality)
                {
                    var stereoType = chirality.Stereo;

                    var atC = atomMap[chirality.ChiralAtom];
                    var at0 = atomMap[chirality.Ligands[0]];
                    var at1 = atomMap[chirality.Ligands[1]];
                    var at2 = atomMap[chirality.Ligands[2]];
                    var at3 = atomMap[chirality.Ligands[3]];
                    var p   = INCHI_PARITY.Unknown;
                    if (stereoType == TetrahedralStereo.AntiClockwise)
                    {
                        p = INCHI_PARITY.Odd;
                    }
                    else if (stereoType == TetrahedralStereo.Clockwise)
                    {
                        p = INCHI_PARITY.Even;
                    }
                    else
                    {
                        throw new CDKException("Unknown tetrahedral chirality");
                    }

                    var jniStereo = new NInchiStereo0D(atC, at0, at1, at2, at3, INCHI_STEREOTYPE.Tetrahedral, p);
                    Input.Stereos.Add(jniStereo);
                }
                else if (stereoElem is IDoubleBondStereochemistry dbStereo)
                {
                    var surroundingBonds = dbStereo.Bonds;
                    if (surroundingBonds[0] == null || surroundingBonds[1] == null)
                    {
                        throw new CDKException("Cannot generate an InChI with incomplete double bond info");
                    }
                    var stereoType = dbStereo.Stereo;

                    IBond      stereoBond = dbStereo.StereoBond;
                    NInchiAtom at0        = null;
                    NInchiAtom at1        = null;
                    NInchiAtom at2        = null;
                    NInchiAtom at3        = null;
                    // TODO: I should check for two atom bonds... or maybe that should happen when you
                    //    create a double bond stereochemistry
                    if (stereoBond.Contains(surroundingBonds[0].Begin))
                    {
                        // first atom is A
                        at1 = atomMap[surroundingBonds[0].Begin];
                        at0 = atomMap[surroundingBonds[0].End];
                    }
                    else
                    {
                        // first atom is X
                        at0 = atomMap[surroundingBonds[0].Begin];
                        at1 = atomMap[surroundingBonds[0].End];
                    }
                    if (stereoBond.Contains(surroundingBonds[1].Begin))
                    {
                        // first atom is B
                        at2 = atomMap[surroundingBonds[1].Begin];
                        at3 = atomMap[surroundingBonds[1].End];
                    }
                    else
                    {
                        // first atom is Y
                        at2 = atomMap[surroundingBonds[1].End];
                        at3 = atomMap[surroundingBonds[1].Begin];
                    }
                    var p = INCHI_PARITY.Unknown;
                    if (stereoType == DoubleBondConformation.Together)
                    {
                        p = INCHI_PARITY.Odd;
                    }
                    else if (stereoType == DoubleBondConformation.Opposite)
                    {
                        p = INCHI_PARITY.Even;
                    }
                    else
                    {
                        throw new CDKException("Unknown double bond stereochemistry");
                    }

                    var jniStereo = new NInchiStereo0D(null, at0, at1, at2, at3, INCHI_STEREOTYPE.DoubleBond, p);
                    Input.Stereos.Add(jniStereo);
                }
                else if (stereoElem is ExtendedTetrahedral extendedTetrahedral)
                {
                    TetrahedralStereo winding = extendedTetrahedral.Winding;

                    // The peripherals (p<i>) and terminals (t<i>) are referring to
                    // the following atoms. The focus (f) is also shown.
                    //
                    //   p0          p2
                    //    \          /
                    //     t0 = f = t1
                    //    /         \
                    //   p1         p3
                    var terminals   = extendedTetrahedral.FindTerminalAtoms(atomContainer);
                    var peripherals = extendedTetrahedral.Peripherals.ToArray();

                    // InChI API is particular about the input, each terminal atom
                    // needs to be present in the list of neighbors and they must
                    // be at index 1 and 2 (i.e. in the middle). This is true even
                    // of explicit atoms. For the implicit atoms, the terminals may
                    // be in the peripherals already and so we correct the winding
                    // and reposition as needed.

                    var t0Bonds = OnlySingleBonded(atomContainer.GetConnectedBonds(terminals[0]));
                    var t1Bonds = OnlySingleBonded(atomContainer.GetConnectedBonds(terminals[1]));

                    // first if there are two explicit atoms we need to replace one
                    // with the terminal atom - the configuration does not change
                    if (t0Bonds.Count == 2)
                    {
                        var orgBond = t0Bonds[0];
                        t0Bonds.RemoveAt(0);
                        var replace = orgBond.GetOther(terminals[0]);
                        for (int i = 0; i < peripherals.Length; i++)
                        {
                            if (replace == peripherals[i])
                            {
                                peripherals[i] = terminals[0];
                            }
                        }
                    }

                    if (t1Bonds.Count == 2)
                    {
                        var orgBond = t0Bonds[0];
                        t1Bonds.RemoveAt(0);
                        var replace = orgBond.GetOther(terminals[1]);
                        for (int i = 0; i < peripherals.Length; i++)
                        {
                            if (replace == peripherals[i])
                            {
                                peripherals[i] = terminals[1];
                            }
                        }
                    }

                    // the neighbor attached to each terminal atom that we will
                    // define the configuration of
                    var t0Neighbor = t0Bonds[0].GetOther(terminals[0]);
                    var t1Neighbor = t1Bonds[0].GetOther(terminals[1]);

                    // we now need to move all the atoms into the correct positions
                    // everytime we exchange atoms the configuration inverts
                    for (int i = 0; i < peripherals.Length; i++)
                    {
                        if (i != 0 && t0Neighbor == peripherals[i])
                        {
                            Swap(peripherals, i, 0);
                            winding = winding.Invert();
                        }
                        else if (i != 1 && terminals[0] == peripherals[i])
                        {
                            Swap(peripherals, i, 1);
                            winding = winding.Invert();
                        }
                        else if (i != 2 && terminals[1] == peripherals[i])
                        {
                            Swap(peripherals, i, 2);
                            winding = winding.Invert();
                        }
                        else if (i != 3 && t1Neighbor == peripherals[i])
                        {
                            Swap(peripherals, i, 3);
                            winding = winding.Invert();
                        }
                    }

                    var parity = INCHI_PARITY.Unknown;
                    if (winding == TetrahedralStereo.AntiClockwise)
                    {
                        parity = INCHI_PARITY.Odd;
                    }
                    else if (winding == TetrahedralStereo.Clockwise)
                    {
                        parity = INCHI_PARITY.Even;
                    }
                    else
                    {
                        throw new CDKException("Unknown extended tetrahedral chirality");
                    }

                    NInchiStereo0D jniStereo = new NInchiStereo0D(atomMap[extendedTetrahedral.Focus],
                                                                  atomMap[peripherals[0]], atomMap[peripherals[1]], atomMap[peripherals[2]],
                                                                  atomMap[peripherals[3]], INCHI_STEREOTYPE.Allene, parity);
                    Input.Stereos.Add(jniStereo);
                }
            }

            try
            {
                Output = NInchiWrapper.GetInchi(Input);
            }
            catch (NInchiException jie)
            {
                throw new CDKException("Failed to generate InChI: " + jie.Message, jie);
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Creates a ligancy for chirality around a single chiral atom, where the involved
        /// atoms are identified by there index in the <see cref="IAtomContainer"/>. For the four ligand
        /// atoms, <see cref="Hydrogen"/> can be passed as index, which will indicate the presence of
        /// an implicit hydrogen, not explicitly present in the chemical graph of the
        /// given <paramref name="container"/>.
        /// </summary>
        /// <param name="container"><see cref="IAtomContainer"/> for which the returned <see cref="ILigand"/>s are defined</param>
        /// <param name="chiralAtom">int pointing to the <see cref="IAtom"/> index of the chiral atom</param>
        /// <param name="ligand1">int pointing to the <see cref="IAtom"/> index of the first <see cref="ILigand"/></param>
        /// <param name="ligand2">int pointing to the <see cref="IAtom"/> index of the second <see cref="ILigand"/></param>
        /// <param name="ligand3">int pointing to the <see cref="IAtom"/> index of the third <see cref="ILigand"/></param>
        /// <param name="ligand4">int pointing to the <see cref="IAtom"/> index of the fourth <see cref="ILigand"/></param>
        /// <param name="stereo"><see cref="TetrahedralStereo"/> for the chirality</param>
        /// <returns>the created <see cref="LigancyFourChirality"/></returns>
        public static LigancyFourChirality DefineLigancyFourChirality(IAtomContainer container, int chiralAtom, int ligand1, int ligand2, int ligand3, int ligand4, TetrahedralStereo stereo)
        {
            var atomIndices  = new int[] { ligand1, ligand2, ligand3, ligand4 };
            var visitedAtoms = new VisitedAtoms();
            var ligands      = new ILigand[4];

            for (int i = 0; i < 4; i++)
            {
                ligands[i] = DefineLigand(container, visitedAtoms, chiralAtom, atomIndices[i]);
            }
            return(new LigancyFourChirality(container.Atoms[chiralAtom], ligands, stereo));
        }
Esempio n. 12
0
 /// <summary>
 /// Create an extended tetrahedral stereo element for the provided 'focus'
 /// and 'peripherals' in the given 'winding'. See class documentation an
 /// annotated storage description.
 /// </summary>
 /// <param name="focus">the central cumulated atom</param>
 /// <param name="peripherals">atoms attached to the terminal atoms</param>
 /// <param name="winding">the configuration</param>
 public ExtendedTetrahedral(IAtom focus, IEnumerable <IAtom> peripherals, TetrahedralStereo winding)
     : this(focus, peripherals, winding.ToConfiguration())
 {
 }
Esempio n. 13
0
 public WoundProjection(Projection projection, TetrahedralStereo winding)
 {
     this.Projection = projection;
     this.Winding    = winding;
 }
Esempio n. 14
0
 public TetrahedralChirality(IAtom chiralAtom, IReadOnlyList <IAtom> ligands, TetrahedralStereo stereo)
     : this(chiralAtom, ligands, stereo.ToConfiguration())
 {
 }
Esempio n. 15
0
 public static bool IsUnset(this TetrahedralStereo value)
 => value == Unset;