Beispiel #1
0
        public void TestExampleStructure2InchiAlanine()
        {
            // START SNIPPET: structure2inchi-alanine
            // Example input - 0D D-Alanine
            NInchiInput input = new NInchiInput();
            //
            // Generate atoms
            NInchiAtom a1 = input.Add(new NInchiAtom(0.0, 0.0, 0.0, "C"));
            NInchiAtom a2 = input.Add(new NInchiAtom(0.0, 0.0, 0.0, "C"));
            NInchiAtom a3 = input.Add(new NInchiAtom(0.0, 0.0, 0.0, "N"));
            NInchiAtom a4 = input.Add(new NInchiAtom(0.0, 0.0, 0.0, "C"));
            NInchiAtom a5 = input.Add(new NInchiAtom(0.0, 0.0, 0.0, "O"));
            NInchiAtom a6 = input.Add(new NInchiAtom(0.0, 0.0, 0.0, "O"));
            NInchiAtom a7 = input.Add(new NInchiAtom(0.0, 0.0, 0.0, "H"));

            a3.ImplicitH = 2;
            a4.ImplicitH = 3;
            a5.ImplicitH = 1;
            //
            // Add bonds
            input.Add(new NInchiBond(a1, a2, INCHI_BOND_TYPE.Single));
            input.Add(new NInchiBond(a1, a3, INCHI_BOND_TYPE.Single));
            input.Add(new NInchiBond(a1, a4, INCHI_BOND_TYPE.Single));
            input.Add(new NInchiBond(a2, a5, INCHI_BOND_TYPE.Single));
            input.Add(new NInchiBond(a2, a6, INCHI_BOND_TYPE.Double));
            input.Add(new NInchiBond(a1, a7, INCHI_BOND_TYPE.Single));
            //
            // Add stereo parities
            input.Stereos.Add(NInchiStereo0D
                              .CreateNewTetrahedralStereo0D(a1, a3, a4, a7, a2, INCHI_PARITY.Even));
            //
            NInchiOutput output = NInchiWrapper.GetInchi(input);
            // END SNIPPET: structure2inchi-alanine
        }
Beispiel #2
0
 public void TestCheckInchi()
 {
     // START SNIPPET: checkinchi
     bool         strict = true;
     INCHI_STATUS status = NInchiWrapper.CheckInchi("InChI=1S/C2H6/c1-2/h1-2H3", strict);
     // END SNIPPET: checkinchi
 }
Beispiel #3
0
 public void TestInchi2InchiKey()
 {
     // START SNIPPET: inchi2inchikey
     NInchiOutputKey output = NInchiWrapper.GetInchiKey("InChI=1S/C2H6/c1-2/h1-2H3");
     string          key    = output.Key;
     // END SNIPPET: inchi2inchikey
 }
Beispiel #4
0
 public void TestAuxinfo2Input()
 {
     // START SNIPPET: auxinfo2input
     NInchiInputData data = NInchiWrapper.GetInputFromAuxInfo("AuxInfo=1/1/N:4,1,2,3,5,6/"
                                                              + "E:(5,6)/it:im/rA:6CCNCOO/rB:s1;N1;s1;s2;d2;/rC:264,968,0;295,985,0;233,986,0;"
                                                              + "264,932,0;326,967,0;295,1021,0;");
     InChIReturnCode ret   = data.ReturnStatus;
     NInchiInput     input = data.Input;
     // END SNIPPET: auxinfo2input
 }
Beispiel #5
0
 public void TestInchi2InchiHydrogen()
 {
     // START SNIPPET: inchi2inchi-hydrogen
     // Input InChI with fixed-hydrogen layer
     string inchiIn = "InChI=1/C3H7NO2/c1-2(4)3(5)6/h2H,4H2,1H3,(H,5,6)/"
                      + "t2-/m0/s1/f/h5H";
     //
     NInchiOutput output = NInchiWrapper.GetInchiFromInchi(
         new NInchiInputInchi(inchiIn));
     string inchiOut = output.InChI;
     // Output InChI:
     //   InChI=1/C3H7NO2/c1-2(4)3(5)6/h2H,4H2,1H3,(H,5,6)/t2-/m0/s1
     // END SNIPPET: inchi2inchi-hydrogen
 }
