public static OBMol molecule_merge(OBMol mol1, OBAtom a, OBMol mol2, OBAtom b) { //takes two molecules and two atoms in each molecule and //assuming atoms are in the same place, delete one atom and copy bond to the other //a //foreach(OBBond bond in b.Bonds()) //{ //} int keepid = Convert.ToInt32(a.GetIdx()); int todeleteid = Convert.ToInt32(b.GetIdx()); //var bonds = b.Bonds(); List <OBBond> bondlist = new List <OBBond>(); foreach (OBBond bon in b.Bonds()) { bondlist.Add(bon); } OBBond bond = bondlist[0]; int connectid = (int)bond.GetNbrAtomIdx(b); int prevatms = (int)mol1.NumAtoms(); //number of atoms before we combine things //OBMol mol3 = new OBMol (); mol1 = addmol(mol2, mol1); mol1.BeginModify(); OBAtom keep = mol1.GetAtom(keepid); OBAtom todelete = mol1.GetAtom(todeleteid + prevatms); OBAtom toconnect = mol1.GetAtom(connectid + prevatms); OBBond newbond = new OBBond(); newbond.SetBegin(keep); newbond.SetEnd(toconnect); newbond.SetBO(1); mol1.AddBond(newbond); mol1.DeleteAtom(todelete); //OBAtom= atom1 //var a = map2[0]; //int c1 = (int)(map1[1]); //int c2 = (int)(map2[1] + prevatms); //int h1 = (int)(map1[0]); ///int h2 = (int)(map2[0] + prevatms); //OBAtom carbon1 = mol1.GetAtom(c1); //OBAtom carbon2 = mol1.GetAtom(c2); //OBAtom hydrogen1 = mol1.GetAtom(h1); ///OBAtom hydrogen2 = mol1.GetAtom(h2); //OBBuilder.Connect(mol1, c1, c2);//connect fragments //mol1.DeleteAtom(hydrogen1); //mol1.DeleteAtom(hydrogen2); mol1.EndModify(); return(mol1); }
public static OBMol addmol2(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 //modifies atom and bond indices in the process //dest.BeginModify(); uint prevatms = dest.NumAtoms(); uint nextatms = source.NumAtoms(); uint acount = prevatms; uint bcount = dest.NumBonds(); // First, handle atoms and bonds foreach (OBAtom atom in source.Atoms()) { atom.SetId(acount); ////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); acount++; //var foooo = dest.Atoms (); } //writeatominfotoscreen (dest); foreach (OBBond bond in source.Bonds()) { bond.SetId(bcount); OBBond b = new OBBond(); //b.SetBegin(dest.GetAtom((int)(bond.GetBeginAtomIdx() + prevatms))); //b.SetEnd(dest.GetAtom((int)(bond.GetEndAtomIdx() + prevatms))); b.Set(0, dest.GetAtom((int)(bond.GetBeginAtomIdx() + prevatms)), dest.GetAtom((int)(bond.GetEndAtomIdx() + prevatms)), (int)bond.GetBO(), (int)bond.GetFlags()); if (bond.HasData("trueBO")) { b.CloneData(bond.GetData("trueBO")); //clone true bond order so we can eventually do MOF-UFF } dest.AddBond(b); //dest.AddBond( (int)bond.GetBO(), (int)bond.GetFlags()); bcount++; } //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 //dest.EndModify(); this tends to mangle up all the atom ids, which is bad return(dest); }
//creates atom bonds void connect(GameObject atom1, GameObject atom2, OBBond bondInfo) { string tag; if (atom1.transform.tag == "hetatmbs") { tag = "hetatms"; } else if (atom1.transform.tag == "water") { return; } else { tag = "bonds"; } Material atom1Mat = atom1.GetComponent <Renderer> ().material; Material atom2Mat = atom2.GetComponent <Renderer> ().material; if (atom1Mat.HasProperty("_TintColor") || atom2Mat.HasProperty("_TintColor")) //skips bonds to pharmacophores { return; } GameObject bind; if (bondInfo.IsSingle() && ((hetatmStick && tag == "hetatms") || (stick && tag == "bonds"))) { bind = createObject(sticks, Vector3.zero); } else //lines { if (bondInfo.IsDouble()) { bind = createObject(doubleBinding, Vector3.zero); } else if (bondInfo.IsTriple()) { bind = createObject(trippleBinding, Vector3.zero); } else if (bondInfo.IsAromatic()) { bind = createObject(aromatic, Vector3.zero); } else { bind = createObject(binding, Vector3.zero); //single bond } } //make the binding as long as the distance bind.transform.localScale = new Vector3(bind.transform.localScale.x, bind.transform.localScale.y, Vector3.Distance(atom1.transform.position, atom2.transform.position)); bind.transform.position = (atom1.transform.position + atom2.transform.position) / 2.0f; //place the binding between the atoms bind.transform.LookAt(atom1.transform.position); //rotate the binding to face the atoms bind.gameObject.tag = tag; if (CollectionOfLigands != null) { for (int i = 0; i < CollectionOfLigands.Count; i++) { for (int j = 0; j < CollectionOfLigands[i].Count; j++) { if (CollectionOfLigands[i][j] == atom2) { CollectionOfLigands[i].Add(bind); } } } } Renderer[] renderers = bind.GetComponentsInChildren <Renderer> (); //color the binding according to atom type for (int i = 0; i < renderers.Length; i++) // different amount of bonds depending on order { if (i % 2 == 0) { renderers [i].sharedMaterial = atom1Mat; } else { renderers [i].sharedMaterial = atom2Mat; } } }
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 bool IsTriple(this OBBond bond) { return(bond.GetBondOrder() == 3); }
public static bool IsDouble(this OBBond bond) { return(bond.GetBondOrder() == 2); }
public static bool IsSingle(this OBBond bond) { return(bond.GetBondOrder() == 1); }
/// <summary> /// A variant which returns an OBMol based on host. /// </summary> /// <param name="host"></param> /// <returns></returns> public static OBMol designgraphtomol(designGraph host) { OBElementTable periodictable = new OBElementTable(); var mol = new OBMol(); Dictionary <string, int> nodeatomlookup = new Dictionary <string, int>(); //dictionary for looking up which nodes go to which atoms by their names int i = 0; foreach (node n in host.nodes) { OBAtom atom = new OBAtom(); double x = scale * n.X; double y = scale * n.Y; double z = scale * n.Z; //set coordinates of atom atom.SetVector(x, y, z); int anum = 0; n.localLabels.Sort(); foreach (string label in n.localLabels) { if (label.Length < 4) { if (label != "sp2" && label != "sp3") ///so openbabel gets less crap { anum = periodictable.GetAtomicNum(label); if (anum > 0) { break; } } } } i++; atom.SetAtomicNum(anum); //set atomic number nodeatomlookup.Add(n.name, i); //add the atom to dictionary and mol mol.AddAtom(atom); } foreach (arc a in host.arcs) { OBBond bond = new OBBond(); int bondorder = 0; bool hassingle = a.localLabels.Contains("s"); bool hasdouble = a.localLabels.Contains("d"); bool hastriple = a.localLabels .Contains("t"); //bonds will probably not be anything other than single, double, or triple //although we could have dative bonds if (hassingle ^ hasdouble ^ hastriple) //we do not want more than one bond type { if (hassingle) { bondorder = 1; } if (hasdouble) { bondorder = 2; } if (hastriple) { bondorder = 3; } } mol.AddBond(nodeatomlookup[a.To.name], nodeatomlookup[a.From.name], bondorder); } return(mol); }
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); }