public void parsePDB() { // for determining hydrogen bonds List <Vector3> hBondAcceptors = new List <Vector3> (); List <Vector3> hBondDonors = new List <Vector3> (); parseMol: // iteration start if multiple input files are used BezierSpline[] ribbonSplineList = new BezierSpline[30]; //for drawing protein lines (30 is max number of chains) int numAtoms = (int)mol.NumAtoms() + 1; atoms = new GameObject[numAtoms]; int maxHelix = 500; radius = new float[maxHelix, numAtoms]; int ribbonChainIndex = 0; OBElementTable table = new OBElementTable(); int currentChain = -1; OBAtom[] alphaCarbons = new OBAtom[numAtoms / 4]; int alphaCarbonCount = 0; List <Vector3> atomPositions = new List <Vector3> (); List <string> atomElements = new List <string> (); for (int i = 1; i < numAtoms; i++) { OBAtom atom = mol.GetAtom(i); string tag; OBResidue res = atom.GetResidue(); Vector3 position = new Vector3((float)atom.GetX(), (float)atom.GetY(), (float)atom.GetZ()); string elem = table.GetSymbol((int)atom.GetAtomicNum()).ToUpper(); //checks for pharmacophore labels if (res.GetName() == "ACC" || res.GetName() == "FOB" || res.GetName() == "POS" || res.GetName() == "NEG" || res.GetName() == "RNG" || res.GetName() == "DON") { if (atom.IsHydrogen()) //added hydrogens gets the same resName and has to be ignored { continue; } renderPharmacophore = true; } else { renderPharmacophore = false; } // pharmacophores if (res.GetName() == "EXC") { if (atom.IsHydrogen()) //added hydrogens gets the same resName and has to be ignored { continue; } renderEXC = true; renderPharmacophore = true; } else { renderEXC = false; } //creates the atom object atoms[i] = createAtomType(elem, position); int n; if (int.TryParse(res.GetName(), out n)) { if (CollectionOfLigands == null) { CollectionOfLigands = new List <List <GameObject> >(); CollectionOfLigands.Add(new List <GameObject>()); } while (n + 1 > CollectionOfLigands.Count) { CollectionOfLigands.Add(new List <GameObject>()); } CollectionOfLigands[n].Add(atoms[i]); } if (res.GetResidueProperty(9)) //water { tag = "water"; } else if (res.GetAtomProperty(atom, 4) || (atom.IsHydrogen() && !res.GetResidueProperty(5))) //ligand { if (res.GetResidueProperty(5)) //ion (should be 3 but a bug in openbabel labels ions as protein, thats why the check has to be done inside the ligand check) { tag = "ion"; } else { TextMesh lText = atoms [i].transform.Find("Text").GetComponent <TextMesh> (); lText.color = textColor; if (renderPharmacophore) { tag = "hetatms"; //make sure pharmacophores always show lText.text = res.GetName() + ":" + res.GetIdx(); lText.fontSize = labelFontSize; } else { tag = "hetatmbs"; if (ligandText) { lText.text = elem + ":" + i.ToString(); lText.fontSize = labelFontSize; } } if (sphere) { atoms [i].transform.localScale *= 4; } if (atom.IsHbondAcceptor()) { foreach (Vector3 candidatePos in hBondDonors) { checkHBond(candidatePos, position); } } if (atom.IsHbondDonor()) { foreach (Vector3 candidatePos in hBondAcceptors) { checkHBond(candidatePos, position); } } } } else //protein { tag = "balls"; atomPositions.Add(position); atomElements.Add(elem); if (atom.IsHbondAcceptor()) { hBondAcceptors.Add(position); } else { hBondDonors.Add(position); } if (res.GetAtomProperty(atom, 0)) //alpha carbon { alphaCarbons[alphaCarbonCount] = atom; if (alphaCarbonCount > 6) //check if the ribbon is alpha helix using torsion angles { double torsion = mol.GetTorsion(atom, alphaCarbons[alphaCarbonCount - 1], alphaCarbons[alphaCarbonCount - 2], alphaCarbons[alphaCarbonCount - 3]); double prevTorsion = mol.GetTorsion(alphaCarbons[alphaCarbonCount - 4], alphaCarbons[alphaCarbonCount - 5], alphaCarbons[alphaCarbonCount - 6], alphaCarbons[alphaCarbonCount - 7]); double torsionSum = torsion + prevTorsion; if (torsionSum > 99 && torsionSum < 111) { for (int j = ribbonChainIndex - 7; j <= ribbonChainIndex; j++) { radius [currentChain, j] = 1.5f; //alpha helix } } else { radius [currentChain, ribbonChainIndex] = 0.5f; } } alphaCarbonCount++; if (proteinText) //only displays text on alpha carbons { TextMesh pText = atoms [i].transform.Find("Text").GetComponent <TextMesh> (); pText.color = textColor; pText.text = res.GetName() + " -" + res.GetNumString(); pText.fontSize = labelFontSize; } int tempChain = (int)res.GetChainNum(); if (tempChain != currentChain) { currentChain = tempChain; ribbonChainIndex = 0; } //add points for ribbon rendering addBezierPoint(ribbonSplineList, currentChain, ribbonChainIndex, position); ribbonChainIndex++; } } atoms[i].transform.tag = tag; centerPos += position; centerCount++; } //createSurface (atomPositions,atomElements); Debug.Log(hBondAcceptors.Count + " " + hBondDonors.Count); //evaluate bonds for (int i = 0; i < mol.NumBonds(); i++) { OBBond bond = mol.GetBond(i); OBAtom atom = mol.GetAtom((int)bond.GetBeginAtomIdx()); OBResidue res = atom.GetResidue(); bool ligand = res.GetAtomProperty(atom, 4) || (atom.IsHydrogen() && !res.GetResidueProperty(5)); if (ligand && sphere) //no ligand bonds if display mode is CPK sphere { continue; } try { connect(atoms[bond.GetBeginAtomIdx()], atoms[bond.GetEndAtomIdx()], bond); } catch (System.Exception e) { Debug.Log(e); } } //handle pharmacophore vectors if (mol.HasData("VECTOR")) { string[] vectors = mol.GetData("VECTOR").GetValue().Split(new string[] { "\n" }, StringSplitOptions.None); foreach (string vector in vectors) { string[] idx = vector.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); try { Vector3 pos = new Vector3(float.Parse(idx[1]), float.Parse(idx[2]), float.Parse(idx[3])); int id = int.Parse(idx[0]); drawVector(atoms[id], pos, mol.GetAtom(id).GetResidue().GetName()); } catch (System.Exception e) { Debug.Log(e); } } } //render protein ribbons drawRibbons(ribbonSplineList, "ribbons"); //must be before alpha due to indexing drawRibbons(ribbonSplineList, "alpha"); // check for separate ligand file if (file.Contains("protein")) { file = file.Replace("protein", "ligand"); string file1 = file.Replace("." + extension, ".sdf"); // .+extension incase the format would also appear in the file name string file2 = file.Replace("." + extension, ".mol2"); if (File.Exists(file1)) { readMol(file); goto parseMol; } else if (File.Exists(file2)) { readMol(file); goto parseMol; } } center = createObject(new GameObject(), centerPos / centerCount); //the center of the pdb show(); }
public static OBMol addmol(OBMol source, OBMol dest) { //combines two OBMols into one molecule // this is designed to do the same thing as the += operator in mol.cpp, in other words this implements functionality present in openbabel, but not in the C# api dest.BeginModify(); uint prevatms = dest.NumAtoms(); uint nextatms = source.NumAtoms(); // First, handle atoms and bonds foreach (OBAtom atom in source.Atoms()) { atom.SetId(0); ////Need to remove ID which relates to source mol rather than this mol// But in the C++ it had a NoId thing I couldn't figure out dest.AddAtom(atom); //var foooo = dest.Atoms (); } //writeatominfotoscreen (dest); foreach (OBBond bond in source.Bonds()) { bond.SetId(0); dest.AddBond((int)(bond.GetBeginAtomIdx() + prevatms), (int)(bond.GetEndAtomIdx() + prevatms), (int)bond.GetBO(), (int)bond.GetFlags()); } //don't really understand what they mean by residues //I think it's an amino acid or nucleotide so you can build up proteins and stuff? //don't think I'm going to use them either, but it might be useful foreach (OBResidue residue in source.Residues()) { OBResidue newres = new OBResidue(); dest.AddResidue(newres); OBResidueAtomIter ai = new OBResidueAtomIter(residue); //dammit why didn't they implement a residue.atoms sort of thing? I don't want to play with enumerators ////#define FOR_ATOMS_OF_RESIDUE(a,r) for( OBResidueAtomIter a(r); a; ++a ) while (ai.MoveNext()) { OBAtom resatom = new OBAtom(); resatom = ai.Current; // This is the equivalent atom in our combined molecule OBAtom atom = dest.GetAtom((int)(resatom.GetIdx() + prevatms)); // So we add this to the last-added residue // (i.e., what we just copied) //[dest.NumResidues () - 1] var res = dest.Residues().GetEnumerator(); while (!res.MoveNext()) { } //move to the last residue res.Current.AddAtom(atom); //var item = dest.Cast<RMSRequestProcessor.RMSMedia> ().ElementAt (1); } //for(OBAtom resatom in ) } dest.EndModify(); return(dest); }