Beispiel #6
0
 public void TestInchi2Structure()
 {
     // START SNIPPET: inchi2structure
     NInchiInputInchi      input  = new NInchiInputInchi("InChI=1/C2H6/c1-2/h1-2H3");
     NInchiOutputStructure output = NInchiWrapper.GetStructureFromInchi(input);
     //
     InChIReturnCode retStatus = output.ReturnStatus;
     int             nat       = output.Atoms.Count;
     int             nbo       = output.Bonds.Count;
     int             nst       = output.Stereos.Count;
     //
     NInchiAtom at0 = output.Atoms[0];
     // END SNIPPET: inchi2structure
 }
Beispiel #7
0
 public void TestInchi2InchiCompress()
 {
     // START SNIPPET: inchi2inchi-compress
     string inchi = "InChI=1/C3H7NO2/c1-2(4)3(5)6/h2H,4H2,1H3,(H,5,6)";
     //
     // Compress InChI
     NInchiOutput cout = NInchiWrapper.GetInchiFromInchi(
         new NInchiInputInchi(inchi, "-compress"));
     string compressedInchi = cout.InChI;
     // compressedInchi = InChI=1/C3H7NO2/cABBCC/hB1D2A3,1EF
     //
     // Uncompress InChI
     NInchiOutput ucout = NInchiWrapper.GetInchiFromInchi(
         new NInchiInputInchi(compressedInchi));
     string uncompressedInchi = ucout.InChI;
     // uncompressedInchi = InChI=1/C3H7NO2/c1-2(4)3(5)6/h2H,4H2,1H3,(H,5,6)
     // END SNIPPET: inchi2inchi-compress
 }
Beispiel #8
0
 /// <summary>
 /// Gets generated InChIKey string.
 /// </summary>
 public string GetInChIKey()
 {
     try
     {
         var key = NInchiWrapper.GetInchiKey(Output.InChI);
         if (key.ReturnStatus == INCHI_KEY.OK)
         {
             return(key.Key);
         }
         else
         {
             throw new CDKException("Error while creating InChIKey: " + key.ReturnStatus);
         }
     }
     catch (NInchiException exception)
     {
         throw new CDKException("Error while creating InChIKey: " + exception.Message, exception);
     }
 }
Beispiel #9
0
        public void TestExampleStructure2InchiDiChloroethene()
        {
            // START SNIPPET: structure2inchi-dichloroethene
            // Example input - 2D E-1,2-dichloroethene
            NInchiInput input = new NInchiInput();
            //
            // Generate atoms
            NInchiAtom a1 = input.Add(new NInchiAtom(2.866, -0.250, 0.000, "C"));
            NInchiAtom a2 = input.Add(new NInchiAtom(3.732, 0.250, 0.000, "C"));
            NInchiAtom a3 = input.Add(new NInchiAtom(2.000, 2.500, 0.000, "Cl"));
            NInchiAtom a4 = input.Add(new NInchiAtom(4.598, -0.250, 0.000, "Cl"));

            a1.ImplicitH = 1;
            a2.ImplicitH = 1;
            //
            // Add bond
            input.Add(new NInchiBond(a1, a2, INCHI_BOND_TYPE.Double));
            input.Add(new NInchiBond(a1, a3, INCHI_BOND_TYPE.Single));
            input.Add(new NInchiBond(a2, a4, INCHI_BOND_TYPE.Single));
            NInchiOutput output = NInchiWrapper.GetInchi(input);
            //END SNIPPET: structure2inchi - dichloroethene
        }
Beispiel #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);
            }
        }
