/// <summary> /// Determines the principle quantum number of an atom /// </summary> /// <param name="atom"></param> /// <returns></returns> public static int PrincipleQuantumNumber(this OBAtom atom) { var atomicNumber = atom.GetAtomicNum(); if (atomicNumber <= 2) { return(1); } if (atomicNumber <= 10) { return(2); } if (atomicNumber <= 18) { return(3); } if (atomicNumber <= 36) { return(4); } if (atomicNumber <= 54) { return(5); } if (atomicNumber <= 86) { return(6); } return(7); }
/// <summary> /// Retrieves the RCov value for atom /// </summary> /// <param name="atom"></param> /// <returns></returns> public static double GetRBO(this OBAtom atom) { var index = atom.GetAtomicNum(); if (index >= AtomicConstants.GetLength()) { throw new IndexOutOfRangeException(string.Format("GetRBO: {0} is out of range", index)); } return(AtomicConstants.GetRBO(index)); }
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(); }
/// <summary> /// Determines the possible Crippen atom type for the OBAtom object /// </summary> /// <param name="atom"></param> /// <returns>Crippen atom type as string if found, otherwise empty string</returns> private static string GetCrippenAtomType(this OBAtom atom) { var partialCharge = Convert.ToInt32(atom.GetPartialCharge()); var atomicNumber = atom.GetAtomicNum(); if (partialCharge != 0) { if (atomicNumber == 9 || atomicNumber == 17 || atomicNumber == 35 || atomicNumber == 53 || atomicNumber == 3 || atomicNumber == 11 || atomicNumber == 19 || atomicNumber == 37 || atomicNumber == 55) { return("Ha"); } } else { if (atomicNumber == 6) { return("C"); } if (atomicNumber == 1) { return("H"); } if (atomicNumber == 7) { return("N"); } if (atomicNumber == 8) { return("O"); } if (atomicNumber == 15) { return("P"); } if (atomicNumber == 16) { return("S"); } if (atomicNumber == 9) { return("F"); } if (atomicNumber == 17) { return("Cl"); } if (atomicNumber == 35) { return("Br"); } if (atomicNumber == 53) { return("I"); } if ((atomicNumber >= 21 && atomicNumber <= 30) || (atomicNumber >= 39 && atomicNumber <= 48) || (atomicNumber >= 72 && atomicNumber <= 80) || atomicNumber == 3 || atomicNumber == 4 || atomicNumber == 5 || atomicNumber == 11 || atomicNumber == 12 || atomicNumber == 13 || atomicNumber == 14 || atomicNumber == 19 || atomicNumber == 20 || atomicNumber == 31 || atomicNumber == 32 || atomicNumber == 33 || atomicNumber == 34 || atomicNumber == 37 || atomicNumber == 38 || atomicNumber == 49 || atomicNumber == 50 || atomicNumber == 51 || atomicNumber == 52 || atomicNumber == 55 || atomicNumber == 56 || atomicNumber == 81 || atomicNumber == 82 || atomicNumber == 83 || atomicNumber == 84) { return("Me"); } } return(string.Empty); }
/// <summary> /// Calculates the number of atoms in the outermost shell /// </summary> /// <param name="atom"></param> /// <returns>int</returns> public static int NOuterShellElectrons(this OBAtom atom) { return(AtomicConstants.GetOuterShellElectrons(atom.GetAtomicNum())); }
/// <summary> /// Retrieves first relevant atom type based on SMARTS pattern that matches atom /// </summary> /// <param name="atom"></param> /// <returns>Crippen Atom Type key if atom matches a pattern, otherwise empty string.</returns> public static string GetCrippenKey(this OBAtom atom) { var element = atom.GetCrippenAtomType(); if (string.IsNullOrEmpty(element)) { throw new Exception(string.Format("Crippen atom type could not be determined for {0}", atom.GetAtomicNum())); } var keys = CrippenConstants.CrippenContributions.Where(g => g.Key.Contains(element)).Select(g => g.Key); foreach (var key in keys) { foreach (var pattern in CrippenConstants.GetSmarts(key)) { if (atom.MatchesSMARTS(pattern)) { return(key); } } } return(string.Empty); }
public MolStat GetMolStat() { /* 统计原子 */ uint _numAtoms = mol.NumAtoms(); //所有原子总数 uint _numHvyAtoms = mol.NumHvyAtoms(); //所有除去氢原子的原子总数 int _totalCharge = mol.GetTotalCharge(); //总电荷数 int n_C = 0; // number of carbon atoms 碳原子总数 int n_C1 = 0; // number of carbon atoms with sp1 hybridization sp1杂化的碳原子数 int n_C2 = 0; // number of carbon atoms with sp1 hybridization sp2杂化的碳原子数 int n_CHB1p = 0; // number of carbon atoms with at least 1 bond to a hetero atom 至少连接一个杂原子的碳原子数 int n_CHB2p = 0; // number of carbon atoms with at least 2 bonds to a hetero atom 至少连接两个个杂原子的碳原子数 int n_CHB3p = 0; // number of carbon atoms with at least 3 bonds to a hetero atom 至少连接三个杂原子的碳原子数 int n_CHB4 = 0; // number of carbon atoms with 4 bonds to a hetero atom 连接了4个杂原子的碳原子数 int n_O = 0; // number of oxygen atoms 氧原子数 int n_O2 = 0; // number of sp2-hybridized oxygen atoms sp2杂化的氧原子数 int n_O3 = 0; // number of sp3-hybridized oxygen atoms sp3杂化的氧原子数 int n_N = 0; // number of nitrogen atoms 氮原子数 int n_N1 = 0; // number of sp-hybridized nitrogen atoms sp杂化的氮原子数 int n_N2 = 0; // number of sp2-hybridized nitrogen atoms sp2杂化的氮原子数 int n_N3 = 0; // number of sp3-hybridized nitrogen atoms sp3杂化的氮原子数 int n_S = 0; // number of sulfur atoms 硫原子数 int n_SeTe = 0; // total number of selenium and tellurium atoms 硒和碲原子的数目 int n_F = 0; // number of fluorine atoms 氟原子的数目 int n_Cl = 0; // number of chlorine atoms 氯原子的数目 int n_Br = 0; // number of bromine atoms 溴原子的数目 int n_I = 0; // number of iodine atoms 碘原子的数目 int n_P = 0; // number of phosphorus atoms 磷原子的数目 int n_B = 0; // number of boron atoms 硼原子的数目 int n_Met = 0; // total number of metal atoms 金属原子的数目 int n_X = 0; // total number of "other" atoms (not listed above) and halogens 其他原子的数目,除了以上列出的之外。 for (int i = 1; i <= _numAtoms; i++) { OBAtom _atom = mol.GetAtom(i); uint _AtomicNum = _atom.GetAtomicNum(); //原子种类,周期表序号 uint _hyb = _atom.GetHyb(); //原子的杂化形态,1 for sp1, 2 for sp2, 3 for sp3 uint _HeteroValence = _atom.GetHeteroValence(); //连接在这个原子上杂(非氢,碳)原子的数目 //uint _HeteroValence = _atom.GetHeteroDegree(); //For openbabel 3.0 if (_AtomicNum == 6) //碳原子 { n_C++; switch (_hyb) { case 1: n_C1++; break; case 2: n_C2++; break; default: break; } if (_HeteroValence >= 4) { n_CHB4++; } if (_HeteroValence >= 3) { n_CHB3p++; } if (_HeteroValence >= 2) { n_CHB2p++; } if (_HeteroValence >= 1) { n_CHB1p++; } } else if (_AtomicNum == 8) { n_O++; switch (_hyb) { case 2: n_O2++; break; case 3: n_O3++; break; default: break; } } else if (_AtomicNum == 7) { n_N++; switch (_hyb) { case 1: n_N1++; break; case 2: n_N2++; break; case 3: n_N3++; break; default: break; } } else if (_AtomicNum == 16) { n_S++; } else if (_AtomicNum == 34 || _AtomicNum == 52) { n_SeTe++; } else if (_AtomicNum == 9) { n_F++; } else if (_AtomicNum == 17) { n_Cl++; } else if (_AtomicNum == 35) { n_Br++; } else if (_AtomicNum == 53) { n_I++; } else if (_AtomicNum == 15) { n_P++; } else if (_AtomicNum == 5) { n_B++; } else if ((_AtomicNum >= 3 && _AtomicNum <= 4) || (_AtomicNum >= 11 && _AtomicNum <= 13) || (_AtomicNum >= 19 && _AtomicNum <= 32) || (_AtomicNum >= 37 && _AtomicNum <= 51) || (_AtomicNum >= 55 && _AtomicNum <= 84) || (_AtomicNum >= 87)) { n_Met++; } } n_X = (int)_numHvyAtoms - n_B - n_C - n_Met - n_N - n_O - n_P - n_S - n_SeTe; /* 统计化学键 */ uint _numBonds = mol.NumBonds(); //所有化学键的总数 int n_b1 = 0; // number of single bonds 单键的个数 int n_b1_NoH = 0; // number of none C-H single bonds 不含氢的单键个数 int n_b2 = 0; // number of double bonds 双键的个数 int n_b3 = 0; // number of triple bonds 三键的个数 int n_bar = 0; // number of aromatic bonds 芳香键的个数 int n_C1O = 0; // number of C-O single bonds 碳-氧单键的个数 int n_C2O = 0; // number of C=O double bonds 碳=氧双键的个数 int n_CN = 0; // number of C/N bonds (any type) 任何类型的碳氮键的个数 int n_XY = 0; // number of heteroatom/heteroatom bonds (any type) 任何类型的杂原子之间化学健的个数 for (int i = 0; i < _numBonds; i++) { OBBond _bond = mol.GetBond(i); OBAtom _beginAtom = _bond.GetBeginAtom(); OBAtom _endAtom = _bond.GetEndAtom(); uint _beginAtomAtomicNum = _beginAtom.GetAtomicNum(); uint _endAtomAtomicNum = _endAtom.GetAtomicNum(); if (_bond.IsSingle()) //Replace IsSingle() method in Openbabel 3.0 { n_b1++; if (_beginAtomAtomicNum != 1 && _endAtomAtomicNum != 1) { n_b1_NoH++; } } else if (_bond.IsDouble()) // Replace IsDouble() method in Openbabel 3.0 { n_b2++; } else if (_bond.IsTriple()) // Replace IsTriple() method in Openbabel 3.0 { n_b3++; } else if (_bond.IsAromatic()) { n_bar++; } if ((_beginAtomAtomicNum == 6 && _endAtomAtomicNum == 8) || (_beginAtomAtomicNum == 8 && _endAtomAtomicNum == 6)) { uint _bondOrder = _bond.GetBondOrder(); if (_bondOrder == 1) { n_C1O++; } else if (_bondOrder == 2) { n_C2O++; } } else if ((_beginAtomAtomicNum == 6 && _endAtomAtomicNum == 7) || (_beginAtomAtomicNum == 7 && _endAtomAtomicNum == 6)) { n_CN++; } else if (_beginAtomAtomicNum != 6 && _endAtomAtomicNum != 6) { n_XY++; } } /* 统计环 */ #region 统计环 VectorpRing _SSSR = mol.GetSSSR(); int n_r3 = 0; // number of 3-membered rings 3元环个数 int n_r4 = 0; // number of 4-membered rings 4元环个数 int n_r5 = 0; // number of 5-membered rings 5元环个数 int n_r6 = 0; // number of 6-membered rings 6元环个数 int n_r7 = 0; // number of 7-membered rings 7元环个数 int n_r8 = 0; // number of 8-membered rings 8元环个数 int n_r9 = 0; // number of 9-membered rings 9元环个数 int n_r10 = 0; // number of 10-membered rings 10元环个数 int n_r11 = 0; // number of 11-membered rings 11元环个数 int n_r12 = 0; // number of 12-membered rings 12元环个数 int n_r13p = 0; // number of 13-membered or larger rings 13元环或者更大的环的个数 int n_rN = 0; // number of rings containing nitrogen (any number) 含氮环的个数 int n_rN1 = 0; // number of rings containing 1 nitrogen atom 含一个氮原子的环的个数 int n_rN2 = 0; // number of rings containing 2 nitrogen atoms 含两个个氮原子的环的个数 int n_rN3p = 0; // number of rings containing 3 or more nitrogen atoms 含三个或以上个氮原子的环的个数 int n_rO = 0; // number of rings containing oxygen (any number) 含氧环的个数 int n_rO1 = 0; // number of rings containing 1 oxygen atom 含一个氧原子的环的个数 int n_rO2p = 0; // number of rings containing 2 or more oxygen atoms 含三个或以上个氧原子的环的个数 int n_rS = 0; // number of rings containing sulfur (any number) 含硫环的个数 int n_rX = 0; // number of heterocycles (any type) 杂环的个数 int n_rar = 0; // number of aromatic rings (any type) 芳香环的个数 if (_SSSR.Count != 0 || _SSSR != null) { foreach (OBRing _ring in _SSSR) { uint _ringSize = _ring.Size(); if (_ringSize == 3) { n_r3++; } else if (_ringSize == 4) { n_r4++; } else if (_ringSize == 5) { n_r5++; } else if (_ringSize == 6) { n_r6++; } else if (_ringSize == 7) { n_r7++; } else if (_ringSize == 8) { n_r8++; } else if (_ringSize == 9) { n_r9++; } else if (_ringSize == 10) { n_r10++; } else if (_ringSize == 11) { n_r11++; } else if (_ringSize == 12) { n_r12++; } else if (_ringSize >= 13) { n_r13p++; } if (_ring.IsAromatic()) { n_rar++; } VectorInt _pathes = _ring._path; int _ct_N = 0; int _ct_O = 0; int _ct_S = 0; bool _isRingX = false; foreach (int _p in _pathes) { OBAtom _atom = mol.GetAtom(_p); uint _AtomicNum = _atom.GetAtomicNum(); if (_AtomicNum == 7) //N原子 { _ct_N++; } else if (_AtomicNum == 8) //O原子 { _ct_O++; } else if (_AtomicNum == 16) //S原子 { _ct_S++; } if (_AtomicNum != 6) { _isRingX = true; } } if (_ct_N == 1) { n_rN1++; } else if (_ct_N == 2) { n_rN2++; } else if (_ct_N >= 3) { n_rN3p++; } n_rN = n_rN1 + n_rN2 + n_rN3p; if (_ct_O == 1) { n_rO1++; } else if (_ct_O >= 2) { n_rO2p++; } n_rO = n_rO1 + n_rO2p; if (_ct_S >= 1) { n_rS++; } if (_isRingX) { n_rX++; } } } #endregion // 统计数字映射成MolStat对象 MolStat stat = new MolStat { // General info AtomsCount = (int)_numAtoms, HeavyAtomsCount = (int)_numHvyAtoms, TotalCharge = _totalCharge, // Atoms info N_B = n_B, N_Br = n_Br, N_C = n_C, N_C1 = n_C1, N_C2 = n_C2, N_CHB1p = n_CHB1p, N_CHB2p = n_CHB2p, N_CHB3p = n_CHB3p, N_CHB4 = n_CHB4, N_Cl = n_Cl, N_F = n_F, N_I = n_I, N_Met = n_Met, N_N = n_N, N_N1 = n_N1, N_N2 = n_N2, N_N3 = n_N3, N_O = n_O, N_O2 = n_O2, N_O3 = n_O3, N_P = n_P, N_S = n_S, N_SeTe = n_SeTe, N_X = n_X, // Bonds info BondsCount = (int)_numBonds, N_b1 = n_b1, N_b1_NoH = n_b1_NoH, N_b2 = n_b2, N_b3 = n_b3, N_bar = n_bar, N_C1O = n_C1O, N_C2O = n_C2O, N_CN = n_CN, N_XY = n_XY, // Rings info RingsCount = _SSSR.Count, N_r10 = n_r10, N_r11 = n_r11, N_r12 = n_r12, N_r13p = n_r13p, N_r3 = n_r3, N_r4 = n_r4, N_r5 = n_r5, N_r6 = n_r6, N_r7 = n_r7, N_r8 = n_r8, N_r9 = n_r9, N_rar = n_rar, N_rN = n_rN, N_rN1 = n_rN1, N_rN2 = n_rN2, N_rN3p = n_rN3p, N_rO = n_rO, N_rO1 = n_rO1, N_rO2p = n_rO2p, N_rS = n_rS, N_rX = n_rX }; return(stat); }