void ImportMolFile(string filename) { atomTable.Clear(); bondTable.Clear(); molecule = new Molecule(); 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; using (var reader = new System.IO.StreamReader(filename)) { string s = reader.ReadToEnd(); string[] lines = s.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); molecule = new Molecule(); for (int i = 0; i < numAtoms; i++) { Atom a = molecule.AddAtom(lines[4 + i].Substring(31, 3).Replace(" ", string.Empty)); // 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)); //DataRow atomRow = atomTable.NewRow(); //atomTable.Rows.Add(atomRow); //atomRow["X"] = a.x; //atomRow["Y"] = a.y; //atomRow["Z"] = a.z; //atomRow["element"] = a.Element.ToString(); //atomRow["MassDiff"] = a.massDiff; //atomRow["Charge"] = a.charge; //atomRow["StereoParity"] = a.stereoParity; //atomRow["HydrogenCount"] = a.hydrogenCount; //atomRow["StereoBoxCare"] = a.stereoCareBox; //atomRow["Valence"] = a.valence; ////atomRow["H0"] = a.HO; //atomRow["rNotUsed"] = a.rNotUsed; //atomRow["iNotUsed"] = a.iNotUsed; //atomRow["AtomMapping"] = a.atomMapping; //atomRow["InversionRetention"] = a.inversionRetension; //atomRow["ExactChange"] = a.exactChange; } for (int i = 0; i < numBonds; i++) { Bond b = new Bond(); // 111222tttsssxxxrrrccc string line = lines[4 + numAtoms + i]; b.firstAtom = Convert.ToInt32(lines[4 + numAtoms + i].Substring(0, 3)); b.secondAtom = Convert.ToInt32(lines[4 + numAtoms + i].Substring(3, 3)); b.bondType = (BondType)Convert.ToInt32(lines[4 + numAtoms + i].Substring(6, 3)); b.bondStereo = (BondStereo)Convert.ToInt32(lines[4 + numAtoms + i].Substring(9, 3)); b.xNotUsed = lines[4 + numAtoms + i].Substring(12, 3); b.bondTopology = (BondTopology)Convert.ToInt32(lines[4 + numAtoms + i].Substring(15, 3)); int reactingCenter = Convert.ToInt32(lines[4 + numAtoms + i].Substring(18, 3)); if (reactingCenter == 13) { b.reactingCenter = BondReactingCenterStatus.bondMadeOrBroken | BondReactingCenterStatus.bondOrderChanges | BondReactingCenterStatus.aCenter; } else if (reactingCenter == 12) { b.reactingCenter = BondReactingCenterStatus.bondMadeOrBroken | BondReactingCenterStatus.bondOrderChanges; } else if (reactingCenter == 9) { b.reactingCenter = BondReactingCenterStatus.bondOrderChanges | BondReactingCenterStatus.aCenter; } else if (reactingCenter == 5) { b.reactingCenter = BondReactingCenterStatus.bondMadeOrBroken | BondReactingCenterStatus.aCenter; } else { b.reactingCenter = (BondReactingCenterStatus)reactingCenter; } DataRow bondRow = bondTable.NewRow(); bondRow["firstAtom"] = b.firstAtom; bondRow["secondAtom"] = b.secondAtom; bondRow["bondType"] = b.bondType; bondRow["bondStereo"] = b.bondStereo; bondRow["xNotUsed"] = b.xNotUsed; bondRow["bondTopology"] = b.bondTopology; bondRow["reactingCenter"] = b.reactingCenter; molecule.AddBond(b.firstAtom - 1, b.secondAtom - 1); } } }