Beispiel #11
0
 /// <summary>
 /// Constructor.
 /// <param name="inchi">InChI string</param>
 /// <param name="opts">Options</param>
 /// </summary>
 public NInchiInputInchi(string inchi, IEnumerable <InChIOption> opts)
 {
     Inchi   = inchi;
     Options = NInchiWrapper.CheckOptions(opts);
 }
Beispiel #12
0
 /// <summary>
 /// Constructor.
 /// <param name="inchi">InChI string</param>
 /// <param name="opts">Options</param>
 /// </summary>
 public NInchiInputInchi(string inchi, string opts)
 {
     this.Inchi   = inchi;
     this.Options = NInchiWrapper.CheckOptions(opts);
 }
Beispiel #13
0
        /// <summary>
        /// Gets structure from InChI, and converts InChI library data structure into an IAtomContainer.
        /// </summary>
        /// <param name="builder"></param>
        private void GenerateAtomContainerFromInChI(IChemObjectBuilder builder)
        {
            try
            {
                output = NInchiWrapper.GetStructureFromInchi(input);
            }
            catch (NInchiException jie)
            {
                throw new CDKException("Failed to convert InChI to molecule: " + jie.Message, jie);
            }

            //molecule = new AtomContainer();
            AtomContainer = builder.NewAtomContainer();

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

            for (int i = 0; i < output.Atoms.Count; i++)
            {
                var iAt = output.Atoms[i];
                var cAt = builder.NewAtom();

                inchiCdkAtomMap[iAt] = cAt;

                cAt.Id           = "a" + i;
                cAt.Symbol       = iAt.ElementType;
                cAt.AtomicNumber = PeriodicTable.GetAtomicNumber(cAt.Symbol);

                // Ignore coordinates - all zero - unless aux info was given... but
                // the CDK doesn't have an API to provide that

                // InChI does not have unset properties so we set charge,
                // hydrogen count (implicit) and isotopic mass
                cAt.FormalCharge          = iAt.Charge;
                cAt.ImplicitHydrogenCount = iAt.ImplicitH;

                var isotopicMass = iAt.IsotopicMass;

                if (isotopicMass != 0)
                {
                    if (ISOTOPIC_SHIFT_FLAG == (isotopicMass & ISOTOPIC_SHIFT_FLAG))
                    {
                        try
                        {
                            var massNumber = CDK.IsotopeFactory.GetMajorIsotope(cAt.AtomicNumber).MassNumber.Value;
                            cAt.MassNumber = massNumber + (isotopicMass - ISOTOPIC_SHIFT_FLAG);
                        }
                        catch (IOException e)
                        {
                            throw new CDKException("Could not load Isotopes data", e);
                        }
                    }
                    else
                    {
                        cAt.MassNumber = isotopicMass;
                    }
                }

                AtomContainer.Atoms.Add(cAt);

                cAt = AtomContainer.Atoms[AtomContainer.Atoms.Count - 1];
                for (int j = 0; j < iAt.ImplicitDeuterium; j++)
                {
                    var deut = builder.NewAtom();
                    deut.AtomicNumber          = 1;
                    deut.Symbol                = "H";
                    deut.MassNumber            = 2;
                    deut.ImplicitHydrogenCount = 0;
                    AtomContainer.Atoms.Add(deut);
                    deut = AtomContainer.Atoms[AtomContainer.Atoms.Count - 1];
                    var bond = builder.NewBond(cAt, deut, BondOrder.Single);
                    AtomContainer.Bonds.Add(bond);
                }
                for (int j = 0; j < iAt.ImplicitTritium; j++)
                {
                    var trit = builder.NewAtom();
                    trit.AtomicNumber          = 1;
                    trit.Symbol                = "H";
                    trit.MassNumber            = 3;
                    trit.ImplicitHydrogenCount = 0;
                    AtomContainer.Atoms.Add(trit);
                    trit = AtomContainer.Atoms[AtomContainer.Atoms.Count - 1];
                    var bond = builder.NewBond(cAt, trit, BondOrder.Single);
                    AtomContainer.Bonds.Add(bond);
                }
            }

            for (int i = 0; i < output.Bonds.Count; i++)
            {
                var iBo = output.Bonds[i];

                var atO = inchiCdkAtomMap[iBo.OriginAtom];
                var atT = inchiCdkAtomMap[iBo.TargetAtom];
                var cBo = builder.NewBond(atO, atT);

                var type = iBo.BondType;
                switch (type)
                {
                case INCHI_BOND_TYPE.Single:
                    cBo.Order = BondOrder.Single;
                    break;

                case INCHI_BOND_TYPE.Double:
                    cBo.Order = BondOrder.Double;
                    break;

                case INCHI_BOND_TYPE.Triple:
                    cBo.Order = BondOrder.Triple;
                    break;

                case INCHI_BOND_TYPE.Altern:
                    cBo.IsAromatic = true;
                    break;

                default:
                    throw new CDKException("Unknown bond type: " + type);
                }

                var stereo = iBo.BondStereo;
                switch (stereo)
                {
                // No stereo definition
                case INCHI_BOND_STEREO.None:
                    cBo.Stereo = BondStereo.None;
                    break;

                // Bond ending (fat end of wedge) below the plane
                case INCHI_BOND_STEREO.Single1Down:
                    cBo.Stereo = BondStereo.Down;
                    break;

                // Bond ending (fat end of wedge) above the plane
                case INCHI_BOND_STEREO.Single1Up:
                    cBo.Stereo = BondStereo.Up;
                    break;

                // Bond starting (pointy end of wedge) below the plane
                case INCHI_BOND_STEREO.Single2Down:
                    cBo.Stereo = BondStereo.DownInverted;
                    break;

                // Bond starting (pointy end of wedge) above the plane
                case INCHI_BOND_STEREO.Single2Up:
                    cBo.Stereo = BondStereo.UpInverted;
                    break;

                // Bond with undefined stereochemistry
                case INCHI_BOND_STEREO.Single1Either:
                case INCHI_BOND_STEREO.DoubleEither:
                    cBo.Stereo = BondStereo.None;
                    break;
                }
                AtomContainer.Bonds.Add(cBo);
            }

            for (int i = 0; i < output.Stereos.Count; i++)
            {
                var stereo0d = output.Stereos[i];
                if (stereo0d.StereoType == INCHI_STEREOTYPE.Tetrahedral ||
                    stereo0d.StereoType == INCHI_STEREOTYPE.Allene)
                {
                    var central    = stereo0d.CentralAtom;
                    var neighbours = stereo0d.Neighbors;

                    var focus     = inchiCdkAtomMap[central];
                    var neighbors = new IAtom[]
                    {
                        inchiCdkAtomMap[neighbours[0]],
                        inchiCdkAtomMap[neighbours[1]],
                        inchiCdkAtomMap[neighbours[2]],
                        inchiCdkAtomMap[neighbours[3]]
                    };
                    TetrahedralStereo stereo;

                    // as per JNI InChI doc even is clockwise and odd is
                    // anti-clockwise
                    switch (stereo0d.Parity)
                    {
                    case INCHI_PARITY.Odd:
                        stereo = TetrahedralStereo.AntiClockwise;
                        break;

                    case INCHI_PARITY.Even:
                        stereo = TetrahedralStereo.Clockwise;
                        break;

                    default:
                        // CDK Only supports parities of + or -
                        continue;
                    }

                    IStereoElement <IChemObject, IChemObject> stereoElement = null;

                    switch (stereo0d.StereoType)
                    {
                    case INCHI_STEREOTYPE.Tetrahedral:
                        stereoElement = builder.NewTetrahedralChirality(focus, neighbors, stereo);
                        break;

                    case INCHI_STEREOTYPE.Allene:
                    {
                        // The periphals (p<i>) and terminals (t<i>) are refering to
                        // the following atoms. The focus (f) is also shown.
                        //
                        //   p0          p2
                        //    \          /
                        //     t0 = f = t1
                        //    /         \
                        //   p1         p3
                        var peripherals = neighbors;
                        var terminals   = ExtendedTetrahedral.FindTerminalAtoms(AtomContainer, focus);

                        // InChI always provides the terminal atoms t0 and t1 as
                        // periphals, here we find where they are and then add in
                        // the other explicit atom. As the InChI create hydrogens
                        // for stereo elements, there will always we an explicit
                        // atom that can be found - it may be optionally suppressed
                        // later.

                        // not much documentation on this (at all) but they appear
                        // to always be the middle two atoms (index 1, 2) we therefore
                        // test these first - but handle the other indices just in
                        // case
                        foreach (var terminal in terminals)
                        {
                            if (peripherals[1].Equals(terminal))
                            {
                                peripherals[1] = FindOtherSinglyBonded(AtomContainer, terminal, peripherals[0]);
                            }
                            else if (peripherals[2].Equals(terminal))
                            {
                                peripherals[2] = FindOtherSinglyBonded(AtomContainer, terminal, peripherals[3]);
                            }
                            else if (peripherals[0].Equals(terminal))
                            {
                                peripherals[0] = FindOtherSinglyBonded(AtomContainer, terminal, peripherals[1]);
                            }
                            else if (peripherals[3].Equals(terminal))
                            {
                                peripherals[3] = FindOtherSinglyBonded(AtomContainer, terminal, peripherals[2]);
                            }
                        }

                        stereoElement = new ExtendedTetrahedral(focus, peripherals, stereo);
                    }
                    break;
                    }

                    Trace.Assert(stereoElement != null);
                    AtomContainer.StereoElements.Add(stereoElement);
                }
                else if (stereo0d.StereoType == INCHI_STEREOTYPE.DoubleBond)
                {
                    NInchiAtom[] neighbors = stereo0d.Neighbors;

                    // from JNI InChI doc
                    //                            neighbor[4]  : {#X,#A,#B,#Y} in this order
                    // X                          central_atom : NO_ATOM
                    //  \            X        Y   type         : INCHI_StereoType_DoubleBond
                    //   A == B       \      /
                    //         \       A == B
                    //          Y
                    var x = inchiCdkAtomMap[neighbors[0]];
                    var a = inchiCdkAtomMap[neighbors[1]];
                    var b = inchiCdkAtomMap[neighbors[2]];
                    var y = inchiCdkAtomMap[neighbors[3]];

                    // XXX: AtomContainer is doing slow lookup
                    var stereoBond = AtomContainer.GetBond(a, b);
                    stereoBond.SetAtoms(new[] { a, b }); // ensure a is first atom

                    var conformation = DoubleBondConformation.Unset;

                    switch (stereo0d.Parity)
                    {
                    case INCHI_PARITY.Odd:
                        conformation = DoubleBondConformation.Together;
                        break;

                    case INCHI_PARITY.Even:
                        conformation = DoubleBondConformation.Opposite;
                        break;
                    }

                    // unspecified not stored
                    if (conformation.IsUnset())
                    {
                        continue;
                    }

                    AtomContainer.StereoElements.Add(new DoubleBondStereochemistry(stereoBond, new IBond[] { AtomContainer.GetBond(x, a),
                                                                                                             AtomContainer.GetBond(b, y) }, conformation));
                }
                else
                {
                    // TODO - other types of atom parity - double bond, etc
                }
            }
        }
Beispiel #14
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="opts">List of options.</param>
 public NInchiInput(IList <InChIOption> opts)
 {
     Options = NInchiWrapper.CheckOptions(opts);
 }
Beispiel #15
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="opts">Options string.</param>
 public NInchiInput(string opts)
 {
     Options = opts == null ? "" : NInchiWrapper.CheckOptions(opts);
 }
Beispiel #16
0
 public void TestCheckInchiKey()
 {
     // START SNIPPET: checkinchikey
     INCHI_KEY_STATUS status = NInchiWrapper.CheckInchiKey("OTMSDBZUPAUEDD-UHFFFAOYSA-N");
     // END SNIPPET: checkinchikey
 }