/// <summary> /// This method parses a GRO formatted file for a molecular structures. /// If there are multiple 'frames' in the file it returns a list of structures rather than /// a structure and a trajectory. i.e. each frame is a new structure added to the output structure list. /// </summary> /// <param name="filename"></param> /// <returns></returns> public static List <PrimaryStructure> GetAllStructures(string filename) { StreamReader sr = null; List <PrimaryStructure> models = new List <PrimaryStructure>(); PrimaryStructure model = null; try { sr = new StreamReader(filename); model = GetFrame(sr); while (model != null) { models.Add(model); model = GetFrame(sr); } } catch (Exception e) { throw new FileParseException(e.Message); } finally { if (sr != null) { sr.Close(); } } return(models); }
public static void Run() { Console.WriteLine("Parsing PBD File"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); PrimaryStructure model = PDBStructureParser.GetPrimaryStructure(inputFilePath + inputFileName); stopWatch.Stop(); Console.WriteLine("Structure Parsing Complete [" + stopWatch.ElapsedMilliseconds + " ms]"); Console.WriteLine("Atom Count: " + model.Atoms().Count); Console.WriteLine("Running Stride Analysis"); stopWatch = new Stopwatch(); stopWatch.Start(); StrideAnalysis stride = new StrideAnalysis(exePath); SecondaryStructure structure = stride.GetSecondaryStructure(inputFilePath + inputFileName); // Console.WriteLine("Secondary structure:\n\n" + structure); stopWatch.Stop(); Console.WriteLine("Processing complete [" + stopWatch.ElapsedMilliseconds + " ms]"); Console.WriteLine("End Testing Stride"); foreach (Chain chain in model.Chains()) { Console.WriteLine("Chain ID: " + chain.ID); if (chain.ResidueType != StandardResidue.AminoAcid) { Console.WriteLine("Not a protein chain"); continue; } foreach (Residue residue in chain.MainChainResidues) { if (residue.CarbonylOxygen == null) { Console.WriteLine("Residue ID: " + residue.ID + " has no oxygen"); } SecondaryStructureInfomation structureInfo = structure.GetStructureInformation(residue.Index); if (structureInfo == null) { Console.WriteLine("Couldn't find structure info for residue index: " + residue.Index); } else { Console.WriteLine("Residue [" + residue.ID + "][" + residue.Name + "] has structure [" + structureInfo.ToString() + "] and Alpha Carbon: " + residue.AlphaCarbon); } } } }
public static void Run() { // get the primary structure Console.WriteLine("Parsing GRO File"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); PrimaryStructure primaryStructure = GROStructureParser.GetStructure(inputFilePath + inputFileName); stopWatch.Stop(); Console.WriteLine("Structure Parsing Complete [" + stopWatch.ElapsedMilliseconds + " ms]"); // get the structure trajectory int atomCount = XTCTrajectoryParser.GetAtomCount(inputFilePath + trajectoryFileName); if (atomCount == primaryStructure.AtomCount()) { Console.WriteLine("Atom Count matches."); } else { Console.WriteLine("Atom count doesnt match between primary structure and trajectory"); } Stopwatch stopWatch2 = new Stopwatch(); stopWatch2.Start(); PrimaryStructureTrajectory trajectory = XTCTrajectoryParser.GetTrajectory(inputFilePath + trajectoryFileName, 0, 100, 1); stopWatch2.Stop(); Console.WriteLine("Trajectory Parsing Complete [" + stopWatch2.ElapsedMilliseconds + " ms]"); // get the secondary structure for the base primary structure Stopwatch stopWatch3 = new Stopwatch(); stopWatch3.Start(); SecondaryStructure secondaryStructure = SecondaryStructure.CreateFromPrimaryStructure(primaryStructure, strideExePath, tmpFilePath); Console.WriteLine("Main Secondary Structure Parsing Complete [" + stopWatch3.ElapsedMilliseconds + " ms]"); Console.WriteLine(secondaryStructure); // get the secondary structure for a frame of the trajectory Stopwatch stopWatch4 = new Stopwatch(); stopWatch4.Start(); SecondaryStructureTrajectory secondaryStructureTrajectory = new SecondaryStructureTrajectory(primaryStructure, trajectory, strideExePath, tmpFilePath); SecondaryStructure secondaryStructure2 = secondaryStructureTrajectory.GetStructure(50); Console.WriteLine("Secondary Structure Parsing for frame 50 Complete [" + stopWatch3.ElapsedMilliseconds + " ms]"); Console.WriteLine(secondaryStructure2); }
public SecondaryStructureTrajectory(PrimaryStructure primaryStructure, PrimaryStructureTrajectory primaryTrajectory, string strideExePath, string tmpFilePath) { this.primaryStructure = primaryStructure; this.primaryTrajectory = primaryTrajectory; this.strideExePath = strideExePath; this.tmpFilePath = tmpFilePath; secondaryStructuresFrames = new Dictionary <int, SecondaryStructure>(); badFrames = new HashSet <int>(); }
public static void Run() { Console.WriteLine("Parsing PDB File"); PrimaryStructure primaryStructure = PDBStructureParser.GetPrimaryStructure(inputFilePath + inputFileName); // dump structure to PDB file. Can check this file against the original input file for equivalence string tmpFileName = tmpFilePath + @"tempStructure.pdb"; PDBStructureCreator pdbCreator = new PDBStructureCreator(primaryStructure, null); pdbCreator.CreatePDBFile(tmpFileName, true, true); // FileUtil.DeleteFile(tmpFileName); }
public static void Run() { Console.WriteLine("Parsing PDB File"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); PrimaryStructure primaryStructure = PDBStructureParser.GetPrimaryStructure(filepath + structureFile); stopWatch.Stop(); Console.WriteLine("Structure Parsing Complete [" + stopWatch.ElapsedMilliseconds + " ms]"); stopWatch.Reset(); stopWatch.Start(); SecondaryStructure.CreateFromPrimaryStructure(primaryStructure, strideExePath, tmpFilePath); Console.WriteLine("Main Secondary Structure Parsing Complete [" + stopWatch.ElapsedMilliseconds + " ms]"); foreach (Chain chain in primaryStructure.Chains()) { foreach (Atom atom in chain.MainChainAtoms) { // if no frame number use the base structure coordinates. if (atom == null) { Console.WriteLine("Main chain atom is null"); } else { Console.WriteLine("Atom found: " + atom.ToString()); } } //Console.WriteLine("\n---------------------\n"); //Console.WriteLine("Chain ID: " + chain.ID); //Console.WriteLine("Chain Residue Count: " + chain.Residues.Count); //if (chain.ResidueType == MolecularDynamics.Definitions.StandardResidue.AminoAcid) { // foreach (Residue residue in chain.Residues) { // Console.WriteLine("Residue index: " + residue.Index + ", ResidueID: " + residue.ID + ", Residue Name: " + residue.Name); // SecondaryStructureInfomation information = secondaryStructure.GetStructureInformation(residue.Index); // if (information == null) { // Console.WriteLine("information null: " + residue.Index); // } // } //} //else { // Console.WriteLine("Not an amino acid residue"); //} } }
public static PrimaryStructure GetStructure(string filename) { PrimaryStructure model; StreamReader sr = null; try { sr = new StreamReader(filename); int atomCount = Int32.Parse(sr.ReadLine().Trim()); string titleLine = sr.ReadLine(); model = new PrimaryStructure(); model.Title = titleLine; model.Time = 0; for (int i = 0; i < atomCount; i++) { string atomLine = sr.ReadLine(); Regex g = new Regex(@"\s*?(\w+)\s+([\d\.\-]+)\s+([\d\.\-]+)\s+([\d\.\-]+).*$"); Match m = g.Match(atomLine); int atomID = int.Parse(i.ToString()); string name = m.Groups[1].Value.Trim(); Element element = ElementHelper.Parse(name); Vector3 position = new Vector3(); position.x = float.Parse(m.Groups[2].Value) / 10f; position.y = float.Parse(m.Groups[3].Value) / 10f; position.z = float.Parse(m.Groups[4].Value) / 10f; Atom atom = new Atom(i, atomID, name, element, position); atom.ResidueType = StandardResidue.None; model.AddAtom(i, atom); } } catch (Exception e) { throw new FileParseException(e.Message); } finally { if (sr != null) { sr.Close(); } } return(model); }
public static SecondaryStructure CreateFromPrimaryStructure(PrimaryStructure primaryStructure, string strideExePath, string tmpFilePath) { string tmpFileName = tmpFilePath + @"tempStructure.pdb"; PDBStructureCreator pdbCreator = new PDBStructureCreator(primaryStructure, null); //pdbCreator.CreatePDBFile(tmpFileName, true, true, true); pdbCreator.CreatePDBFile(tmpFileName); SecondaryStructure secondaryStructure = null; try { StrideAnalysis stride = new StrideAnalysis(strideExePath); secondaryStructure = stride.GetSecondaryStructure(tmpFileName); } finally { FileUtil.DeleteFile(tmpFileName); } return(secondaryStructure); }
/// <summary> /// This method parses a GRO formatted file for a molecular structure. /// It will only parse the first frame in the file and return a MolecularModel with one frame. Additional frames in the GRO file will be discarded. /// </summary> /// <param name="filename"></param> /// <returns></returns> public static PrimaryStructure GetStructure(string filename) { StreamReader sr = null; PrimaryStructure model = null; try { sr = new StreamReader(filename); model = GetFrame(sr); } catch (Exception e) { throw new FileParseException(e.Message); } finally { if (sr != null) { sr.Close(); } } return(model); }
// private static string inputFileFileName = @"lipoprotein_DS.pdb"; //private static string inputFileFileName = @"lipoprotein.pdb"; //private static string inputFilePath = @"D:\Molecule Examples\PDB Example Files\"; //private static string inputFileFileName = @"Zika_Virus_5ire.pdb"; public static void Run() { Console.WriteLine("Parsing PBD File"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // PrimaryStructure model = PDBStructureParser.GetStructure(inputFilePath + inputFileFileName); PrimaryStructure model = GROStructureParser.GetStructure(inputFilePath + inputFileFileName); stopWatch.Stop(); Console.WriteLine("Structure Parsing Complete [" + stopWatch.ElapsedMilliseconds + " ms]"); Console.WriteLine("Atom Count: " + model.Atoms().Count); // Console.WriteLine(model.ToString()); foreach (Chain chain in model.Chains()) { Console.WriteLine("Chain " + chain.ID + ": ");// + residue.ToString()); if (chain.ResidueType == StandardResidue.AminoAcid) { foreach (Residue residue in chain.MainChainResidues) { Console.WriteLine(residue); } //foreach (Atom mainChainAtom in chain.Value.MainChainAtoms) { // Console.WriteLine(mainChainAtom); //} } else { Console.WriteLine("Chain " + chain.ID + " is not a protein chain"); //foreach (KeyValuePair<int, Residue> residue in chain.Value.Residues) { // Console.WriteLine(residue.Value.ResidueType.ToString()); //} } } }
public static void Run() { Console.WriteLine("Parsing GRO File"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); PrimaryStructure primaryStructure = GROStructureParser.GetStructure(filepath + structureFile); stopWatch.Stop(); Console.WriteLine("Structure Parsing Complete [" + stopWatch.ElapsedMilliseconds + " ms]"); stopWatch.Reset(); stopWatch.Start(); SecondaryStructure secondaryStructure = SecondaryStructure.CreateFromPrimaryStructure(primaryStructure, strideExePath, tmpFilePath); Console.WriteLine("Main Secondary Structure Parsing Complete [" + stopWatch.ElapsedMilliseconds + " ms]"); foreach (Chain chain in primaryStructure.Chains()) { Console.WriteLine("\n---------------------\n"); Console.WriteLine("Chain ID: " + chain.ID); Console.WriteLine("Chain Residue Count: " + chain.Residues.Count); foreach (Residue residue in chain.Residues) { Console.WriteLine("Residue index: " + residue.Index + ", ResidueID: " + residue.ID + ", Residue Name: " + residue.Name); SecondaryStructureInfomation information = secondaryStructure.GetStructureInformation(residue.Index); if (information == null) { Console.WriteLine("information null: " + residue.Index); } } } }
public static void GetTrajectoryColours(string filename, PrimaryStructure model, PrimaryStructureTrajectory trajectory) { GetTrajectoryColours(filename, model, trajectory, 0, DEFAULT_FRAME_READ, 1); }
public static void GetTrajectoryColours(string filename, PrimaryStructure model, PrimaryStructureTrajectory trajectory, int startFrame, int numFrames, int frameFrequency) { Stopwatch watch = new Stopwatch(); watch.Start(); StreamReader reader = null; Regex g = new Regex(@"\s*(\d+)\s*(\d+\.?\d*)"); try { reader = new StreamReader(filename); discardFrames(reader, startFrame); List <float[]> colourFrames = new List <float[]>(); int colourFrameNumber = -1; int atomIndex = 0; float colour = 0; float[] colourFrame = null; string line; while ((line = readLine(reader)) != null && colourFrames.Count < numFrames) { if (line.Trim().Length == 0) // is empty string? { continue; } // discard everything but matches Match m = g.Match(line); if (m.Success) { atomIndex = int.Parse(m.Groups[1].Value); colour = float.Parse(m.Groups[2].Value); if (atomIndex == 1) { colourFrameNumber++; // save colours if (colourFrame != null) { colourFrames.Add(colourFrame); colourFrame = null; } if (colourFrameNumber % frameFrequency == 0) { // initialise new colour arrary colourFrame = new float[model.AtomCount()]; for (int i = 0; i < colourFrame.Length; i++) { colourFrame[i] = DEFAULT_COLOUR_VALUE; } } } if (colourFrame != null) { if (atomIndex > 0 && atomIndex <= colourFrame.Length) { colourFrame[atomIndex - 1] = colour; } } } } PrimaryStructureFrame currentFrame = null; int frameNumber = 0; // copy all colour frames to trajectory frames foreach (float[] frame in colourFrames) { currentFrame = trajectory.GetFrame(frameNumber); currentFrame.Colours = frame; frameNumber++; // if we've run out of trajectory frames then stop copying if (frameNumber >= trajectory.FrameCount()) { break; } } // if more trajectory frames than colour frames fill in rest of trajectory frames with default colours float[] colours = new float[model.AtomCount()]; for (int i = 0; i < colours.Length; i++) { colours[i] = 0f; } foreach (PrimaryStructureFrame frame in trajectory.GetFrames()) { if (frame.Colours == null) { frame.Colours = colours; } } } catch (Exception e) { throw new FileParseException(e.Message); } finally { if (reader != null) { reader.Close(); } } }
/// <summary> /// This method parses a PDB formatted file for a molecular primary structure. /// It will only parse the first model in the file (as defined by the ENDMDL record. Additional models in the PDB file will be discarded. /// </summary> /// <param name="filename"></param> /// <returns></returns> public static PrimaryStructure GetPrimaryStructure(string filename) { PrimaryStructure model; StreamReader sr = null; try { sr = new StreamReader(filename); model = new PrimaryStructure(); bool EOF = false; // all indexing is 1 based and will increment before first assignment int atomIndex = 0; int residueIndex = 0; int chainIndex = 0; Chain chain = null; Residue residue = null; int currentResidueID = -1; string currentChainID = ""; bool TERFound = false; while (!EOF) { string record = sr.ReadLine(); // Console.WriteLine("processing Line: " + record); if (record == null || record.Trim().Equals("END")) { EOF = true; } else { if (record == null || record.Trim() == "") { continue; } string recordName = record; if (recordName.Length < 6) { recordName = recordName.Trim(); } else { recordName = record.Substring(0, 6).Trim(); } switch (recordName) { case "ATOM": case "HETATM": int atomResidueID = int.Parse(record.Substring(22, 4).Trim()); if (atomResidueID != currentResidueID) { // store residue - first time here will be null if (residue != null) { model.AddResidue(residueIndex, residue); if (chain != null && currentChainID != "") { chain.AddResidue(residueIndex, residue); } } residueIndex++; currentResidueID = atomResidueID; string residueName = record.Substring(17, 3).Trim(); residue = new Residue(residueIndex, atomResidueID, residueName); } string chainID = record.Substring(21, 1).Trim(); if (currentChainID != chainID || TERFound) { Console.WriteLine("Handling new chain"); if (chain != null && currentChainID != "") { model.AddChain(chain); } if (chainID != null) { chainIndex++; chain = new Chain(chainIndex, chainID); } currentChainID = chainID; TERFound = false; } int atomID = int.Parse(record.Substring(6, 5).Trim()); string atomName = record.Substring(12, 4).Trim(); Element element = ElementHelper.Parse(record.Substring(76, 2).Trim()); float charge = 0; // if the file has extra columns at the end then assume they are for charge and try to parse if (record.Length > 80) { string chargeString = record.Substring(80, record.Length - 80).Trim(); if (chargeString.Length > 0) { try { charge = float.Parse(chargeString); } catch (Exception) { // do nothing } } } // PDB coordinates are in angstroms. Convert to nanometres. Vector3 position = new Vector3(); position.x = float.Parse(record.Substring(30, 8)) / 10; position.y = float.Parse(record.Substring(38, 8)) / 10; position.z = float.Parse(record.Substring(46, 8)) / 10; atomIndex++; Atom atom = new Atom(atomIndex, atomID, atomName, element, position, charge); //Debug.Log("Atom: " + atom); // check for and store main chain elements. if (recordName.Equals("ATOM") && residue.ResidueType != StandardResidue.None) { switch (atom.Name) { case "N": residue.AmineNitrogen = atom; break; case "CA": residue.AlphaCarbon = atom; break; case "C": residue.CarbonylCarbon = atom; break; case "O": case "O1": case "OT1": residue.CarbonylOxygen = atom; break; } } atom.ResidueIndex = residueIndex; atom.ResidueID = currentResidueID; atom.ResidueName = residue.Name; atom.ResidueType = residue.ResidueType; if (currentChainID != "") { atom.ChainID = currentChainID; } residue.Atoms.Add(atomIndex, atom); model.AddAtom(atomIndex, atom); break; case "TER": Console.WriteLine("Found TER"); TERFound = true; break; case "TITLE": if (model.Title == null) { model.Title = ""; } // many PDB's have long remark sections. Abbreviate for now. if (model.Title.Length < 200) { model.Title += record.Substring(7) + "\n"; } break; case "ENDMDL": case "END": // currently only parse the first model in the file EOF = true; break; } } } if (residue != null) { model.AddResidue(residueIndex, residue); if (chain != null) { chain.AddResidue(residueIndex, residue); } } if (chain != null && currentChainID != "") { model.AddChain(chain); } } catch (Exception e) { throw new FileParseException(e.Message); } finally { if (sr != null) { sr.Close(); } } return(model); }
public static void ParseGromacs() { Console.WriteLine("Parsing GRO File"); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); PrimaryStructure model = GROStructureParser.GetStructure(filepath + structureFile); stopWatch.Stop(); Console.WriteLine("Structure Parsing Complete [" + stopWatch.ElapsedMilliseconds + " ms]"); Console.WriteLine("Atom Count: " + model.Atoms().Count); foreach (Atom atom in model.Atoms()) { Console.WriteLine("Atom " + atom.Index + ": " + atom.ToString()); } Console.WriteLine("\n---------------------\n"); Dictionary <Element, Dictionary <int, Atom> > atomSet = model.GetAtomsByElement(); foreach (KeyValuePair <Element, Dictionary <int, Atom> > set in atomSet) { Element element = set.Key; Console.WriteLine("Element: " + element.ToString()); Dictionary <int, Atom> atoms = set.Value; foreach (KeyValuePair <int, Atom> atom in atoms) { Console.WriteLine("Atom: " + atom.Value.ToString()); } } foreach (Chain chain in model.Chains()) { Console.WriteLine("\n---------------------\n"); Console.WriteLine("Chain ID: " + chain.ID); Console.WriteLine("Chain Residue Count: " + chain.Residues.Count); foreach (Residue residue in chain.Residues) { Console.WriteLine("ResidueID: " + residue.ID + ", Residue Name: " + residue.Name); } } stopWatch.Reset(); stopWatch.Start(); int NumberOfProcessorCores = 6; Dictionary <int, Bond> bonds = model.GenerateBonds(NumberOfProcessorCores); Console.WriteLine("Bond generation complete [" + stopWatch.ElapsedMilliseconds + " ms]"); int count = 0; foreach (KeyValuePair <int, Bond> bond in bonds) { Atom atom1 = model.Atoms()[bond.Value.Atom1Index]; Atom atom2 = model.Atoms()[bond.Value.Atom2Index]; if ((atom1.Element == Element.O && atom2.Element == Element.H) || (atom2.Element == Element.O && atom1.Element == Element.H)) { Console.WriteLine("O-H bond found. Distance: " + Vector3.Distance(atom1.Position, atom2.Position)); count++; if (count > 5) { break; } } } Console.WriteLine("Getting frame count from trajectory file"); stopWatch.Reset(); stopWatch.Start(); count = XTCTrajectoryParser.GetFrameCount(filepath + trajectoryFile); stopWatch.Stop(); Console.WriteLine("Frame count complete [" + stopWatch.ElapsedMilliseconds + " ms]"); Console.WriteLine("Frames counted: " + count); }
public PDBStructureCreator(PrimaryStructure structure, PrimaryStructureFrame frame) { this.structure = structure; this.frame = frame; }
public PDBStructureCreator(PrimaryStructure structure) { this.structure = structure; }
/// <summary> /// generate a box from a provided Primary Structure /// </summary> /// <returns></returns> public BoundingBox(PrimaryStructure structure, bool flipZ = false) { float minx = 0; float maxx = 0; float miny = 0; float maxy = 0; float minz = 0; float maxz = 0; bool firstAtom = true; foreach (Atom atom in structure.Atoms()) { if (firstAtom) { minx = atom.Position.x; maxx = atom.Position.x; miny = atom.Position.y; maxy = atom.Position.y; minz = atom.Position.z; maxz = atom.Position.z; firstAtom = false; } else { if (atom.Position.x < minx) { minx = atom.Position.x; } if (atom.Position.x > maxx) { maxx = atom.Position.x; } if (atom.Position.y < miny) { miny = atom.Position.y; } if (atom.Position.y > maxy) { maxy = atom.Position.y; } if (atom.Position.z < minz) { minz = atom.Position.z; } if (atom.Position.z > maxz) { maxz = atom.Position.z; } } } float edgeBuffer = 0.1f; minx -= edgeBuffer; maxx += edgeBuffer; miny -= edgeBuffer; maxy += edgeBuffer; minz -= edgeBuffer; maxz += edgeBuffer; if (flipZ) { minz *= -1; maxz *= -1; } setVectors(minx, maxx, miny, maxy, minz, maxz); }
private static PrimaryStructure GetFrame(StreamReader sr) { PrimaryStructure model; // todo: improve file format error handling for misformatted files try { model = new PrimaryStructure(); string titleLine = sr.ReadLine(); // remove any blank lines before title line while (titleLine != null && titleLine.Trim().Equals("")) { titleLine = sr.ReadLine(); } if (titleLine == null) { return(null); } model.Title = titleLine; model.Time = 0; Regex g = new Regex(@"\st=\s*(\d+\.?\d*)"); Match m = g.Match(titleLine); if (m.Success) { string frameTimeString = m.Groups[1].Value; model.Time = float.Parse(frameTimeString); // Console.WriteLine("Success parsing[" + titleLine + "] for frame time"); } else { // no frame time in header. Assume structure file, leave frame time at 0; // return false; } int residueIndex = 0; int chainIndex = 0; Chain chain = null; Residue residue = null; int currentResidueID = -1; Residue lastResidue = null; int atomCount = Int32.Parse(sr.ReadLine().Trim()); for (int i = 0; i < atomCount; i++) { string atomLine = sr.ReadLine(); if (atomLine == null) // if something is wrong with the file, i.e. ends before total atom count { break; } // if atom residue number not the existing residue number store the existing residue and instantiate new residue int atomResidueID = int.Parse(atomLine.Substring(0, 5).Trim()); if (atomResidueID != currentResidueID) { // store residue - first time here will be null if (residue != null) { model.AddResidue(residueIndex, residue); if (chain != null) { chain.AddResidue(residueIndex, residue); } } residueIndex++; currentResidueID = atomResidueID; string residueName = atomLine.Substring(5, 5).Trim(); lastResidue = residue; residue = new Residue(residueIndex, currentResidueID, residueName); // Residue type changes used to capture chain information. May not be 100% accurate but not parsing topology files so options are limited. // Also checking to see if last two atoms before end of amino acid were Oxygen, signifying a chain terminator if ((lastResidue == null || residue.ResidueType != lastResidue.ResidueType) || (lastResidue.ResidueType == StandardResidue.AminoAcid && model.Atoms()[i - 1].Element == Element.O && model.Atoms()[i - 2].Element == Element.O)) { if (chain != null) { model.AddChain(chain); } chainIndex++; chain = new Chain(chainIndex, chainIndex.ToString()); } } int atomIndex = i; int atomID = int.Parse((atomLine.Substring(15, 5)).Trim()); string atomName = atomLine.Substring(10, 5).Trim(); Element element = ElementHelper.Parse(atomName); Vector3 position = new Vector3(); position.x = float.Parse(atomLine.Substring(20, 8)); position.y = float.Parse(atomLine.Substring(28, 8)); position.z = float.Parse(atomLine.Substring(36, 8)); Atom atom = new Atom(atomIndex, atomID, atomName, element, position); // check for and store main chain elements. if (residue.ResidueType != StandardResidue.None) { switch (atom.Name) { case "N": residue.AmineNitrogen = atom; break; case "CA": residue.AlphaCarbon = atom; break; case "C": residue.CarbonylCarbon = atom; break; case "O": case "O1": case "OT1": residue.CarbonylOxygen = atom; break; } } atom.ResidueIndex = residueIndex; atom.ResidueID = currentResidueID; atom.ResidueName = residue.Name; atom.ResidueType = residue.ResidueType; atom.ChainID = chainIndex.ToString(); residue.Atoms.Add(atomIndex, atom); model.AddAtom(atomIndex, atom); } if (residue != null) { model.AddResidue(residueIndex, residue); if (chain != null) { chain.AddResidue(residueIndex, residue); } } if (chain != null) { model.AddChain(chain); } // Parse box vectors. // todo: test and make this more robust for various string lengths float[] vertices = parseBoxLine(sr.ReadLine()); model.OriginalBoundingBox = new BoundingBox(vertices[0], vertices[1], vertices[2], vertices[3], vertices[4], vertices[5], vertices[6], vertices[7], vertices[8]); } catch (Exception e) { throw new FileParseException(e.Message); } return(model); }