public void SetUp() { molecule1 = builder.NewAtomContainer(); atomInMol1 = builder.NewAtom("Cl"); molecule1.Atoms.Add(atomInMol1); molecule1.Atoms.Add(builder.NewAtom("Cl")); bondInMol1 = builder.NewBond(atomInMol1, molecule1.Atoms[1]); molecule1.Bonds.Add(bondInMol1); molecule2 = builder.NewAtomContainer(); atomInMol2 = builder.NewAtom("O"); atomInMol2.ImplicitHydrogenCount = 2; molecule2.Atoms.Add(atomInMol2); moleculeSet = builder.NewChemObjectSet <IAtomContainer>(); moleculeSet.Add(molecule1); moleculeSet.Add(molecule2); reaction = builder.NewReaction(); reaction.Reactants.Add(molecule1); reaction.Products.Add(molecule2); reactionSet = builder.NewReactionSet(); reactionSet.Add(reaction); chemModel = builder.NewChemModel(); chemModel.MoleculeSet = moleculeSet; chemModel.ReactionSet = reactionSet; chemSequence1 = builder.NewChemSequence(); chemSequence1.Add(chemModel); chemSequence2 = builder.NewChemSequence(); chemFile = builder.NewChemFile(); chemFile.Add(chemSequence1); chemFile.Add(chemSequence2); }
public virtual void TestAddChemSequence_IChemSequence() { IChemFile cs = (IChemFile)NewChemObject(); cs.Add(cs.Builder.NewChemSequence()); cs.Add(cs.Builder.NewChemSequence()); cs.Add(cs.Builder.NewChemSequence()); Assert.AreEqual(3, cs.Count); }
public virtual void TestGetChemSequence_int() { IChemFile cs = (IChemFile)NewChemObject(); cs.Add(cs.Builder.NewChemSequence()); IChemSequence second = cs.Builder.NewChemSequence(); cs.Add(second); cs.Add(cs.Builder.NewChemSequence()); Assert.AreEqual(second, cs[1]); }
public virtual void TestRemoveChemSequence_int() { IChemFile cs = (IChemFile)NewChemObject(); cs.Add(cs.Builder.NewChemSequence()); cs.Add(cs.Builder.NewChemSequence()); cs.Add(cs.Builder.NewChemSequence()); Assert.AreEqual(3, cs.Count); cs.RemoveAt(1); Assert.AreEqual(2, cs.Count); }
/// <summary> /// Takes an object which subclasses IChemObject, e.g.Molecule, and will read /// this (from file, database, Internet etc). If the specific implementation /// does not support a specific IChemObject it will throw an Exception. /// </summary> /// <param name="obj">The object that subclasses <see cref="IChemObject"/></param> /// <returns>The <see cref="IChemObject"/> read</returns> /// <exception cref="CDKException"></exception> public override T Read <T>(T obj) { if (obj is IReaction) { return((T)ReadReaction(obj.Builder)); } else if (obj is IReactionSet) { IReactionSet reactionSet = obj.Builder.NewReactionSet(); reactionSet.Add(ReadReaction(obj.Builder)); return((T)reactionSet); } else if (obj is IChemModel) { IChemModel model = obj.Builder.NewChemModel(); IReactionSet reactionSet = obj.Builder.NewReactionSet(); reactionSet.Add(ReadReaction(obj.Builder)); model.ReactionSet = reactionSet; return((T)model); } else if (obj is IChemFile) { IChemFile chemFile = obj.Builder.NewChemFile(); IChemSequence sequence = obj.Builder.NewChemSequence(); sequence.Add((IChemModel)Read(obj.Builder.NewChemModel())); chemFile.Add(sequence); return((T)chemFile); } else { throw new CDKException($"Only supported are Reaction and ChemModel, and not {obj.GetType().Name}."); } }
private IChemFile ReadChemFile(IChemFile file) { IChemSequence seq = ReadChemSequence(file.Builder.NewChemSequence()); file.Add(seq); return(file); }
// private procedures private IChemFile ReadChemFile(IChemFile file) { var chemSequence = file.Builder.NewChemSequence(); var chemModel = file.Builder.NewChemModel(); var moleculeSet = file.Builder.NewAtomContainerSet(); molecule = file.Builder.NewAtomContainer(); atomIDs = new Dictionary <string, IAtom>(); string line = input.ReadLine(); while (line != null) { if (line.IndexOf('{') != -1) { ProcessBlock(line); } else { Trace.TraceWarning("Skipping non-block: " + line); } line = input.ReadLine(); } moleculeSet.Add(molecule); chemModel.MoleculeSet = moleculeSet; chemSequence.Add(chemModel); file.Add(chemSequence); return(file); }
private IChemFile ReadChemFile(IChemFile chemFile) { IChemSequence sequence = ReadChemSequence(chemFile.Builder.NewChemSequence()); chemFile.Add(sequence); return(chemFile); }
// private functions /// <summary> /// Reads a ChemFile object from input. /// </summary> /// <returns>ChemFile with the content read from the input</returns> private IChemFile ReadChemFile(IChemFile cf) { // have to do stuff here try { string line = null; while ((line = input.ReadLine()) != null) { if (line.StartsWith("INChI=", StringComparison.Ordinal) || line.StartsWith("InChI=", StringComparison.Ordinal)) { // ok, the fun starts cf = cf.Builder.NewChemFile(); // ok, we need to parse things like: // INChI=1.12Beta/C6H6/c1-2-4-6-5-3-1/h1-6H string INChI = line.Substring(6); var tok = Strings.Tokenize(INChI, '/'); // ok, we expect 4 tokens // tok[0]; // 1.12Beta not stored since never used string formula = tok[1]; // C6H6 string connections = null; if (tok.Count > 2) { connections = tok[2].Substring(1); // 1-2-4-6-5-3-1 } //final string hydrogens = tokenizer.NextToken().Substring(1); // 1-6H IAtomContainer parsedContent = InChIContentProcessorTool.ProcessFormula( cf.Builder.NewAtomContainer(), formula); if (connections != null) { InChIContentProcessorTool.ProcessConnections(connections, parsedContent, -1); } var moleculeSet = cf.Builder.NewAtomContainerSet(); moleculeSet.Add(cf.Builder.NewAtomContainer(parsedContent)); var model = cf.Builder.NewChemModel(); model.MoleculeSet = moleculeSet; var sequence = cf.Builder.NewChemSequence(); sequence.Add(model); cf.Add(sequence); } } } catch (Exception exception) { if (exception is IOException || exception is ArgumentException) { Console.Error.WriteLine(exception.StackTrace); throw new CDKException($"Error while reading INChI file: {exception.Message}", exception); } else { throw; } } return(cf); }
public override void TestStateChanged_IChemObjectChangeEvent() { ChemObjectListenerImpl listener = new ChemObjectListenerImpl(); IChemFile chemObject = (IChemFile)NewChemObject(); chemObject.Listeners.Add(listener); chemObject.Add(chemObject.Builder.NewChemSequence()); Assert.IsTrue(listener.Changed); }
/// <summary> /// Read a ChemFile from a file in MDL RDF format. /// </summary> /// <param name="chemFile">The IChemFile</param> /// <returns>The IChemFile that was read from the RDF file.</returns> private IChemFile ReadChemFile(IChemFile chemFile) { IChemSequence chemSequence = chemFile.Builder.NewChemSequence(); IChemModel chemModel = chemFile.Builder.NewChemModel(); chemSequence.Add(ReadChemModel(chemModel)); chemFile.Add(chemSequence); return(chemFile); }
/// <summary> /// Read the ShelX from input. Each ShelX document is expected to contain one crystal structure. /// </summary> /// <param name="file"></param> /// <returns>a ChemFile with the coordinates, charges, vectors, etc.</returns> private IChemFile ReadChemFile(IChemFile file) { IChemSequence seq = file.Builder.NewChemSequence(); IChemModel model = file.Builder.NewChemModel(); ICrystal crystal = ReadCrystal(file.Builder.NewCrystal()); model.Crystal = crystal; seq.Add(model); file.Add(seq); return(file); }
public virtual void TestClone_ChemSequence() { IChemFile file = (IChemFile)NewChemObject(); file.Add(file.Builder.NewChemSequence()); // 1 file.Add(file.Builder.NewChemSequence()); // 2 file.Add(file.Builder.NewChemSequence()); // 3 file.Add(file.Builder.NewChemSequence()); // 4 IChemFile clone = (IChemFile)file.Clone(); Assert.AreEqual(file.Count, clone.Count); for (int f = 0; f < file.Count; f++) { for (int g = 0; g < clone.Count; g++) { Assert.IsNotNull(file[f]); Assert.IsNotNull(clone[g]); Assert.AreNotSame(file[f], clone[g]); } } }
public virtual void TestGrowChemSequenceArray() { IChemFile cs = (IChemFile)NewChemObject(); cs.Add(cs.Builder.NewChemSequence()); cs.Add(cs.Builder.NewChemSequence()); cs.Add(cs.Builder.NewChemSequence()); Assert.AreEqual(3, cs.Count); cs.Add(cs.Builder.NewChemSequence()); cs.Add(cs.Builder.NewChemSequence()); cs.Add(cs.Builder.NewChemSequence()); // this one should enfore array grow Assert.AreEqual(6, cs.Count); }
/// <summary> /// Writes a <see cref="IChemObject"/> to the MDL SD file formated output. It can only /// output <see cref="IChemObject"/> of type <see cref="IChemFile"/>, <see cref="IAtomContainerSet"/> /// and <see cref="IAtomContainerSet"/>. /// </summary> /// <param name="obj">an acceptable <see cref="IChemObject"/></param> /// <seealso cref="Accepts(Type)"/> public override void Write(IChemObject obj) { try { if (obj is IEnumerableChemObject <IAtomContainer> ) { WriteMoleculeSet((IEnumerableChemObject <IAtomContainer>)obj); return; } else if (obj is IChemFile) { WriteChemFile((IChemFile)obj); return; } else if (obj is IChemModel) { IChemFile file = obj.Builder.NewChemFile(); IChemSequence sequence = obj.Builder.NewChemSequence(); sequence.Add((IChemModel)obj); file.Add(sequence); WriteChemFile((IChemFile)file); return; } else if (obj is IAtomContainer) { WriteMolecule((IAtomContainer)obj); return; } } catch (Exception ex) { Trace.TraceError(ex.Message); Debug.WriteLine(ex); throw new CDKException("Exception while writing MDL file: " + ex.Message, ex); } throw new CDKException( "Only supported is writing of ChemFile, MoleculeSet, AtomContainer and Molecule objects."); }
/// <summary> /// Reads data from the "file system" file through the use of the "input" /// field, parses data and feeds the ChemFile object with the extracted data. /// </summary> /// <returns>A ChemFile containing the data parsed from input.</returns> /// <exception cref="IOException">may be thrown buy the <c>this.input.ReadLine()</c> instruction.</exception> /// <seealso cref="GamessReader.input"/> //TODO Answer the question : Is this method's name appropriate (given the fact that it do not read a ChemFile object, but return it)? private IChemFile ReadChemFile(IChemFile file) { IChemSequence sequence = file.Builder.NewChemSequence(); // TODO Answer the question : Is this line needed ? IChemModel model = file.Builder.NewChemModel(); // TODO Answer the question : Is this line needed ? var moleculeSet = file.Builder.NewAtomContainerSet(); model.MoleculeSet = moleculeSet; //TODO Answer the question : Should I do this? sequence.Add(model); //TODO Answer the question : Should I do this? file.Add(sequence); //TODO Answer the question : Should I do this? string currentReadLine = this.input.ReadLine(); while (currentReadLine != null) { // There are 2 types of coordinate sets: - bohr coordinates sets (if statement) - angstr???m coordinates sets (else statement) if (currentReadLine.Contains("COORDINATES (BOHR)")) { // The following line do no contain data, so it is ignored. this.input.ReadLine(); moleculeSet.Add(this.ReadCoordinates(file.Builder.NewAtomContainer(), GamessReader.BohrUnit)); //break; //<- stops when the first set of coordinates is found. } else if (currentReadLine.Contains(" COORDINATES OF ALL ATOMS ARE (ANGS)")) { // The following 2 lines do no contain data, so it are ignored. this.input.ReadLine(); this.input.ReadLine(); moleculeSet.Add(this.ReadCoordinates(file.Builder.NewAtomContainer(), GamessReader.AngstromUnit)); //break; //<- stops when the first set of coordinates is found. } currentReadLine = this.input.ReadLine(); } return(file); }
/// <summary> /// Private method that actually parses the input to read a ChemFile /// object. In its current state it is able to read all the molecules /// (if more than one is present) in the specified HIN file. These are /// placed in a MoleculeSet object which in turn is placed in a ChemModel /// which in turn is placed in a ChemSequence object and which is finally /// placed in a ChemFile object and returned to the user. /// </summary> /// <returns>A ChemFile containing the data parsed from input.</returns> private IChemFile ReadChemFile(IChemFile file) { var chemSequence = file.Builder.NewChemSequence(); var chemModel = file.Builder.NewChemModel(); var setOfMolecules = file.Builder.NewAtomContainerSet(); string info; var aroringText = new List <string>(); var mols = new List <IAtomContainer>(); try { string line; // read in header info while (true) { line = input.ReadLine(); if (line.StartsWith("mol", StringComparison.Ordinal)) { info = GetMolName(line); break; } } // start the actual molecule data - may be multiple molecule line = input.ReadLine(); while (true) { if (line == null) { break; // end of file } if (line.StartsWithChar(';')) { continue; // comment line } if (line.StartsWith("mol", StringComparison.Ordinal)) { info = GetMolName(line); line = input.ReadLine(); } var m = file.Builder.NewAtomContainer(); m.Title = info; // Each element of cons is an List of length 3 which stores // the start and end indices and bond order of each bond // found in the HIN file. Before adding bonds we need to reduce // the number of bonds so as not to count the same bond twice List <List <Object> > cons = new List <List <Object> >(); // read data for current molecule int atomSerial = 0; while (true) { if (line == null || line.Contains("endmol")) { break; } if (line.StartsWithChar(';')) { continue; // comment line } var toks = line.Split(' '); var sym = toks[3]; var charge = double.Parse(toks[6], NumberFormatInfo.InvariantInfo); var x = double.Parse(toks[7], NumberFormatInfo.InvariantInfo); var y = double.Parse(toks[8], NumberFormatInfo.InvariantInfo); var z = double.Parse(toks[9], NumberFormatInfo.InvariantInfo); var nbond = int.Parse(toks[10], NumberFormatInfo.InvariantInfo); var atom = file.Builder.NewAtom(sym, new Vector3(x, y, z)); atom.Charge = charge; var bo = BondOrder.Single; for (int j = 11; j < (11 + nbond * 2); j += 2) { var s = int.Parse(toks[j], NumberFormatInfo.InvariantInfo) - 1; // since atoms start from 1 in the file var bt = toks[j + 1][0]; switch (bt) { case 's': bo = BondOrder.Single; break; case 'd': bo = BondOrder.Double; break; case 't': bo = BondOrder.Triple; break; case 'a': bo = BondOrder.Quadruple; break; } var ar = new List <object>(3) { atomSerial, s, bo }; cons.Add(ar); } m.Atoms.Add(atom); atomSerial++; line = input.ReadLine(); } // now just store all the bonds we have foreach (var ar in cons) { var s = m.Atoms[(int)ar[0]]; var e = m.Atoms[(int)ar[1]]; var bo = (BondOrder)ar[2]; if (!IsConnected(m, s, e)) { m.Bonds.Add(file.Builder.NewBond(s, e, bo)); } } mols.Add(m); // we may not get a 'mol N' immediately since // the aromaticring keyword might be present // and doesn't seem to be located within the molecule // block. However, if we do see this keyword we save this // since it can contain aromatic specs for any molecule // listed in the file // // The docs do not explicitly state the the keyword comes // after *all* molecules. So we save and then reprocess // all the molecules in a second pass while (true) { line = input.ReadLine(); if (line == null || line.StartsWith("mol", StringComparison.Ordinal)) { break; } if (line.StartsWith("aromaticring", StringComparison.Ordinal)) { aroringText.Add(line.Trim()); } } } } catch (IOException) { // FIXME: should make some noise now file = null; } if (aroringText.Count > 0) { // process aromaticring annotations foreach (var line in aroringText) { var toks = line.Split(' '); var natom = int.Parse(toks[1], NumberFormatInfo.InvariantInfo); int n = 0; for (int i = 2; i < toks.Length; i += 2) { var molnum = int.Parse(toks[i], NumberFormatInfo.InvariantInfo); // starts from 1 var atnum = int.Parse(toks[i + 1], NumberFormatInfo.InvariantInfo); // starts from 1 mols[molnum - 1].Atoms[atnum - 1].IsAromatic = true; n++; } Trace.Assert(n == natom); } } foreach (var mol in mols) { setOfMolecules.Add(mol); } chemModel.MoleculeSet = setOfMolecules; chemSequence.Add(chemModel); file.Add(chemSequence); return(file); }
private IChemFile ReadChemFile() { IChemSequence seq = file.Builder.NewChemSequence(); IChemModel model = file.Builder.NewChemModel(); var containerSet = file.Builder.NewAtomContainerSet(); IAtomContainer container = file.Builder.NewAtomContainer(); int lineNumber = 0; try { string line = input.ReadLine(); while (line != null) { Debug.WriteLine((lineNumber++) + ": ", line); string command = null; if (IsCommand(line)) { command = GetCommand(line); int lineCount = GetContentLinesCount(line); if (string.Equals("ATOMS", command, StringComparison.Ordinal)) { ProcessAtomsBlock(lineCount, container); } else if (string.Equals("BONDS", command, StringComparison.Ordinal)) { ProcessBondsBlock(lineCount, container); } else if (string.Equals("IDENT", command, StringComparison.Ordinal)) { ProcessIdentBlock(lineCount, container); } else if (string.Equals("NAME", command, StringComparison.Ordinal)) { ProcessNameBlock(lineCount, container); } else { // skip lines Trace.TraceWarning("Dropping block: ", command); for (int i = 0; i < lineCount; i++) { input.ReadLine(); } } } else { Trace.TraceWarning("Unexpected content at line: ", lineNumber); } line = input.ReadLine(); } containerSet.Add(container); model.MoleculeSet = containerSet; seq.Add(model); file.Add(seq); } catch (Exception exception) { string message = "Error while parsing CTX file: " + exception.Message; Trace.TraceError(message); Debug.WriteLine(exception); throw new CDKException(message, exception); } return(file); }
/// <summary> /// Read a ChemFile from a file in MDL SDF format. /// </summary> /// <returns>The ChemFile that was read from the MDL file.</returns> private IChemFile ReadChemFile(IChemFile chemFile) { IChemSequence chemSequence = chemFile.Builder.NewChemSequence(); IChemModel chemModel = chemFile.Builder.NewChemModel(); IChemObjectSet <IAtomContainer> setOfMolecules = chemFile.Builder.NewAtomContainerSet(); IAtomContainer m = ReadMolecule(chemFile.Builder.NewAtomContainer()); if (m != null) { setOfMolecules.Add(m); } chemModel.MoleculeSet = setOfMolecules; chemSequence.Add(chemModel); setOfMolecules = chemFile.Builder.NewAtomContainerSet(); chemModel = chemFile.Builder.NewChemModel(); string str; try { string line; while ((line = input.ReadLine()) != null) { Debug.WriteLine($"line: {line}"); // apparently, this is a SDF file, continue with // reading mol files str = line; if (string.Equals(line, "M END", StringComparison.Ordinal)) { continue; } if (string.Equals(str, "$$$$", StringComparison.Ordinal)) { m = ReadMolecule(chemFile.Builder.NewAtomContainer()); if (m != null) { setOfMolecules.Add(m); chemModel.MoleculeSet = setOfMolecules; chemSequence.Add(chemModel); setOfMolecules = chemFile.Builder.NewAtomContainerSet(); chemModel = chemFile.Builder.NewChemModel(); } } else { // here the stuff between 'M END' and '$$$$' if (m != null) { // ok, the first lines should start with '>' string fieldName = null; if (str.StartsWith("> ", StringComparison.Ordinal)) { // ok, should extract the field name int index = str.IndexOf('<', 2); if (index != -1) { int index2 = str.Substring(index).IndexOf('>'); if (index2 != -1) { fieldName = str.Substring(index + 1, index2 - 1); } } // end skip all other lines while ((line = input.ReadLine()) != null && line.StartsWithChar('>')) { Debug.WriteLine($"data header line: {line}"); } } if (line == null) { throw new CDKException("Expecting data line here, but found null!"); } string data = line; while ((line = input.ReadLine()) != null && line.Trim().Length > 0) { if (string.Equals(line, "$$$$", StringComparison.Ordinal)) { Trace.TraceError($"Expecting data line here, but found end of molecule: {line}"); break; } Debug.WriteLine($"data line: {line}"); data += line; // preserve newlines, unless the line is exactly 80 chars; in that case it // is assumed to continue on the next line. See MDL documentation. if (line.Length < 80) { data += "\n"; } } if (fieldName != null) { Trace.TraceInformation($"fieldName, data: {fieldName}, {data}"); m.SetProperty(fieldName, data); } } } } } catch (CDKException) { throw; } catch (Exception exception) { if (!(exception is IOException || exception is ArgumentException)) { throw; } string error = "Error while parsing SDF"; Trace.TraceError(error); Debug.WriteLine(exception); throw new CDKException(error, exception); } try { input.Close(); } catch (Exception exc) { string error = "Error while closing file: " + exc.Message; Trace.TraceError(error); throw new CDKException(error, exc); } chemFile.Add(chemSequence); return(chemFile); }
/// <summary> /// Read the Gaussian98 output. /// </summary> /// <param name="chemFile"></param> /// <returns>a ChemFile with the coordinates, energies, and vibrations.</returns> private IChemFile ReadChemFile(IChemFile chemFile) { IChemSequence sequence = chemFile.Builder.NewChemSequence(); IChemModel model = null; string line = input.ReadLine(); string levelOfTheory; string description; int modelCounter = 0; // Find first set of coordinates by skipping all before "Standard orientation" while (line != null) { if (line.Contains("Standard orientation:")) { // Found a set of coordinates model = chemFile.Builder.NewChemModel(); ReadCoordinates(model); break; } line = input.ReadLine(); } if (model != null) { // Read all other data line = input.ReadLine().Trim(); while (line != null) { if (line.IndexOf('#') == 0) { // Found the route section // Memorizing this for the description of the chemmodel lastRoute = line; modelCounter = 0; } else if (line.Contains("Standard orientation:")) { // Found a set of coordinates // Add current frame to file and create a new one. if (!readOptimizedStructureOnly.IsSet) { sequence.Add(model); } else { Trace.TraceInformation("Skipping frame, because I was told to do"); } FrameRead(); model = chemFile.Builder.NewChemModel(); modelCounter++; ReadCoordinates(model); } else if (line.Contains("SCF Done:")) { // Found an energy model.SetProperty(CDKPropertyName.Remark, line.Trim()); } else if (line.Contains("Harmonic frequencies")) { // Found a set of vibrations // ReadFrequencies(frame); } else if (line.Contains("Total atomic charges")) { ReadPartialCharges(model); } else if (line.Contains("Magnetic shielding")) { // Found NMR data ReadNMRData(model, line); } else if (line.Contains("GINC")) { // Found calculation level of theory levelOfTheory = ParseLevelOfTheory(line); Debug.WriteLine($"Level of Theory for this model: {levelOfTheory}"); description = lastRoute + ", model no. " + modelCounter; model.SetProperty(CDKPropertyName.Description, description); } else { } line = input.ReadLine(); } // Add last frame to file sequence.Add(model); FrameRead(); } chemFile.Add(sequence); return(chemFile); }
/// <summary> /// Read the ShelX from input. Each ShelX document is expected to contain one crystal structure. /// </summary> /// <param name="file"></param> /// <returns>a ChemFile with the coordinates, charges, vectors, etc.</returns> private IChemFile ReadChemFile(IChemFile file) { IChemSequence seq = file.Builder.NewChemSequence(); IChemModel model = file.Builder.NewChemModel(); crystal = file.Builder.NewCrystal(); string line = input.ReadLine(); bool end_found = false; while (input.Ready() && line != null && !end_found) { if (line.Length == 0) { Debug.WriteLine("Skipping empty line"); // skip empty lines } else if (line[0] == '#') { Trace.TraceWarning("Skipping comment: " + line); // skip comment lines } else if (!(line[0] == '_' || line.StartsWith("loop_", StringComparison.Ordinal))) { Trace.TraceWarning("Skipping unrecognized line: " + line); // skip line } else { /* determine CIF command */ string command = ""; int spaceIndex = line.IndexOf(' '); if (spaceIndex != -1) { // everything upto space is command try { command = line.Substring(0, spaceIndex); } catch (ArgumentOutOfRangeException) { // disregard this line break; } } else { // complete line is command command = line; } Debug.WriteLine($"command: {command}"); if (command.StartsWith("_cell", StringComparison.Ordinal)) { ProcessCellParameter(command, line); } else if (string.Equals(command, "loop_", StringComparison.Ordinal)) { line = ProcessLoopBlock(); continue; } else if (string.Equals(command, "_symmetry_space_group_name_H-M", StringComparison.Ordinal)) { string value = line.Substring(29).Trim(); crystal.SpaceGroup = value; } else { // skip command Trace.TraceWarning($"Skipping command: {command}"); line = input.ReadLine(); if (line != null && line.StartsWithChar(';')) { Debug.WriteLine("Skipping block content"); line = input.ReadLine(); if (line != null) { line = line.Trim(); } while ((line = input.ReadLine()) != null && !line.StartsWith(";")) { Debug.WriteLine($"Skipping block line: {line}"); } } } } line = input.ReadLine(); } Trace.TraceInformation("Adding crystal to file with #atoms: " + crystal.Atoms.Count); model.Crystal = crystal; seq.Add(model); file.Add(seq); return(file); }
private IChemFile ReadChemFile(IChemFile file) { IChemSequence seq = file.Builder.NewChemSequence(); IChemModel model = file.Builder.NewChemModel(); ICrystal crystal = null; int lineNumber = 0; Vector3 a, b, c; try { string line = input.ReadLine(); while (line != null) { Debug.WriteLine($"{lineNumber++}: {line}"); if (line.StartsWith("frame:", StringComparison.Ordinal)) { Debug.WriteLine("found new frame"); model = file.Builder.NewChemModel(); crystal = file.Builder.NewCrystal(); // assume the file format is correct Debug.WriteLine("reading spacegroup"); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); crystal.SpaceGroup = line; Debug.WriteLine("reading unit cell axes"); Vector3 axis = new Vector3(); Debug.WriteLine("parsing A: "); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); axis.X = FortranFormat.Atof(line); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); axis.Y = FortranFormat.Atof(line); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); axis.Z = FortranFormat.Atof(line); crystal.A = axis; axis = new Vector3(); Debug.WriteLine("parsing B: "); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); axis.X = FortranFormat.Atof(line); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); axis.Y = FortranFormat.Atof(line); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); axis.Z = FortranFormat.Atof(line); crystal.B = axis; axis = new Vector3(); Debug.WriteLine("parsing C: "); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); axis.X = FortranFormat.Atof(line); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); axis.Y = FortranFormat.Atof(line); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); axis.Z = FortranFormat.Atof(line); crystal.C = axis; Debug.WriteLine($"Crystal: {crystal}"); a = crystal.A; b = crystal.B; c = crystal.C; Debug.WriteLine("Reading number of atoms"); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); int atomsToRead = int.Parse(line, NumberFormatInfo.InvariantInfo); Debug.WriteLine("Reading no molecules in assym unit cell"); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); int Z = int.Parse(line, NumberFormatInfo.InvariantInfo); crystal.Z = Z; string symbol; double charge; Vector3 cart; for (int i = 1; i <= atomsToRead; i++) { cart = new Vector3(); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); symbol = line.Substring(0, line.IndexOf(':')); charge = double.Parse(line.Substring(line.IndexOf(':') + 1), NumberFormatInfo.InvariantInfo); line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); cart.X = double.Parse(line, NumberFormatInfo.InvariantInfo); // x line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); cart.Y = double.Parse(line, NumberFormatInfo.InvariantInfo); // y line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); cart.Z = double.Parse(line, NumberFormatInfo.InvariantInfo); // z IAtom atom = file.Builder.NewAtom(symbol); atom.Charge = charge; // convert Cartesian coords to fractional Vector3 frac = CrystalGeometryTools.CartesianToFractional(a, b, c, cart); atom.FractionalPoint3D = frac; crystal.Atoms.Add(atom); Debug.WriteLine($"Added atom: {atom}"); } model.Crystal = crystal; seq.Add(model); } else { Debug.WriteLine("Format seems broken. Skipping these lines:"); while (line != null && !line.StartsWith("frame:", StringComparison.Ordinal)) { line = input.ReadLine(); Debug.WriteLine($"{lineNumber++}: {line}"); } Debug.WriteLine("Ok, resynched: found new frame"); } } file.Add(seq); } catch (Exception exception) { if (!(exception is IOException || exception is ArgumentException)) { throw; } string message = "Error while parsing CrystClust file: " + exception.Message; Trace.TraceError(message); Debug.WriteLine(exception); throw new CDKException(message, exception); } return(file); }
/// <summary> /// Read a <see cref="IChemFile"/> from a file in PDB format. The molecules /// in the file are stored as <see cref="IBioPolymer"/>s in the /// <see cref="IChemFile"/>. The residues are the monomers of the /// <see cref="IBioPolymer"/>, and their names are the concatenation of the /// residue, chain id, and the sequence number. Separate chains (denoted by /// TER records) are stored as separate <see cref="IBioPolymer"/> molecules. /// </summary> /// <remarks> /// Connectivity information is not currently read. /// </remarks> /// <returns>The ChemFile that was read from the PDB file.</returns> private IChemFile ReadChemFile(IChemFile oFile) { // initialize all containers var oSeq = oFile.Builder.NewChemSequence(); var oModel = oFile.Builder.NewChemModel(); var oSet = oFile.Builder.NewAtomContainerSet(); // some variables needed var oBP = new PDBPolymer(); var molecularStructure = oFile.Builder.NewAtomContainer(); string cRead = ""; char chain = 'A'; // To ensure stringent name giving of monomers int lineLength = 0; bool isProteinStructure = false; atomNumberMap = new Dictionary <int, IAtom>(); if (readConnect.IsSet) { bondsFromConnectRecords = new List <IBond>(); } // do the reading of the Input try { do { cRead = oInput.ReadLine(); Debug.WriteLine($"Read line: {cRead}"); if (cRead != null) { lineLength = cRead.Length; // make sure the record name is 6 characters long if (lineLength < 6) { cRead = cRead + " "; } // check the first column to decide what to do var cCol = cRead.Substring(0, 6); switch (cCol.ToUpperInvariant()) { case "SEQRES": { isProteinStructure = true; } break; case "ATOM ": { #region // read an atom record var oAtom = ReadAtom(cRead, lineLength); if (isProteinStructure) { // construct a string describing the residue var cResidue = new StringBuilder(8); var oObj = oAtom.ResName; if (oObj != null) { cResidue = cResidue.Append(oObj.Trim()); } oObj = oAtom.ChainID; if (oObj != null) { // cResidue = cResidue.Append(((string)oObj).Trim()); cResidue = cResidue.Append(chain); } oObj = oAtom.ResSeq; if (oObj != null) { cResidue = cResidue.Append(oObj.Trim()); } // search for an existing strand or create a new one. var strandName = oAtom.ChainID; if (strandName == null || strandName.Length == 0) { strandName = chain.ToString(NumberFormatInfo.InvariantInfo); } var oStrand = oBP.GetStrand(strandName); if (oStrand == null) { oStrand = new PDBStrand { StrandName = strandName, Id = chain.ToString(NumberFormatInfo.InvariantInfo) }; } // search for an existing monomer or create a new one. var oMonomer = oBP.GetMonomer(cResidue.ToString(), chain.ToString(NumberFormatInfo.InvariantInfo)); if (oMonomer == null) { var monomer = new PDBMonomer { MonomerName = cResidue.ToString(), MonomerType = oAtom.ResName, ChainID = oAtom.ChainID, ICode = oAtom.ICode, ResSeq = oAtom.ResSeq }; oMonomer = monomer; } // add the atom oBP.AddAtom(oAtom, oMonomer, oStrand); } else { molecularStructure.Atoms.Add(oAtom); } if (readConnect.IsSet) { var isDup = atomNumberMap.ContainsKey(oAtom.Serial.Value); atomNumberMap[oAtom.Serial.Value] = oAtom; if (isDup) { Trace.TraceWarning($"Duplicate serial ID found for atom: {oAtom}"); } } Debug.WriteLine($"Added ATOM: {oAtom}"); // As HETATMs cannot be considered to either belong to a certain monomer or strand, // they are dealt with separately. #endregion } break; case "HETATM": { #region // read an atom record var oAtom = ReadAtom(cRead, lineLength); oAtom.HetAtom = true; if (isProteinStructure) { oBP.Atoms.Add(oAtom); } else { molecularStructure.Atoms.Add(oAtom); } var isDup = atomNumberMap.ContainsKey(oAtom.Serial.Value); atomNumberMap[oAtom.Serial.Value] = oAtom; if (isDup) { Trace.TraceWarning($"Duplicate serial ID found for atom: {oAtom}"); } Debug.WriteLine($"Added HETATM: {oAtom}"); #endregion } break; case "TER ": { #region // start new strand chain++; var oStrand = new PDBStrand { StrandName = chain.ToString(NumberFormatInfo.InvariantInfo) }; Debug.WriteLine("Added new STRAND"); #endregion } break; case "END ": { #region atomNumberMap.Clear(); if (isProteinStructure) { // create bonds and finish the molecule oSet.Add(oBP); if (useRebondTool.IsSet) { try { if (!CreateBondsWithRebondTool(oBP)) { // Get rid of all potentially created bonds. Trace.TraceInformation("Bonds could not be created using the RebondTool when PDB file was read."); oBP.Bonds.Clear(); } } catch (Exception exception) { Trace.TraceInformation("Bonds could not be created when PDB file was read."); Debug.WriteLine(exception); } } } else { if (useRebondTool.IsSet) { CreateBondsWithRebondTool(molecularStructure); } oSet.Add(molecularStructure); } #endregion } break; case "MODEL ": { #region // OK, start a new model and save the current one first *if* it contains atoms if (isProteinStructure) { if (oBP.Atoms.Count > 0) { // save the model oSet.Add(oBP); oModel.MoleculeSet = oSet; oSeq.Add(oModel); // setup a new one oBP = new PDBPolymer(); oModel = oFile.Builder.NewChemModel(); oSet = oFile.Builder.NewAtomContainerSet(); // avoid duplicate atom warnings atomNumberMap.Clear(); } } else { if (molecularStructure.Atoms.Count > 0) { // save the model oSet.Add(molecularStructure); oModel.MoleculeSet = oSet; oSeq.Add(oModel); // setup a new one molecularStructure = oFile.Builder.NewAtomContainer(); oModel = oFile.Builder.NewChemModel(); oSet = oFile.Builder.NewAtomContainerSet(); } } #endregion } break; case "REMARK": { #region var comment = oFile.GetProperty <string>(CDKPropertyName.Comment, ""); if (lineLength > 12) { comment = comment + cRead.Substring(11).Trim() + "\n"; oFile.SetProperty(CDKPropertyName.Comment, comment); } else { Trace.TraceWarning("REMARK line found without any comment!"); } #endregion } break; case "COMPND": { #region var title = cRead.Substring(10).Trim(); oFile.SetProperty(CDKPropertyName.Title, title); #endregion } break; case "CONECT": { #region // Read connectivity information from CONECT records. Only // covalent bonds are dealt with. Perhaps salt bridges // should be dealt with in the same way..? if (!readConnect.IsSet) { break; } cRead = cRead.Trim(); if (cRead.Length < 16) { Debug.WriteLine($"Skipping unexpected empty CONECT line! : {cRead}"); } else { int lineIndex = 6; int atomFromNumber = -1; int atomToNumber = -1; var molecule = (isProteinStructure) ? oBP : molecularStructure; while (lineIndex + 5 <= cRead.Length) { var part = cRead.Substring(lineIndex, 5).Trim(); if (atomFromNumber == -1) { try { atomFromNumber = int.Parse(part, NumberFormatInfo.InvariantInfo); } catch (FormatException) { } } else { try { atomToNumber = int.Parse(part, NumberFormatInfo.InvariantInfo); } catch (FormatException) { atomToNumber = -1; } if (atomFromNumber != -1 && atomToNumber != -1) { AddBond(molecule, atomFromNumber, atomToNumber); Debug.WriteLine($"Bonded {atomFromNumber} with {atomToNumber}"); } } lineIndex += 5; } } #endregion } break; case "HELIX ": { #region // HELIX 1 H1A CYS A 11 LYS A 18 1 RESIDUE 18 HAS POSITIVE PHI 1D66 72 // 1 2 3 4 5 6 7 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 var structure = new PDBStructure { StructureType = PDBStructure.Helix, StartChainID = cRead[19], StartSequenceNumber = int.Parse(cRead.Substring(21, 4).Trim(), NumberFormatInfo.InvariantInfo), StartInsertionCode = cRead[25], EndChainID = cRead[31], EndSequenceNumber = int.Parse(cRead.Substring(33, 4).Trim(), NumberFormatInfo.InvariantInfo), EndInsertionCode = cRead[37] }; oBP.Add(structure); #endregion } break; case "SHEET ": { #region var structure = new PDBStructure { StructureType = PDBStructure.Sheet, StartChainID = cRead[21], StartSequenceNumber = int.Parse(cRead.Substring(22, 4).Trim(), NumberFormatInfo.InvariantInfo), StartInsertionCode = cRead[26], EndChainID = cRead[32], EndSequenceNumber = int.Parse(cRead.Substring(33, 4).Trim(), NumberFormatInfo.InvariantInfo), EndInsertionCode = cRead[37] }; oBP.Add(structure); #endregion } break; case "TURN ": { #region var structure = new PDBStructure { StructureType = PDBStructure.Turn, StartChainID = cRead[19], StartSequenceNumber = int.Parse(cRead.Substring(20, 4).Trim(), NumberFormatInfo.InvariantInfo), StartInsertionCode = cRead[24], EndChainID = cRead[30], EndSequenceNumber = int.Parse(cRead.Substring(31, 4).Trim(), NumberFormatInfo.InvariantInfo), EndInsertionCode = cRead[35] }; oBP.Add(structure); #endregion } break; default: break; // ignore all other commands } } } while (cRead != null); } catch (Exception e) { if (e is IOException || e is ArgumentException) { Trace.TraceError("Found a problem at line:"); Trace.TraceError(cRead); Trace.TraceError("01234567890123456789012345678901234567890123456789012345678901234567890123456789"); Trace.TraceError(" 1 2 3 4 5 6 7 "); Trace.TraceError($" error: {e.Message}"); Debug.WriteLine(e); Console.Error.WriteLine(e.StackTrace); } else { throw; } } // try to close the Input try { oInput.Close(); } catch (Exception e) { Debug.WriteLine(e); } // Set all the dependencies oModel.MoleculeSet = oSet; oSeq.Add(oModel); oFile.Add(oSeq); return(oFile); }
/// <summary> /// Private method that actually parses the input to read a ChemFile /// object. /// /// Each PMP frame is stored as a Crystal in a ChemModel. The PMP /// file is stored as a ChemSequence of ChemModels. /// </summary> /// <returns>A ChemFile containing the data parsed from input.</returns> private IChemFile ReadChemFile(IChemFile chemFile) { IChemSequence chemSequence; IChemModel chemModel; ICrystal crystal; try { string line = ReadLine(); while (line != null) { if (line.StartsWith("%%Header Start", StringComparison.Ordinal)) { // parse Header section while (line != null && !(line.StartsWith("%%Header End", StringComparison.Ordinal))) { if (line.StartsWith("%%Version Number", StringComparison.Ordinal)) { string version = ReadLine().Trim(); if (!string.Equals(version, "3.00", StringComparison.Ordinal)) { Trace.TraceError("The PMPReader only supports PMP files with version 3.00"); return(null); } } line = ReadLine(); } } else if (line.StartsWith("%%Model Start", StringComparison.Ordinal)) { // parse Model section modelStructure = chemFile.Builder.NewAtomContainer(); while (line != null && !(line.StartsWith("%%Model End", StringComparison.Ordinal))) { var objHeaderMatcher = objHeader.Match(line); if (objHeaderMatcher.Success) { var obj = objHeaderMatcher.Groups[2].Value; ConstructObject(chemFile.Builder, obj); var id = int.Parse(objHeaderMatcher.Groups[1].Value, NumberFormatInfo.InvariantInfo); // Debug.WriteLine(object + " id: " + id); line = ReadLine(); while (line != null && !(string.Equals(line.Trim(), ")", StringComparison.Ordinal))) { // parse object command (or new object header) var objCommandMatcher = objCommand.Match(line); objHeaderMatcher = objHeader.Match(line); if (objHeaderMatcher.Success) { // ok, forget about nesting and hope for the best obj = objHeaderMatcher.Groups[2].Value; id = int.Parse(objHeaderMatcher.Groups[1].Value, NumberFormatInfo.InvariantInfo); ConstructObject(chemFile.Builder, obj); } else if (objCommandMatcher.Success) { var format = objCommandMatcher.Groups[1].Value; var command = objCommandMatcher.Groups[2].Value; var field = objCommandMatcher.Groups[3].Value; ProcessModelCommand(obj, command, format, field); } else { Trace.TraceWarning("Skipping line: " + line); } line = ReadLine(); } if (chemObject is IAtom) { atomids[id] = modelStructure.Atoms.Count; atomGivenIds[int.Parse(chemObject.GetProperty <string>(PMP_ID), NumberFormatInfo.InvariantInfo)] = id; modelStructure.Atoms.Add((IAtom)chemObject); } else if (chemObject is IBond) { // ignored: bonds may be defined before their // atoms so their handling is deferred until the // end of the model } else { Trace.TraceError("chemObject is not initialized or of bad class type"); } } line = ReadLine(); } Trace.Assert(line != null); if (line.StartsWith("%%Model End", StringComparison.Ordinal)) { // during the Model Start, all bonds are cached as PMP files might // define bonds *before* the involved atoms :( // the next lines dump the cache into the atom container int bondsFound = bondids.Count; Debug.WriteLine($"Found #bonds: {bondsFound}"); Debug.WriteLine($"#atom ones: {bondAtomOnes.Count}"); Debug.WriteLine($"#atom twos: {bondAtomTwos.Count}"); Debug.WriteLine($"#orders: {bondOrders.Count}"); foreach (var index in bondids.Keys) { if (!bondOrders.TryGetValue(index, out double order)) { order = 1; } Debug.WriteLine($"index: {index}"); Debug.WriteLine($"ones: {bondAtomOnes[index]}"); var atom1 = modelStructure.Atoms[atomids[bondAtomOnes[index]]]; var atom2 = modelStructure.Atoms[atomids[bondAtomTwos[index]]]; var bond = modelStructure.Builder.NewBond(atom1, atom2); if (order == 1.0) { bond.Order = BondOrder.Single; } else if (order == 2.0) { bond.Order = BondOrder.Double; } else if (order == 3.0) { bond.Order = BondOrder.Triple; } else if (order == 4.0) { bond.Order = BondOrder.Quadruple; } modelStructure.Bonds.Add(bond); } } } else if (line.StartsWith("%%Traj Start", StringComparison.Ordinal)) { chemSequence = chemFile.Builder.NewChemSequence(); double energyFragment = 0.0; double energyTotal = 0.0; int Z = 1; while (line != null && !(line.StartsWith("%%Traj End", StringComparison.Ordinal))) { if (line.StartsWith("%%Start Frame", StringComparison.Ordinal)) { chemModel = chemFile.Builder.NewChemModel(); crystal = chemFile.Builder.NewCrystal(); while (line != null && !(line.StartsWith("%%End Frame", StringComparison.Ordinal))) { // process frame data if (line.StartsWith("%%Atom Coords", StringComparison.Ordinal)) { // calculate Z: as it is not explicitely given, try to derive it from the // energy per fragment and the total energy if (energyFragment != 0.0 && energyTotal != 0.0) { Z = (int)Math.Round(energyTotal / energyFragment); Debug.WriteLine($"Z derived from energies: {Z}"); } // add atomC as atoms to crystal int expatoms = modelStructure.Atoms.Count; for (int molCount = 1; molCount <= Z; molCount++) { IAtomContainer clone = modelStructure.Builder.NewAtomContainer(); for (int i = 0; i < expatoms; i++) { line = ReadLine(); IAtom a = clone.Builder.NewAtom(); var st = Strings.Tokenize(line, ' '); a.Point3D = new Vector3(double.Parse(st[0], NumberFormatInfo.InvariantInfo), double.Parse(st[1], NumberFormatInfo.InvariantInfo), double.Parse(st[2], NumberFormatInfo.InvariantInfo)); a.CovalentRadius = 0.6; IAtom modelAtom = modelStructure.Atoms[atomids[atomGivenIds[i + 1]]]; a.Symbol = modelAtom.Symbol; clone.Atoms.Add(a); } rebonder.Rebond(clone); crystal.Add(clone); } } else if (line.StartsWith("%%E/Frag", StringComparison.Ordinal)) { line = ReadLine().Trim(); energyFragment = double.Parse(line, NumberFormatInfo.InvariantInfo); } else if (line.StartsWith("%%Tot E", StringComparison.Ordinal)) { line = ReadLine().Trim(); energyTotal = double.Parse(line, NumberFormatInfo.InvariantInfo); } else if (line.StartsWith("%%Lat Vects", StringComparison.Ordinal)) { line = ReadLine(); IList <string> st; st = Strings.Tokenize(line, ' '); crystal.A = new Vector3(double.Parse(st[0], NumberFormatInfo.InvariantInfo), double.Parse(st[1], NumberFormatInfo.InvariantInfo), double.Parse(st[2], NumberFormatInfo.InvariantInfo)); line = ReadLine(); st = Strings.Tokenize(line, ' '); crystal.B = new Vector3(double.Parse(st[0], NumberFormatInfo.InvariantInfo), double.Parse(st[1], NumberFormatInfo.InvariantInfo), double.Parse(st[2], NumberFormatInfo.InvariantInfo)); line = ReadLine(); st = Strings.Tokenize(line, ' '); crystal.C = new Vector3(double.Parse(st[0], NumberFormatInfo.InvariantInfo), double.Parse(st[1], NumberFormatInfo.InvariantInfo), double.Parse(st[2], NumberFormatInfo.InvariantInfo)); } else if (line.StartsWith("%%Space Group", StringComparison.Ordinal)) { line = ReadLine().Trim(); // standardize space group name. See Crystal.SetSpaceGroup() if (string.Equals("P 21 21 21 (1)", line, StringComparison.Ordinal)) { crystal.SpaceGroup = "P 2_1 2_1 2_1"; } else { crystal.SpaceGroup = "P1"; } } line = ReadLine(); } chemModel.Crystal = crystal; chemSequence.Add(chemModel); } line = ReadLine(); } chemFile.Add(chemSequence); } // else disregard line // read next line line = ReadLine(); } } catch (IOException e) { Trace.TraceError($"An IOException happened: {e.Message}"); Debug.WriteLine(e); chemFile = null; } catch (CDKException e) { Trace.TraceError($"An CDKException happened: {e.Message}"); Debug.WriteLine(e); chemFile = null; } return(chemFile); }
// private procedures /// <summary> /// Private method that actually parses the input to read a <see cref="IChemFile"/> object. /// </summary> /// <returns>A ChemFile containing the data parsed from input.</returns> private IChemFile ReadChemFile(IChemFile file) { IChemSequence chemSequence = file.Builder.NewChemSequence(); int number_of_atoms = 0; try { string line; while ((line = input.ReadLine()) != null) { // parse frame by frame string token = line.Split('\t', ' ', ',', ';')[0]; number_of_atoms = int.Parse(token, NumberFormatInfo.InvariantInfo); string info = input.ReadLine(); IChemModel chemModel = file.Builder.NewChemModel(); var setOfMolecules = file.Builder.NewAtomContainerSet(); IAtomContainer m = file.Builder.NewAtomContainer(); m.Title = info; for (int i = 0; i < number_of_atoms; i++) { line = input.ReadLine(); if (line == null) { break; } if (line.StartsWithChar('#') && line.Length > 1) { var comment = m.GetProperty(CDKPropertyName.Comment, ""); comment = comment + line.Substring(1).Trim(); m.SetProperty(CDKPropertyName.Comment, comment); Debug.WriteLine($"Found and set comment: {comment}"); i--; // a comment line does not count as an atom } else { double x = 0.0f, y = 0.0f, z = 0.0f; double charge = 0.0f; var tokenizer = Strings.Tokenize(line, '\t', ' ', ',', ';'); int fields = tokenizer.Count; if (fields < 4) { // this is an error but cannot throw exception } else { string atomtype = tokenizer[0]; x = double.Parse(tokenizer[1], NumberFormatInfo.InvariantInfo); y = double.Parse(tokenizer[2], NumberFormatInfo.InvariantInfo); z = double.Parse(tokenizer[3], NumberFormatInfo.InvariantInfo); if (fields == 8) { charge = double.Parse(tokenizer[4], NumberFormatInfo.InvariantInfo); } IAtom atom = file.Builder.NewAtom(atomtype, new Vector3(x, y, z)); atom.Charge = charge; m.Atoms.Add(atom); } } } setOfMolecules.Add(m); chemModel.MoleculeSet = setOfMolecules; chemSequence.Add(chemModel); line = input.ReadLine(); } file.Add(chemSequence); } catch (IOException e) { // should make some noise now file = null; Trace.TraceError($"Error while reading file: {e.Message}"); Debug.WriteLine(e); } return(file); }
/// <summary> /// Private method that actually parses the input to read a <see cref="IChemFile"/> object. /// </summary> /// <param name="file">the file to read from</param> /// <returns>A ChemFile containing the data parsed from input.</returns> private IChemFile ReadChemFile(IChemFile file) { IChemSequence chemSequence = file.Builder.NewChemSequence(); int number_of_atoms; try { string line = input.ReadLine(); while (line.StartsWithChar('#')) { line = input.ReadLine(); } // while (input.Ready() && line != null) { // Debug.WriteLine("lauf"); // parse frame by frame string token = Strings.Tokenize(line, '\t', ' ', ',', ';')[0]; number_of_atoms = int.Parse(token, NumberFormatInfo.InvariantInfo); string info = input.ReadLine(); IChemModel chemModel = file.Builder.NewChemModel(); var setOfMolecules = file.Builder.NewAtomContainerSet(); IAtomContainer m = file.Builder.NewAtomContainer(); m.Title = info; string[] types = new string[number_of_atoms]; double[] d = new double[number_of_atoms]; int[] d_atom = new int[number_of_atoms]; // Distances double[] a = new double[number_of_atoms]; int[] a_atom = new int[number_of_atoms]; // Angles double[] da = new double[number_of_atoms]; int[] da_atom = new int[number_of_atoms]; // Diederangles //Vector3[] pos = new Vector3[number_of_atoms]; // calculated positions int i = 0; while (i < number_of_atoms) { line = input.ReadLine(); // Debug.WriteLine("line:\""+line+"\""); if (line == null) { break; } if (line.StartsWithChar('#')) { // skip comment in file } else { d[i] = 0d; d_atom[i] = -1; a[i] = 0d; a_atom[i] = -1; da[i] = 0d; da_atom[i] = -1; var tokens = Strings.Tokenize(line, '\t', ' ', ',', ';'); int fields = int.Parse(tokens[0], NumberFormatInfo.InvariantInfo); if (fields < Math.Min(i * 2 + 1, 7)) { // this is an error but cannot throw exception } else if (i == 0) { types[i] = tokens[1]; i++; } else if (i == 1) { types[i] = tokens[1]; d_atom[i] = int.Parse(tokens[2], NumberFormatInfo.InvariantInfo) - 1; d[i] = double.Parse(tokens[3], NumberFormatInfo.InvariantInfo); i++; } else if (i == 2) { types[i] = tokens[1]; d_atom[i] = int.Parse(tokens[2], NumberFormatInfo.InvariantInfo) - 1; d[i] = double.Parse(tokens[3], NumberFormatInfo.InvariantInfo); a_atom[i] = int.Parse(tokens[4], NumberFormatInfo.InvariantInfo) - 1; a[i] = double.Parse(tokens[5], NumberFormatInfo.InvariantInfo); i++; } else { types[i] = tokens[1]; d_atom[i] = int.Parse(tokens[2], NumberFormatInfo.InvariantInfo) - 1; d[i] = double.Parse(tokens[3], NumberFormatInfo.InvariantInfo); a_atom[i] = int.Parse(tokens[4], NumberFormatInfo.InvariantInfo) - 1; a[i] = double.Parse(tokens[5], NumberFormatInfo.InvariantInfo); da_atom[i] = int.Parse(tokens[6], NumberFormatInfo.InvariantInfo) - 1; da[i] = double.Parse(tokens[7], NumberFormatInfo.InvariantInfo); i++; } } } // calculate cartesian coordinates var cartCoords = ZMatrixTools.ZMatrixToCartesian(d, d_atom, a, a_atom, da, da_atom); for (i = 0; i < number_of_atoms; i++) { m.Atoms.Add(file.Builder.NewAtom(types[i], cartCoords[i])); } // Debug.WriteLine("molecule:"+m); setOfMolecules.Add(m); chemModel.MoleculeSet = setOfMolecules; chemSequence.Add(chemModel); line = input.ReadLine(); file.Add(chemSequence); } catch (IOException) { // should make some noise now file = null; } return(file); }
private IChemFile ReadChemFile(IChemFile chemFile) { var chemSequence = chemFile.Builder.NewChemSequence(); var chemModel = chemFile.Builder.NewChemModel(); var setOfMolecules = chemFile.Builder.NewAtomContainerSet(); var m = ReadMolecule(chemFile.Builder.NewAtomContainer()); if (m != null) { setOfMolecules.Add(m); } chemModel.MoleculeSet = setOfMolecules; chemSequence.Add(chemModel); setOfMolecules = chemFile.Builder.NewAtomContainerSet(); chemModel = chemFile.Builder.NewChemModel(); try { firstLineisMolecule = true; while (m != null) { m = ReadMolecule(chemFile.Builder.NewAtomContainer()); if (m != null) { setOfMolecules.Add(m); chemModel.MoleculeSet = setOfMolecules; chemSequence.Add(chemModel); setOfMolecules = chemFile.Builder.NewAtomContainerSet(); chemModel = chemFile.Builder.NewChemModel(); } } } catch (CDKException) { throw; } catch (ArgumentException exception) { var error = "Error while parsing MOL2"; Trace.TraceError(error); Debug.WriteLine(exception); throw new CDKException(error, exception); } try { input.Close(); } catch (Exception exc) { var error = "Error while closing file: " + exc.Message; Trace.TraceError(error); throw new CDKException(error, exc); } chemFile.Add(chemSequence); // reset it to false so that other read methods called later do not get confused firstLineisMolecule = false; return(chemFile); }