Esempio n. 1
0
        private static int BondStereoFromModel(BondStereo modelBondStereo)
        {
            //Translates from the model enumerated bond stereochemistry to the molfile convention
            //The opposite of BondStereoFromMolfile
            int molfileStereo = 0;

            //MODEL  : 0 is None,       1 is Wedge, 2 is Hatch, 3 is Indeterminate
            //MOLFILE: 0 is NOT stereo, 1 is UP,    6 is DOWN,  4 is EITHER
            switch (modelBondStereo)
            {
            case Enums.BondStereo.None:
                molfileStereo = 0;
                break;

            case Enums.BondStereo.Wedge:
                molfileStereo = 1;
                break;

            case Enums.BondStereo.Hatch:
                molfileStereo = 6;
                break;

            case Enums.BondStereo.Indeterminate:
                molfileStereo = 4;
                break;

            default:
                molfileStereo = 4;
                break;
            }
            return(molfileStereo);
        }
Esempio n. 2
0
        /// <summary>
        /// Test whether we accept atom and it's connected bonds for inclusion in a
        /// double bond configuration. This method checks for query bonds (up/down)
        /// as well as double bond counts. If there is more then one double bond in
        /// the connect bonds then it cannot have Z/E configuration.
        /// </summary>
        /// <param name="atom">a double bonded atom</param>
        /// <param name="bonds">all bonds connected to the atom</param>
        /// <returns>whether the atom is accepted for configuration</returns>
        internal static bool Accept(IAtom atom, IEnumerable <IBond> bonds)
        {
            int dbCount = 0;

            // not SP2
            if (!Hybridization.SP2.Equals(atom.Hybridization))
            {
                return(false);
            }

            // only have one neighbour (which is the other atom) -> this is no configurable
            if (bonds.Count() == 1)
            {
                return(false);
            }

            foreach (var bond in bonds)
            {
                // increment the number of double bonds
                if (BondOrder.Double.Equals(bond.Order))
                {
                    dbCount++;
                }

                // up/down bonds sometimes used to indicate E/Z
                BondStereo stereo = bond.Stereo;
                if (BondStereo.UpOrDown.Equals(stereo) || BondStereo.UpOrDownInverted.Equals(stereo))
                {
                    return(false);
                }
            }

            // not cumulated
            return(dbCount == 1);
        }
Esempio n. 3
0
        private string GetStereoString(BondStereo stereo)
        {
            switch (stereo)
            {
            case BondStereo.None:
                return(null);

            case BondStereo.Hatch:
                return("H");

            case BondStereo.Wedge:
                return("W");

            case BondStereo.Cis:
                return("C");

            case BondStereo.Trans:
                return("T");

            case BondStereo.Indeterminate:
                return("S");

            default:
                return(null);
            }
        }
Esempio n. 4
0
        private IRenderingElement GenerateStereoElement(IBond bond, RendererModel model)
        {
            BondStereo stereo = bond.Stereo;

            WedgeLineElement.WedgeType type = WedgeLineElement.WedgeType.Wedged;
            BondDirection dir = BondDirection.ToSecond;

            switch (stereo)
            {
            case BondStereo.Down:
            case BondStereo.DownInverted:
                type = WedgeLineElement.WedgeType.Dashed;
                break;

            case BondStereo.UpOrDown:
            case BondStereo.UpOrDownInverted:
                type = WedgeLineElement.WedgeType.Indiff;
                break;
            }
            switch (stereo)
            {
            case BondStereo.DownInverted:
            case BondStereo.UpInverted:
            case BondStereo.UpOrDownInverted:
                dir = BondDirection.ToFirst;
                break;
            }

            IRenderingElement base_ = GenerateBondElement(bond, BondOrder.Single, model);

            return(new WedgeLineElement((LineElement)base_, type, dir, GetColorForBond(bond, model)));
        }
Esempio n. 5
0
        public Bond AddBond(Atom atom, BondType type, BondStereo stereo, BondTopology topology, BondReactingCenterStatus rcStatus)
        {
            Bond b = new Bond(this, atom, type, BondStereo.NotStereoOrUseXYZ, BondTopology.Either, BondReactingCenterStatus.notACenter);

            this.BondedAtoms.Add(b);
            return(b);
        }
Esempio n. 6
0
        public override void CharacterData(CMLStack xpath, XElement element)
        {
            string s = element.Value.Trim();

            if (xpath.ToString().EndsWith("string/", StringComparison.Ordinal) && Builtin.Equals("stereo", StringComparison.Ordinal))
            {
                StereoGiven = true;
                switch (s.Trim())
                {
                case "W":
                    Debug.WriteLine("CML W stereo found");
                    BondStereo.Add("1");
                    break;

                case "H":
                    Debug.WriteLine("CML H stereo found");
                    BondStereo.Add("6");
                    break;
                }
            }
            else
            {
                base.CharacterData(xpath, element);
            }
        }
