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); }
/// <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); }
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); } }
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))); }
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); }
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); } }
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); }
/// <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; }
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; }
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); } }
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); }
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); }
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); }
public static IBond NewBond(IEnumerable <IAtom> atoms, BondOrder order, BondStereo stereo) => (IBond)CDK.Builder.NewBond(atoms, order, stereo);
public static IBond NewBond(IAtom atom1, IAtom atom2, BondOrder order, BondStereo stereo) => (IBond)CDK.Builder.NewBond(atom1, atom2, order, stereo);
public IBond NewBond(IEnumerable <IAtom> atoms, BondOrder order, BondStereo stereo) => (IBond) new Bond(atoms, order, stereo);
public IBond NewBond(IAtom atom1, IAtom atom2, BondOrder order, BondStereo stereo) => (IBond) new Bond(atom1, atom2, order, stereo);
/// <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) { }
/// <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); }
/// <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); }
/// <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; }