bool RandomAtomsAreCorrect(PDBImporter importer) { PDBAtom testAtom; for (int i = 0; i < randomAtomsToTestPerStructure; i++) { string line = importer.lines[Random.Range(0, importer.lines.Length)]; if (line.Substring(0, 6).Trim().Equals("ATOM")) { testAtom = importer.ParseAtom(-1, line); testAtom.localPosition -= importer.molecule.centerOffset; PDBAtom realAtom = importer.molecule.atoms.Find(a => a.atomNumber == testAtom.atomNumber); if (!realAtom.EqualsAtom(testAtom)) { return(false); } // Debug.Log(realAtom.ToString() + " PASSED"); } } return(true); }
public /*Chem*/ Frame(Org.OpenScience.CDK.Interfaces.IChemFile chemFile, Device graphicsDevice) { shapes = new Shape[JmolConstants.SHAPE_MAX]; this.g3d = new NuGraphics3D(graphicsDevice); this.frameRenderer = new FrameRenderer(); for (int i = MAX_BONDS_LENGTH_TO_CACHE; --i > 0;) // .GT. 0 { freeBonds[i] = new Bond[MAX_NUM_TO_CACHE][]; } // convert to jmol native mmset = new Mmset(this); // set properties mmset.ModelSetProperties = new System.Collections.Specialized.NameValueCollection(); // init build currentModelIndex = -1; currentModel = null; currentChainID = '\uFFFF'; currentChain = null; currentGroupSequenceNumber = -1; currentGroupInsertionCode = '\uFFFF'; int atomCountEstimate = 0; for (int seq = 0; seq < chemFile.ChemSequenceCount; seq++) { for (int model = 0; model < chemFile.ChemSequences[seq].ChemModelCount; model++) { Org.OpenScience.CDK.Interfaces.IChemModel chemModel = chemFile.ChemSequences[seq].ChemModels[model]; for (int atomC = 0; atomC < chemModel.SetOfMolecules.AtomContainerCount; atomC++) { atomCountEstimate += chemModel.SetOfMolecules.AtomContainers[atomC].AtomCount; } } } if (atomCountEstimate <= 0) { atomCountEstimate = ATOM_GROWTH_INCREMENT; } atoms = new Atom[atomCountEstimate]; bonds = new Bond[2 * atomCountEstimate]; htAtomMap.Clear(); // translate IChemSequence[] into Model[] mmset.ModelCount = chemFile.ChemSequenceCount; for (int seq = 0; seq < chemFile.ChemSequenceCount; ++seq) { int modelNumber = seq + 1; string modelName = modelNumber.ToString(); NameValueCollection modelProperties = new NameValueCollection(); // FIXME: Loading property values mmset.setModelNameNumberProperties(seq, modelName, modelNumber, modelProperties); } // translate Atoms Dictionary <Org.OpenScience.CDK.Interfaces.IAtom, Atom> atomsList = new Dictionary <Org.OpenScience.CDK.Interfaces.IAtom, Atom>(); //try //{ for (int seq = 0; seq < chemFile.ChemSequenceCount; seq++) { for (int model = 0; model < chemFile.ChemSequences[seq].ChemModelCount; model++) { Org.OpenScience.CDK.Interfaces.IChemModel chemModel = chemFile.ChemSequences[seq].ChemModels[model]; for (int atomC = 0; atomC < chemModel.SetOfMolecules.AtomContainerCount; atomC++) { for (int atomIdx = 0; atomIdx < chemModel.SetOfMolecules.AtomContainers[atomC].AtomCount; atomIdx++) { Org.OpenScience.CDK.Interfaces.IAtom atom = chemModel.SetOfMolecules.AtomContainers[atomC].Atoms[atomIdx]; sbyte elementNumber = (sbyte)atom.AtomicNumber; if (elementNumber <= 0) { elementNumber = JmolConstants.elementNumberFromSymbol(atom.Symbol); } char alternateLocation = '\0'; int sequenceNumber = int.MinValue; char groupInsertionCode = '\0'; string atomName = null; string group3Name = null; char chainID = '\0'; if (atom is PDBAtom) { PDBAtom pdbAtom = (PDBAtom)atom; if (pdbAtom.ResSeq != null && pdbAtom.ResSeq.Length > 0) { sequenceNumber = int.Parse(pdbAtom.ResSeq); } if (pdbAtom.ICode != null && pdbAtom.ICode.Length > 0) { groupInsertionCode = pdbAtom.ICode[0]; } atomName = pdbAtom.Name; group3Name = pdbAtom.ResName; if (pdbAtom.ChainID != null && pdbAtom.ChainID.Length >= 1) { chainID = pdbAtom.ChainID[0]; } } else { atomName = atom.AtomTypeName; } atomsList[atom] = AddAtom(model, atom, elementNumber, atomName, atom.getFormalCharge(), (float)atom.getCharge(), 100, float.NaN, (float)atom.X3d, (float)atom.Y3d, (float)atom.Z3d, false, int.MinValue, chainID, group3Name, sequenceNumber, groupInsertionCode, float.NaN, float.NaN, float.NaN, alternateLocation, null); } } } } //} //catch (Exception e) //{ // throw new ApplicationException("Problem translating atoms", e); //} fileHasHbonds = false; // translate bonds try { for (int seq = 0; seq < chemFile.ChemSequenceCount; seq++) { for (int model = 0; model < chemFile.ChemSequences[seq].ChemModelCount; model++) { Org.OpenScience.CDK.Interfaces.IChemModel chemModel = chemFile.ChemSequences[seq].ChemModels[model]; for (int atomC = 0; atomC < chemModel.SetOfMolecules.AtomContainerCount; atomC++) { for (int bondIdx = 0; bondIdx < chemModel.SetOfMolecules.AtomContainers[atomC].Bonds.Length; bondIdx++) { Org.OpenScience.CDK.Interfaces.IBond bond = chemModel.SetOfMolecules.AtomContainers[atomC].Bonds[bondIdx]; Org.OpenScience.CDK.Interfaces.IAtom[] cdkAtoms = bond.getAtoms(); // locate translated atoms Atom atom1, atom2; atomsList.TryGetValue(cdkAtoms[0], out atom1); atomsList.TryGetValue(cdkAtoms[1], out atom2); bondAtoms(atom1, atom2, (int)bond.Order); } } } } } catch (Exception e) { throw new ApplicationException("Problem translating bonds", e); } atomsList.Clear(); // translate structures of PDBPolymer only for (int seq = 0; seq < chemFile.ChemSequenceCount; seq++) { for (int model = 0; model < chemFile.ChemSequences[seq].ChemModelCount; model++) { Org.OpenScience.CDK.Interfaces.IChemModel chemModel = chemFile.ChemSequences[seq].ChemModels[model]; foreach (Org.OpenScience.CDK.Interfaces.IMolecule molecule in chemModel.SetOfMolecules.Molecules) { if (molecule is PDBPolymer) { PDBPolymer pdbPolymer = (PDBPolymer)molecule; if (pdbPolymer.Structures != null && pdbPolymer.Structures.Count > 0) { structuresDefined = true; foreach (PDBStructure pdbStruct in pdbPolymer.Structures) { structuresDefined = true; mmset.defineStructure(pdbStruct.StructureType, pdbStruct.StartChainID, pdbStruct.StartSequenceNumber, pdbStruct.StartInsertionCode, pdbStruct.EndChainID, pdbStruct.EndSequenceNumber, pdbStruct.EndInsertionCode); } } } } } } autoBond(null, null); // build groups FinalizeGroupBuild(); BuildPolymers(); Freeze(); finalizeBuild(); // create ribbon shapes try { setShapeSize(JmolConstants.SHAPE_RIBBONS, -1, new BitArray(0)); setShapeSize(JmolConstants.SHAPE_CARTOON, -1, new BitArray(0)); } catch (Exception) { } }
/// <summary> /// Creates an <see cref="PDBAtom"/> and sets properties to their values from /// the ATOM or HETATM record. If the line is shorter than 80 characters, the /// information past 59 characters is treated as optional. If the line is /// shorter than 59 characters, a <see cref="ApplicationException"/> is thrown. /// </summary> /// <param name="cLine">the PDB ATOM or HEATATM record.</param> /// <param name="lineLength"></param> /// <returns>the <see cref="PDBAtom"/>created from the record.</returns> /// <exception cref="InvalidDataException">if the line is too short (less than 59 characters).</exception> private PDBAtom ReadAtom(string cLine, int lineLength) { // a line can look like (two in old format, then two in new format): // // 1 2 3 4 5 6 7 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // ATOM 1 O5* C A 1 20.662 36.632 23.475 1.00 10.00 114D 45 // ATOM 1186 1H ALA 1 10.105 5.945 -6.630 1.00 0.00 1ALE1288 // ATOM 31 CA SER A 3 -0.891 17.523 51.925 1.00 28.64 C // HETATM 3486 MG MG A 302 24.885 14.008 59.194 1.00 29.42 MG+2 // // note: the first two examples have the PDBID in col 72-75 // note: the last two examples have the element symbol in col 76-77 // note: the last (Mg hetatm) has a charge in col 78-79 if (lineLength < 59) { throw new InvalidDataException("PDBReader error during ReadAtom(): line too short"); } var isHetatm = cLine.StartsWith("HETATM", StringComparison.Ordinal); var atomName = cLine.Substring(12, 4).Trim(); var resName = cLine.Substring(17, 3).Trim(); var symbol = ParseAtomSymbol(cLine); if (symbol == null) { HandleError($"Cannot parse symbol from {atomName}"); } var oAtom = new PDBAtom(symbol, new Vector3(double.Parse(cLine.Substring(30, 8), NumberFormatInfo.InvariantInfo), double.Parse(cLine.Substring(38, 8), NumberFormatInfo.InvariantInfo), double.Parse(cLine.Substring(46, 8), NumberFormatInfo.InvariantInfo))); if (useHetDictionary.IsSet && isHetatm) { var cdkType = TypeHetatm(resName, atomName); oAtom.AtomTypeName = cdkType; if (cdkType != null) { try { cdkAtomTypeFactory.Configure(oAtom); } catch (CDKException) { Trace.TraceWarning("Could not configure", resName, " ", atomName); } } } oAtom.Record = cLine; oAtom.Serial = int.Parse(cLine.Substring(6, 5).Trim(), NumberFormatInfo.InvariantInfo); oAtom.Name = atomName.Trim(); oAtom.AltLoc = cLine.Substring(16, 1).Trim(); oAtom.ResName = resName; oAtom.ChainID = cLine.Substring(21, 1).Trim(); oAtom.ResSeq = cLine.Substring(22, 4).Trim(); oAtom.ICode = cLine.Substring(26, 1).Trim(); if (useHetDictionary.IsSet && isHetatm) { oAtom.Id = oAtom.ResName + "." + atomName; } else { oAtom.AtomTypeName = oAtom.ResName + "." + atomName; } if (lineLength >= 59) { var frag = cLine.Substring(54, Math.Min(lineLength - 54, 6)).Trim(); if (frag.Length > 0) { oAtom.Occupancy = double.Parse(frag, NumberFormatInfo.InvariantInfo); } } if (lineLength >= 65) { var frag = cLine.Substring(60, Math.Min(lineLength - 60, 6)).Trim(); if (frag.Length > 0) { oAtom.TempFactor = double.Parse(frag, NumberFormatInfo.InvariantInfo); } } if (lineLength >= 75) { oAtom.SegID = cLine.Substring(72, Math.Min(lineLength - 72, 4)).Trim(); } if (lineLength >= 79) { string frag; if (lineLength >= 80) { frag = cLine.Substring(78, 2).Trim(); } else { frag = cLine.Substring(78); } if (frag.Length > 0) { // see Format_v33_A4.pdf, p. 178 if (frag.EndsWithChar('-') || frag.EndsWithChar('+')) { var aa = frag.ToCharArray(); Array.Reverse(aa); oAtom.Charge = double.Parse(new string(aa), NumberFormatInfo.InvariantInfo); } else { oAtom.Charge = double.Parse(frag, NumberFormatInfo.InvariantInfo); } } } // *********************************************************************************** // It sets a flag in the property content of an atom, which is used when // bonds are created to check if the atom is an OXT-record => needs // special treatment. var oxt = cLine.Substring(13, 3).Trim(); if (string.Equals(oxt, "OXT", StringComparison.Ordinal)) { oAtom.Oxt = true; } else { oAtom.Oxt = false; } // ********************************************************************************** return(oAtom); }
/// <summary> Creates an <code>Atom</code> and sets properties to their values from /// the ATOM record. If the line is shorter than 80 characters, the information /// past 59 characters is treated as optional. If the line is shorter than 59 /// characters, a <code>RuntimeException</code> is thrown. /// /// </summary> /// <param name="cLine"> the PDB ATOM record. /// </param> /// <returns> the <code>Atom</code> created from the record. /// </returns> /// <throws> RuntimeException if the line is too short (less than 59 characters). </throws> private PDBAtom readAtom(string cLine, int lineLength) { // a line looks like: // 0 1 2 3 4 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // ATOM 1 O5* C A 1 20.662 36.632 23.475 1.00 10.00 114D 45 // ATOM 1186 1H ALA 1 10.105 5.945 -6.630 1.00 0.00 1ALE1288 if (lineLength < 59) { throw new System.SystemException("PDBReader error during readAtom(): line too short"); } string elementSymbol = cLine.Substring(12, 4).Trim(); if (elementSymbol.Length == 2) { // ensure that the second char is lower case elementSymbol = elementSymbol[0] + elementSymbol.Substring(1).ToLower(); } string rawAtomName = cLine.Substring(12, 4).Trim(); string resName = cLine.Substring(17, 3).Trim(); try { IAtomType type = pdbFactory.getAtomType(resName + "." + rawAtomName); elementSymbol = type.Symbol; } catch (NoSuchAtomTypeException e) { // try 1 char try { elementSymbol = rawAtomName.Substring(0, 1);//pdbFactory.getAtomType(rawAtomName.Substring(0, 1)).Symbol; } catch { elementSymbol = "Xx"; } //System.Console.Out.WriteLine("Did not recognize PDB atom type: " + resName + "." + rawAtomName); } PDBAtom oAtom = new PDBAtom(elementSymbol, new Point3d(System.Double.Parse(cLine.Substring(30, (38) - (30))), System.Double.Parse(cLine.Substring(38, (46) - (38))), System.Double.Parse(cLine.Substring(46, (54) - (46))))); oAtom.Record = cLine; oAtom.Serial = System.Int32.Parse(cLine.Substring(6, 5).Trim()); oAtom.Name = rawAtomName.Trim(); oAtom.AltLoc = cLine.Substring(16, 1).Trim(); oAtom.ResName = resName; oAtom.ChainID = cLine.Substring(21, (22) - (21)).Trim(); oAtom.ResSeq = cLine.Substring(22, (26) - (22)).Trim(); oAtom.ICode = cLine.Substring(26, (27) - (26)).Trim(); oAtom.AtomTypeName = oAtom.ResName + "." + rawAtomName; if (lineLength >= 59) { string frag = cLine.Substring(54, (60) - (54)).Trim(); if (frag.Length > 0) { oAtom.Occupancy = System.Double.Parse(frag); } } if (lineLength >= 65) { string frag = cLine.Substring(60, (66) - (60)).Trim(); if (frag.Length > 0) { oAtom.TempFactor = System.Double.Parse(frag); } } if (lineLength >= 75) { oAtom.SegID = cLine.Substring(72, (76) - (72)).Trim(); } // if (lineLength >= 78) { // oAtom.setSymbol((new String(cLine.substring(76, 78))).trim()); // } if (lineLength >= 79) { string frag = cLine.Substring(78, (80) - (78)).Trim(); if (frag.Length > 0) { oAtom.setCharge(System.Double.Parse(frag)); } } /************************************************************************************* * It sets a flag in the property content of an atom, * which is used when bonds are created to check if the atom is an OXT-record => needs * special treatment. */ string oxt = cLine.Substring(13, (16) - (13)).Trim(); if (oxt.Equals("OXT")) { oAtom.Oxt = true; } else { oAtom.Oxt = false; } /*************************************************************************************/ return(oAtom); }
/// <summary> Create bonds when reading a protein PDB file. NB ONLY works for protein /// PDB files! If you want to read small molecules I recommend using molecule /// file format where the connectivity is explicitly stated. [This method can /// however reasonably easily be extended to cover e.g. nucleic acids or your /// favourite small molecule]. Returns 'false' if bonds could not be created /// due to incomplete pdb-records or other reasons. /// /// </summary> /// <param name="pol">The Biopolymer to work on /// </param> public virtual bool createBonds(IBioPolymer pol) { //UPGRADE_TODO: Class 'java.util.HashMap' was converted to 'System.Collections.Hashtable' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilHashMap'" System.Collections.Hashtable AAs = AminoAcids.HashMapByThreeLetterCode; int[][] AABondInfo = AminoAcids.aaBondInfo(); System.Collections.Hashtable strands = pol.Strands; System.Collections.IEnumerator strandKeys = strands.Keys.GetEnumerator(); //UPGRADE_TODO: Method 'java.util.Enumeration.hasMoreElements' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationhasMoreElements'" while (strandKeys.MoveNext()) { //UPGRADE_TODO: Method 'java.util.Enumeration.nextElement' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilEnumerationnextElement'" IStrand strand = (IStrand)strands[strandKeys.Current]; int atoms = 0; int atomsInLastResidue = 0; int atomsInPresentResidue = 0; while (atoms < strand.AtomCount - 1) { PDBAtom anAtom = (PDBAtom)strand.getAtomAt(atoms); // Check that we have bond info about residue/ligand, if not - exit. if (!AAs.ContainsKey(anAtom.ResName)) { return(false); } //UPGRADE_TODO: Method 'java.util.HashMap.get' was converted to 'System.Collections.Hashtable.Item' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilHashMapget_javalangObject'" IMonomer monomer = (IMonomer)AAs[anAtom.ResName]; atomsInPresentResidue = System.Int32.Parse((string)monomer.getProperty(AminoAcids.NO_ATOMS)); /* Check if there's something wrong with the residue record (e.g. it doesn't contain the * correct number of atom records). */ int counter = 1; while (atoms + counter < strand.AtomCount && anAtom.ResName.Equals(strand.getAtomAt(atoms + counter).getProperty(AminoAcids.RESIDUE_NAME))) { counter++; } // Check if something is wrong. Remember to deal with possible OXT atom... if (counter % atomsInPresentResidue != 0 && (atoms + counter == strand.AtomCount && counter % atomsInPresentResidue != 1)) { return(false); } // If nothing's wrong, add bonds int bondID = System.Int32.Parse((string)monomer.getProperty(AminoAcids.ID)); for (int l = 0; l < System.Int32.Parse((string)monomer.getProperty(AminoAcids.NO_BONDS)); l++) { IBond bond = pol.Builder.newBond(strand.getAtomAt(AABondInfo[bondID + l][1] + atoms), strand.getAtomAt(AABondInfo[bondID + l][2] + atoms), (double)(AABondInfo[bondID + l][3])); pol.addBond(bond); } // If not first residue, connect residues if (atomsInLastResidue != 0) { IBond bond = pol.Builder.newBond(strand.getAtomAt(atoms - atomsInLastResidue + 2), strand.getAtomAt(atoms), 1); pol.addBond(bond); } atoms = atoms + atomsInPresentResidue; atomsInLastResidue = atomsInPresentResidue; // Check if next atom is an OXT. The reason to why this is seemingly overly complex is because // not all PDB-files have ending OXT. If that were the case you could just check if // atoms == mol.getAtomCount()... if (strand.AtomCount < atoms && ((PDBAtom)strand.getAtomAt(atoms)).Oxt) { // if(strand.getAtomCount() < atoms && ((String)strand.getAtomAt(atoms).getProperty("oxt")).equals("1")) { IBond bond = pol.Builder.newBond(strand.getAtomAt(atoms - atomsInLastResidue + 2), strand.getAtomAt(atoms), 1); pol.addBond(bond); } } } return(true); }