Esempio n. 7
0
        private static BondStereo BondStereoFromMolfile(int molfileBondStereo)
        {
            //Translates from a molfile convention bond stereochemistry number to the enumeration used in the model
            //The opposite of BondStereoFromModel
            BondStereo modelStereo = 0;

            //MOLFILE: 0 is NOT stereo, 1 is UP,    6 is DOWN,  4 is EITHER
            //MODEL  : 0 is None,       1 is Wedge, 2 is Hatch, 3 is Indeterminate
            switch (molfileBondStereo)
            {
            case 0:
                modelStereo = BondStereo.None;
                break;

            case 1:
                modelStereo = BondStereo.Wedge;
                break;

            case 4:
                modelStereo = BondStereo.Indeterminate;
                break;

            case 6:
                modelStereo = BondStereo.Hatch;
                break;

            default:
                modelStereo = BondStereo.None;
                break;
            }
            return(modelStereo);
        }
Esempio n. 8
0
 /// <summary>
 /// Constructs a query bond with a given order and stereo orientation from an array of atoms.
 /// </summary>
 /// <param name="atom1">the first Atom in the query bond</param>
 /// <param name="atom2">the second Atom in the query bond</param>
 /// <param name="order">the query bond order</param>
 /// <param name="stereo">a descriptor the stereochemical orientation of this query bond</param>
 public QueryBond(IAtom atom1, IAtom atom2, BondOrder order, BondStereo stereo, IChemObjectBuilder builder)
 {
     this.builder = builder;
     SetAtoms(new[] { atom1, atom2 });
     this.order  = order;
     this.stereo = stereo;
 }
Esempio n. 9
0
File: Bond.tt.cs Progetto: qize/NCDK
 public Bond(IEnumerable <IAtom> atoms, BondOrder order, BondStereo stereo)
     : base()
 {
     InitAtoms(atoms);
     this.order = order;
     UpdateElectronCount(order);
     this.stereo = stereo;
 }
 public Bond(Atom parent, Atom connectedAtom, BondType type, BondStereo stereo, BondTopology topology, BondReactingCenterStatus rcStatus)
 {
     ParentAtom     = parent;
     ConnectedAtom  = connectedAtom;
     BondType       = type;
     DrawType       = type;
     Stereo         = stereo;
     Topology       = topology;
     ReactingCenter = rcStatus;
     BondLength     = 0; // parent.CovalentRadius + connectedAtom.CovalentRadius;
 }
Esempio n. 11
0
 public static void MakeUpDownBonds(IAtomContainer container)
 {
     for (int i = 0; i < container.Atoms.Count; i++)
     {
         var a = container.Atoms[i];
         var connectedAtoms = container.GetConnectedAtoms(a).ToReadOnlyList();
         if (connectedAtoms.Count == 4)
         {
             int   up   = 0;
             int   down = 0;
             int   hs   = 0;
             IAtom h    = null;
             for (int k = 0; k < 4; k++)
             {
                 IAtom      conAtom = connectedAtoms[k];
                 BondStereo stereo  = container.GetBond(a, conAtom).Stereo;
                 if (stereo == BondStereo.Up)
                 {
                     up++;
                 }
                 else if (stereo == BondStereo.Down)
                 {
                     down++;
                 }
                 else if (stereo == BondStereo.None && conAtom.AtomicNumber.Equals(AtomicNumbers.H))
                 {
                     h = conAtom;
                     hs++;
                 }
                 else
                 {
                     h = null;
                 }
             }
             if (up == 0 && down == 1 && h != null && hs == 1)
             {
                 container.GetBond(a, h).Stereo = BondStereo.Up;
             }
             if (up == 1 && down == 0 && h != null && hs == 1)
             {
                 container.GetBond(a, h).Stereo = BondStereo.Down;
             }
         }
     }
 }
        /// <summary>
        /// Access the elevation of a bond.
        /// </summary>
        /// <param name="bond">the bond</param>
        /// <returns>+1 above the plane, 0 in the plane (default) or -1 below the plane</returns>
        internal static int Elevation(IBond bond)
        {
            BondStereo stereo = bond.Stereo;

            switch (stereo)
            {
            case BondStereo.None:
                return(0);

            case BondStereo.Up:
            case BondStereo.DownInverted:
                return(+1);

            case BondStereo.Down:
            case BondStereo.UpInverted:
                return(-1);

            default:
                return(0);
            }
        }
Esempio n. 13
0
        public void TestBondStereo()
        {
            var  mol   = new AtomContainer();
            Atom atom  = new Atom("C");
            Atom atom2 = new Atom("O");

            mol.Atoms.Add(atom);
            mol.Atoms.Add(atom2);
            Bond       bond   = new Bond(atom, atom2, BondOrder.Single);
            BondStereo stereo = BondStereo.Down;

            bond.Stereo = stereo;
            mol.Bonds.Add(bond);

            IAtomContainer roundTrippedMol = CMLRoundTripTool.RoundTripMolecule(convertor, mol);

            Assert.AreEqual(2, roundTrippedMol.Atoms.Count);
            Assert.AreEqual(1, roundTrippedMol.Bonds.Count);
            IBond roundTrippedBond = roundTrippedMol.Bonds[0];

            Assert.AreEqual(bond.Stereo, roundTrippedBond.Stereo);
        }
Esempio n. 14
0
        private static int MdlBondStereo(BondStereo code)
        {
            int stereo = 0;

            if (code == BondStereo.None)
            {
                stereo = 0;
            }
            else if (code == BondStereo.Wedge)
            {
                stereo = 1;
            }
            else if (code == BondStereo.Hatch)
            {
                stereo = 6;
            }
            else
            {
                stereo = 0;
            }
            return(stereo);
        }
Esempio n. 15
0
        public static BondStereo StereoFromString(string stereo)
        {
            BondStereo result = BondStereo.None;

            switch (stereo)
            {
            case "N":
                result = BondStereo.None;
                break;

            case "W":
                result = BondStereo.Wedge;
                break;

            case "H":
                result = BondStereo.Hatch;
                break;

            case "S":
                result = BondStereo.Indeterminate;
                break;

            case "C":
                result = BondStereo.Cis;
                break;

            case "T":
                result = BondStereo.Trans;
                break;

            default:
                result = BondStereo.None;
                break;
            }

            return(result);
        }
Esempio n. 16
0
 public static IBond NewBond(IEnumerable <IAtom> atoms, BondOrder order, BondStereo stereo) => (IBond)CDK.Builder.NewBond(atoms, order, stereo);
Esempio n. 17
0
 public static IBond NewBond(IAtom atom1, IAtom atom2, BondOrder order, BondStereo stereo) => (IBond)CDK.Builder.NewBond(atom1, atom2, order, stereo);
Esempio n. 18
0
 public IBond NewBond(IEnumerable <IAtom> atoms, BondOrder order, BondStereo stereo) => (IBond) new Bond(atoms, order, stereo);
Esempio n. 19
0
 public IBond NewBond(IAtom atom1, IAtom atom2, BondOrder order, BondStereo stereo) => (IBond) new Bond(atom1, atom2, order, stereo);
Esempio n. 20
0
File: Bond.tt.cs Progetto: qize/NCDK
 /// <summary>
 /// Constructs a bond with a single bond order.
 /// </summary>
 /// <param name="atom1">the first Atom in the bond</param>
 /// <param name="atom2">the second Atom in the bond</param>
 /// <param name="order">the bond order</param>
 /// <param name="stereo">a descriptor the stereochemical orientation of this bond</param>
 public Bond(IAtom atom1, IAtom atom2, BondOrder order, BondStereo stereo)
     : this(new IAtom[] { atom1, atom2, }, order, stereo)
 {
 }
Esempio n. 21
0
        /// <summary>
        ///  Read a Molecule from a file in MDL sd format
        /// </summary>
        /// <returns>The Molecule that was read from the MDL file.</returns>
        private IAtomContainer ReadMolecule(IAtomContainer molecule)
        {
            Debug.WriteLine("Reading new molecule");
            int        linecount     = 0;
            int        atoms         = 0;
            int        bonds         = 0;
            int        atom1         = 0;
            int        atom2         = 0;
            int        order         = 0;
            BondStereo stereo        = BondStereo.None;
            int        RGroupCounter = 1;
            int        Rnumber       = 0;
            double     x             = 0.0;
            double     y             = 0.0;
            double     z             = 0.0;
            double     totalX        = 0.0;
            double     totalY        = 0.0;
            double     totalZ        = 0.0;
            //int[][] conMat = Array.Empty<int>()[0];
            //string help;
            IAtom  atom;
            string line = "";

            try
            {
                var isotopeFactory = CDK.IsotopeFactory;
                Trace.TraceInformation("Reading header");
                line = input.ReadLine();
                linecount++;
                if (line == null)
                {
                    return(null);
                }
                Debug.WriteLine("Line " + linecount + ": " + line);

                if (line.StartsWith("$$$$", StringComparison.Ordinal))
                {
                    Debug.WriteLine("File is empty, returning empty molecule");
                    return(molecule);
                }
                if (line.Length > 0)
                {
                    molecule.Title = line;
                }
                line = input.ReadLine();
                linecount++;
                Debug.WriteLine("Line " + linecount + ": " + line);
                line = input.ReadLine();
                linecount++;
                Debug.WriteLine("Line " + linecount + ": " + line);
                if (line.Length > 0)
                {
                    molecule.SetProperty(CDKPropertyName.Remark, line);
                }

                Trace.TraceInformation("Reading rest of file");
                line = input.ReadLine();
                linecount++;
                Debug.WriteLine("Line " + linecount + ": " + line);
                if (ReaderMode == ChemObjectReaderMode.Strict)
                {
                    if (line.Contains("V2000") || line.Contains("v2000"))
                    {
                        throw new CDKException("This file must be read with the MDLV2000Reader.");
                    }
                    if (line.Contains("V3000") || line.Contains("v3000"))
                    {
                        throw new CDKException("This file must be read with the MDLV3000Reader.");
                    }
                }
                atoms = int.Parse(Strings.Substring(line, 0, 3).Trim(), NumberFormatInfo.InvariantInfo);
                Debug.WriteLine($"Atomcount: {atoms}");
                bonds = int.Parse(Strings.Substring(line, 3, 3).Trim(), NumberFormatInfo.InvariantInfo);
                Debug.WriteLine($"Bondcount: {bonds}");

                // read ATOM block
                Trace.TraceInformation("Reading atom block");
                for (int f = 0; f < atoms; f++)
                {
                    line = input.ReadLine();
                    linecount++;
                    var trailingSpaceMatcher = TRAILING_SPACE.Match(line);
                    if (trailingSpaceMatcher.Success)
                    {
                        HandleError("Trailing space found", linecount, trailingSpaceMatcher.Index, trailingSpaceMatcher.Index + trailingSpaceMatcher.Length);
                        line = Strings.Substring(line, 0, trailingSpaceMatcher.Index);
                    }
                    x = double.Parse(Strings.Substring(line, 0, 10).Trim(), NumberFormatInfo.InvariantInfo);
                    y = double.Parse(Strings.Substring(line, 10, 10).Trim(), NumberFormatInfo.InvariantInfo);
                    z = double.Parse(Strings.Substring(line, 20, 10).Trim(), NumberFormatInfo.InvariantInfo);
                    // *all* values should be zero, not just the sum
                    totalX += Math.Abs(x);
                    totalY += Math.Abs(y);
                    totalZ += Math.Abs(z);
                    Debug.WriteLine("Coordinates: " + x + "; " + y + "; " + z);
                    string element = Strings.Substring(line, 31, 3).Trim();
                    if (line.Length < 34)
                    {
                        HandleError("Element atom type does not follow V2000 format type should of length three"
                                    + " and padded with space if required", linecount, 31, 34);
                    }

                    Debug.WriteLine($"Atom type: {element}");
                    if (isotopeFactory.IsElement(element))
                    {
                        atom = isotopeFactory.Configure(molecule.Builder.NewAtom(element));
                    }
                    else if (string.Equals("A", element, StringComparison.Ordinal))
                    {
                        atom = molecule.Builder.NewPseudoAtom(element);
                    }
                    else if (string.Equals("Q", element, StringComparison.Ordinal))
                    {
                        atom = molecule.Builder.NewPseudoAtom(element);
                    }
                    else if (string.Equals("*", element, StringComparison.Ordinal))
                    {
                        atom = molecule.Builder.NewPseudoAtom(element);
                    }
                    else if (string.Equals("LP", element, StringComparison.Ordinal))
                    {
                        atom = molecule.Builder.NewPseudoAtom(element);
                    }
                    else if (string.Equals("L", element, StringComparison.Ordinal))
                    {
                        atom = molecule.Builder.NewPseudoAtom(element);
                    }
                    else if (element.Length > 0 && element[0] == 'R')
                    {
                        Debug.WriteLine("Atom ", element, " is not an regular element. Creating a PseudoAtom.");
                        //check if the element is R
                        string rn = element.Substring(1);
                        if (int.TryParse(rn, out Rnumber))
                        {
                            RGroupCounter = Rnumber;
                        }
                        else
                        {
                            Rnumber = RGroupCounter;
                            RGroupCounter++;
                        }
                        element = "R" + Rnumber;
                        atom    = molecule.Builder.NewPseudoAtom(element);
                    }
                    else
                    {
                        if (ReaderMode == ChemObjectReaderMode.Strict)
                        {
                            throw new CDKException(
                                      "Invalid element type. Must be an existing element, or one in: A, Q, L, LP, *.");
                        }
                        atom = molecule.Builder.NewPseudoAtom(element);
                    }

                    // store as 3D for now, convert to 2D (if totalZ == 0.0) later
                    atom.Point3D = new Vector3(x, y, z);

                    // parse further fields
                    if (line.Length >= 36)
                    {
                        string massDiffString = Strings.Substring(line, 34, 2).Trim();
                        Debug.WriteLine($"Mass difference: {massDiffString}");
                        if (!(atom is IPseudoAtom))
                        {
                            try
                            {
                                int massDiff = int.Parse(massDiffString, NumberFormatInfo.InvariantInfo);
                                if (massDiff != 0)
                                {
                                    var major = CDK.IsotopeFactory.GetMajorIsotope(element);
                                    atom.AtomicNumber = major.AtomicNumber + massDiff;
                                }
                            }
                            catch (Exception exception)
                            {
                                if (!(exception is FormatException || exception is IOException))
                                {
                                    throw;
                                }
                                Trace.TraceError("Could not parse mass difference field");
                            }
                        }
                        else
                        {
                            Trace.TraceError("Cannot set mass difference for a non-element!");
                        }
                    }
                    else
                    {
                        HandleError("Mass difference is missing", linecount, 34, 36);
                    }

                    if (line.Length >= 39)
                    {
                        string chargeCodeString = Strings.Substring(line, 36, 3).Trim();
                        Debug.WriteLine($"Atom charge code: {chargeCodeString}");
                        int chargeCode = int.Parse(chargeCodeString, NumberFormatInfo.InvariantInfo);
                        if (chargeCode == 0)
                        {
                            // uncharged species
                        }
                        else if (chargeCode == 1)
                        {
                            atom.FormalCharge = +3;
                        }
                        else if (chargeCode == 2)
                        {
                            atom.FormalCharge = +2;
                        }
                        else if (chargeCode == 3)
                        {
                            atom.FormalCharge = +1;
                        }
                        else if (chargeCode == 4)
                        {
                        }
                        else if (chargeCode == 5)
                        {
                            atom.FormalCharge = -1;
                        }
                        else if (chargeCode == 6)
                        {
                            atom.FormalCharge = -2;
                        }
                        else if (chargeCode == 7)
                        {
                            atom.FormalCharge = -3;
                        }
                    }
                    else
                    {
                        HandleError("Atom charge count is empty", linecount, 35, 39);
                    }

                    if (line.Length >= 64)
                    {
                        // read the mmm field as position 61-63
                        string reactionAtomIDString = Strings.Substring(line, 60, 3).Trim();
                        Debug.WriteLine($"Parsing mapping id: {reactionAtomIDString}");
                        try
                        {
                            int reactionAtomID = int.Parse(reactionAtomIDString, NumberFormatInfo.InvariantInfo);
                            if (reactionAtomID != 0)
                            {
                                atom.SetProperty(CDKPropertyName.AtomAtomMapping, reactionAtomID);
                            }
                        }
                        catch (Exception exception)
                        {
                            Trace.TraceError("Mapping number ", reactionAtomIDString, " is not an integer.");
                            Debug.WriteLine(exception);
                        }
                    }

                    //shk3: This reads shifts from after the molecule. I don't think this is an official format, but I saw it frequently 80=>78 for alk
                    if (line.Length >= 78)
                    {
                        double shift = double.Parse(Strings.Substring(line, 69, 11).Trim(), NumberFormatInfo.InvariantInfo);
                        atom.SetProperty("first shift", shift);
                    }
                    if (line.Length >= 87)
                    {
                        double shift = double.Parse(Strings.Substring(line, 79, 8).Trim(), NumberFormatInfo.InvariantInfo);
                        atom.SetProperty("second shift", shift);
                    }

                    molecule.Atoms.Add(atom);
                }

                // convert to 2D, if totalZ == 0
                if (totalX == 0.0 && totalY == 0.0 && totalZ == 0.0)
                {
                    Trace.TraceInformation("All coordinates are 0.0");
                    foreach (var atomToUpdate in molecule.Atoms)
                    {
                        atomToUpdate.Point3D = null;
                    }
                }
                else if (totalZ == 0.0 && !forceReadAs3DCoords.IsSet)
                {
                    Trace.TraceInformation("Total 3D Z is 0.0, interpreting it as a 2D structure");
                    IEnumerator <IAtom> atomsToUpdate = molecule.Atoms.GetEnumerator();
                    while (atomsToUpdate.MoveNext())
                    {
                        IAtom   atomToUpdate = (IAtom)atomsToUpdate.Current;
                        Vector3?p3d          = atomToUpdate.Point3D;
                        atomToUpdate.Point2D = new Vector2(p3d.Value.X, p3d.Value.Y);
                        atomToUpdate.Point3D = null;
                    }
                }

                // read BOND block
                Trace.TraceInformation("Reading bond block");
                for (int f = 0; f < bonds; f++)
                {
                    line = input.ReadLine();
                    linecount++;
                    atom1 = int.Parse(Strings.Substring(line, 0, 3).Trim(), NumberFormatInfo.InvariantInfo);
                    atom2 = int.Parse(Strings.Substring(line, 3, 3).Trim(), NumberFormatInfo.InvariantInfo);
                    order = int.Parse(Strings.Substring(line, 6, 3).Trim(), NumberFormatInfo.InvariantInfo);
                    if (line.Length > 12)
                    {
                        int mdlStereo = int.Parse(Strings.Substring(line, 9, 3).Trim(), NumberFormatInfo.InvariantInfo);
                        if (mdlStereo == 1)
                        {
                            // MDL up bond
                            stereo = BondStereo.Up;
                        }
                        else if (mdlStereo == 6)
                        {
                            // MDL down bond
                            stereo = BondStereo.Down;
                        }
                        else if (mdlStereo == 0)
                        {
                            // bond has no stereochemistry
                            stereo = BondStereo.None;
                        }
                        else if (mdlStereo == 4)
                        {
                            //MDL up or down bond
                            stereo = BondStereo.UpOrDown;
                        }
                        else if (mdlStereo == 3)
                        {
                            //MDL e or z undefined
                            stereo = BondStereo.EOrZ;
                        }
                    }
                    else
                    {
                        Trace.TraceWarning("Missing expected stereo field at line: " + line);
                    }
                    Debug.WriteLine("Bond: " + atom1 + " - " + atom2 + "; order " + order);
                    // interpret CTfile's special bond orders
                    IAtom a1      = molecule.Atoms[atom1 - 1];
                    IAtom a2      = molecule.Atoms[atom2 - 1];
                    IBond newBond = null;
                    if (order >= 1 && order <= 3)
                    {
                        BondOrder cdkOrder = BondOrder.Single;
                        if (order == 2)
                        {
                            cdkOrder = BondOrder.Double;
                        }
                        if (order == 3)
                        {
                            cdkOrder = BondOrder.Triple;
                        }
                        if (stereo != BondStereo.None)
                        {
                            newBond = molecule.Builder.NewBond(a1, a2, cdkOrder, stereo);
                        }
                        else
                        {
                            newBond = molecule.Builder.NewBond(a1, a2, cdkOrder);
                        }
                    }
                    else if (order == 4)
                    {
                        // aromatic bond
                        if (stereo != BondStereo.None)
                        {
                            newBond = molecule.Builder.NewBond(a1, a2, BondOrder.Single, stereo);
                        }
                        else
                        {
                            newBond = molecule.Builder.NewBond(a1, a2, BondOrder.Single);
                        }
                        // mark both atoms and the bond as aromatic
                        newBond.IsAromatic = true;
                        a1.IsAromatic      = true;
                        a2.IsAromatic      = true;
                    }
                    molecule.Bonds.Add(newBond);
                }
            }
            catch (Exception exception)
            {
                if (!(exception is IOException
                      | exception is CDKException
                      | exception is ArgumentException))
                {
                    throw;
                }
                string error = "Error while parsing line " + linecount + ": " + line + " -> " + exception.Message;
                Trace.TraceError(error);
                Debug.WriteLine(exception);
                throw new CDKException(error, exception);
            }
            return(molecule);
        }
Esempio n. 22
0
        /// <summary>
        /// Adds a bond to this container.
        /// </summary>
        /// <param name="atom1">the first atom</param>
        /// <param name="atom2">the second atom</param>
        /// <param name="order">bond order</param>
        /// <param name="stereo">Stereochemical orientation</param>
        public static void AddBond(this IAtomContainer mol, IAtom atom1, IAtom atom2, BondOrder order, BondStereo stereo)
        {
            if (!(mol.Contains(atom1) && mol.Contains(atom2)))
            {
                throw new InvalidOperationException();
            }
            var bond = mol.Builder.NewBond(atom1, atom2, order, stereo);

            mol.Bonds.Add(bond);
        }
        //static Molecule ReadMoleFile(string filename)
        //{
        //    using (var reader = new System.IO.StreamReader(filename))
        //    {
        //        string s = reader.ReadToEnd();
        //        if (s.Contains("V2000")) return MoleFileReader.ParseMoleFile2(s);
        //        if (s.Contains("V3000")) throw new Exception("Version 3000 Mol file is currently not supported.");
        //        throw new Exception("Mol file type not recognized. It is does not contain a version number.");
        //    }
        //}

        static Molecule ParseMoleFile2(string moleFile)
        {
            Molecule molecule = new Molecule();
            //atoms.Clear();
            //cycles.Clear();
            //fusedRings.Clear();

            int numAtoms = 0;
            int numBonds = 0;

            // This information is contained in the header (first 3 lines) of the mol file. It is currently not being used, but code has been created for
            // future use.
            string name    = string.Empty;
            string program = string.Empty;
            string user    = string.Empty;
            //// used to test Line 2 reading below.
            //string MM = string.Empty;
            //string DD = string.Empty;
            //string YY = string.Empty;
            //string HH = string.Empty;
            //string mm = string.Empty;
            int    MM = 1;
            int    DD = 1;
            int    YY = 0;
            int    HH = 0;
            int    mm = 0;
            string dimensionalCodes = string.Empty;
            //// used to test Line 2 reading below.
            //string scalingFactor1 = string.Empty;
            int scalingFactor1 = 0;
            //// used to test Line 2 reading below.
            //string scalingFactor2 = string.Empty;
            double scalingFactor2 = 0;
            // used to test Line 2 reading below.
            string energy         = string.Empty;
            string registryNumber = string.Empty;
            string comments       = string.Empty;

            string[] lines = moleFile.Split('\n');
            // Line 1 contains the compound name. It can not be longer than 80 characters, and is allowed to be empty.
            // The length of the line is not relevant in how this is read, so it is not checked.
            name = lines[0];
            //// used to test Line 2 reading below.
            //lines[1] = "IIPPPPPPPPMMDDYYHHmmddSSssssssssssEEEEEEEEEEEERRRRRR";
            // Line 2 is optional. Skip this if it is not there.
            if (lines[1] != string.Empty)
            {
                // Line format: IIPPPPPPPPMMDDYYHHmmddSSssssssssssEEEEEEEEEEEERRRRRR
                //              A2<--A8--><---A10-->A2I2<--F10.5-><---F12.5--><-I6->
                //User's first and last initials (l), program name (P), date/time (M/D/Y,H:m),
                //dimensional codes (d), scaling factors (S, s), energy (E) if modeling program input,
                //internal registry number (R) if input through MDL form.
                if (lines[1].Length > 2)
                {
                    user = lines[1].Substring(0, 2);                      // II
                }
                if (lines[1].Length > 10)
                {
                    program = lines[1].Substring(2, 8);                       // PPPPPPPP
                }
                if (lines[1].Length > 20)
                {
                    //// used to test Line 2 reading below.
                    //MM = lines[1].Substring(10, 2); // MMDDYYHHmm
                    //DD = lines[1].Substring(12, 2); // MMDDYYHHmm
                    //YY = lines[1].Substring(14, 2); // MMDDYYHHmm
                    //HH = lines[1].Substring(16, 2); // MMDDYYHHmm
                    //mm = lines[1].Substring(18, 2); // MMDDYYHHmm
                    MM = Convert.ToInt32(lines[1].Substring(10, 2)); // MMDDYYHHmm
                    DD = Convert.ToInt32(lines[1].Substring(12, 2)); // MMDDYYHHmm
                    YY = Convert.ToInt32(lines[1].Substring(14, 2)); // MMDDYYHHmm
                    HH = Convert.ToInt32(lines[1].Substring(16, 2)); // MMDDYYHHmm
                    mm = Convert.ToInt32(lines[1].Substring(18, 2)); // MMDDYYHHmm
                }
                if (lines[1].Length > 22)
                {
                    dimensionalCodes = lines[1].Substring(20, 2);                       // dd
                }
                //// used to test Line 2 reading below.
                // if (lines[1].Length > 24) scalingFactor1 = lines[1].Substring(22, 2); //SS
                if (lines[1].Length > 24)
                {
                    scalingFactor1 = Convert.ToInt32(lines[1].Substring(22, 2));                       //SS
                }
                //// used to test Line 2 reading below.
                // if (lines[1].Length > 34) scalingFactor2 = lines[1].Substring(24, 10); //ss
                if (lines[1].Length > 34)
                {
                    scalingFactor2 = Convert.ToDouble(lines[1].Substring(24, 10));                       //ss
                }
                if (lines[1].Length > 46)
                {
                    energy = lines[1].Substring(34, 12);                       //EEEEEEEEEEEE
                }
                if (lines[1].Length == 52)
                {
                    registryNumber = lines[1].Substring(46, 6);                        //RRRRRR
                }
            }
            comments = lines[2];

            // Counts Line
            // aaabbblllfffcccsssxxxrrrpppiiimmmvvvvvv
            numAtoms = Convert.ToInt32(lines[3].Substring(0, 3));
            numBonds = Convert.ToInt32(lines[3].Substring(3, 3));
            int atomLists = Convert.ToInt32(lines[3].Substring(6, 3));
            //int fObsolete = Convert.ToInt32(lines[3].Substring(9, 3));
            bool chiral = false;

            if (Convert.ToInt32(lines[3].Substring(12, 3)) == 1)
            {
                chiral = true;
            }
            int sText = Convert.ToInt32(lines[3].Substring(15, 3));
            //int xObsolete = Convert.ToInt32(lines[3].Substring(18, 3));
            //int rObsolete = Convert.ToInt32(lines[3].Substring(21, 3));
            //int pObsolete = Convert.ToInt32(lines[3].Substring(24, 3));
            //int iObsolete = Convert.ToInt32(lines[3].Substring(27, 3));
            int    properties = Convert.ToInt32(lines[3].Substring(30, 3));
            string version    = lines[3].Substring(33, 6);

            for (int i = 0; i < numAtoms; i++)
            {
                Atom a = new ChemInfo.Atom(lines[4 + i].Substring(31, 3).Trim());
                molecule.AddAtom(a);
                // xxxxx.xxxxyyyyy.yyyyzzzzz.zzzz aaaddcccssshhhbbbvvvHHHrrriiimmmnnneee
                //a.x = Convert.ToDouble(lines[4 + i].Substring(0, 10));
                //a.y = Convert.ToDouble(lines[4 + i].Substring(10, 10));
                //a.z = Convert.ToDouble(lines[4 + i].Substring(20, 10));
                string text = lines[4 + i].Substring(34, 2);
                a.MassDiff      = Convert.ToInt32(lines[4 + i].Substring(34, 2));
                a.Charge        = Convert.ToInt32(lines[4 + i].Substring(36, 3));
                a.StereoParity  = Convert.ToInt32(lines[4 + i].Substring(39, 3));
                a.HydrogenCount = Convert.ToInt32(lines[4 + i].Substring(42, 3));
                a.StereoCareBox = Convert.ToInt32(lines[4 + i].Substring(45, 3));
                //a.Valence = Convert.ToInt32(lines[4 + i].Substring(48, 3));
                // string H0 = lines[4 + i].Substring(51, 3);
                // a.HO = Convert.ToInt32(lines[4 + i].Substring(51, 3));
                a.RNotUsed           = lines[4 + i].Substring(54, 3);
                a.INotUsed           = lines[4 + i].Substring(57, 3);
                a.AtomMapping        = Convert.ToInt32(lines[4 + i].Substring(60, 3));
                a.InversionRetension = Convert.ToInt32(lines[4 + i].Substring(63, 3));
                a.ExactChange        = Convert.ToInt32(lines[4 + i].Substring(66, 3));
            }
            for (int i = 0; i < numBonds; i++)
            {
                //Bond b = new Bond();
                // 111222tttsssxxxrrrccc
                string                   line           = lines[4 + numAtoms + i];
                int                      firstAtom      = Convert.ToInt32(lines[4 + numAtoms + i].Substring(0, 3));
                int                      secondAtom     = Convert.ToInt32(lines[4 + numAtoms + i].Substring(3, 3));
                BondType                 bondType       = (BondType)Convert.ToInt32(lines[4 + numAtoms + i].Substring(6, 3));
                BondStereo               bondStereo     = (BondStereo)Convert.ToInt32(lines[4 + numAtoms + i].Substring(9, 3));
                string                   xNotUsed       = lines[4 + numAtoms + i].Substring(12, 3);
                BondTopology             bondTopology   = (BondTopology)Convert.ToInt32(lines[4 + numAtoms + i].Substring(15, 3));
                int                      rc             = Convert.ToInt32(lines[4 + numAtoms + i].Substring(18, 3));
                BondReactingCenterStatus reactingCenter = BondReactingCenterStatus.Unmarked;
                if (rc == 13)
                {
                    reactingCenter = BondReactingCenterStatus.bondMadeOrBroken | BondReactingCenterStatus.bondOrderChanges | BondReactingCenterStatus.aCenter;
                }
                else if (rc == 12)
                {
                    reactingCenter = BondReactingCenterStatus.bondMadeOrBroken | BondReactingCenterStatus.bondOrderChanges;
                }
                else if (rc == 9)
                {
                    reactingCenter = BondReactingCenterStatus.bondOrderChanges | BondReactingCenterStatus.aCenter;
                }
                else if (rc == 5)
                {
                    reactingCenter = BondReactingCenterStatus.bondMadeOrBroken | BondReactingCenterStatus.aCenter;
                }
                else
                {
                    reactingCenter = (BondReactingCenterStatus)rc;
                }
                molecule.AddBond(molecule.Atoms[firstAtom - 1], molecule.Atoms[secondAtom - 1], bondType, bondStereo, bondTopology, reactingCenter);
            }
            molecule.FindRings();
            return(molecule);
        }
Esempio n. 24
0
 /// <summary>
 /// Constructs a query bond with a given order and stereo orientation from an array of atoms.
 /// </summary>
 /// <param name="atom1">the first Atom in the query bond</param>
 /// <param name="atom2">the second Atom in the query bond</param>
 /// <param name="order">the query bond order</param>
 /// <param name="stereo">a descriptor the stereochemical orientation of this query bond</param>
 public QueryBond(IAtom atom1, IAtom atom2, BondOrder order, BondStereo stereo)
 {
     SetAtoms(new[] { atom1, atom2 });
     this.order  = order;
     this.stereo = stereo;
 }