/// <summary> /// return the overlapped leaf nodes /// </summary> /// <param name="extTree"></param> /// <returns></returns> public void Intersect(BVTree treeA, BVTree treeB) { if (treeA == null || treeB == null) { return; } if (!treeA.Root.BoundBox.MayOverlap (treeB.Root.BoundBox, AppSettings.parameters.contactParams.cutoffAtomDist)) { return; } // if it is a leaf node of tree A if (treeA.Root.AtomList.Length <= BVTree.leafAtomNumber) { // it is a leaf node of tree B if (treeB.Root.AtomList.Length <= BVTree.leafAtomNumber) { foreach (AtomInfo atomA in treeA.Root.AtomList) { foreach (AtomInfo atomB in treeB.Root.AtomList) { float atomDist = (float)(atomA - atomB); // if distance is less than the threshold // possible atomic contact if (atomDist < AppSettings.parameters.contactParams.cutoffAtomDist) { AtomPair atomPair = new AtomPair(); atomPair.firstAtom = atomA; atomPair.secondAtom = atomB; atomPair.distance = atomDist; string seqIdString = atomA.seqId + "_" + atomB.seqId; if (!chainContactInfo.atomContactHash.ContainsKey(seqIdString)) { chainContactInfo.atomContactHash.Add(seqIdString, atomPair); } else { // give priority to Cbeta then Calpha if (atomPair.firstAtom.atomName == "CB" && atomPair.secondAtom.atomName == "CB") { chainContactInfo.atomContactHash[seqIdString] = atomPair; } } } } } } else { Intersect(treeA, treeB.LeftBranch); Intersect(treeA, treeB.RightBranch); } } else { Intersect(treeA.LeftBranch, treeB); Intersect(treeA.RightBranch, treeB); } }
/// <summary> /// contacts /// </summary> /// <returns></returns> public Dictionary <string, Contact> GetContactsHash() { Dictionary <string, Contact> contactsHash = new Dictionary <string, Contact>(); foreach (string seqString in atomContactHash.Keys) { AtomPair atomPair = (AtomPair)atomContactHash[seqString]; Contact contact = new Contact(); contact.Atom1 = atomPair.firstAtom.atomName; contact.Atom2 = atomPair.secondAtom.atomName; contact.Residue1 = atomPair.firstAtom.residue; contact.Residue2 = atomPair.secondAtom.residue; contact.SeqID1 = atomPair.firstAtom.seqId; contact.SeqID2 = atomPair.secondAtom.seqId; contact.Distance = atomPair.distance; contactsHash.Add(seqString, contact); } return(contactsHash); }
/// <summary> /// /// </summary> /// <param name="extAtomPair"></param> public void DeepCopy(AtomPair extAtomPair) { this.firstAtom = (AtomInfo)extAtomPair.firstAtom.Clone(); // deep copy the atom info this.secondAtom = (AtomInfo)extAtomPair.secondAtom.Clone(); this.distance = extAtomPair.distance; }
/// <summary> /// get contacts between two chains /// </summary> /// <param name="chain1"></param> /// <param name="chain2"></param> /// <returns></returns> public void ComputeChainsContact(AtomInfo[] chain1, AtomInfo[] chain2) { chainContactInfo = new ChainContactInfo(); Dictionary <string, AtomInfo[]> residueAtomsHash1 = null; Dictionary <string, BoundingBox> residueBbHash1 = null; Dictionary <string, AtomInfo[]> residueAtomsHash2 = null; Dictionary <string, BoundingBox> residueBbHash2 = null; GetResidueBb(chain1, ref residueAtomsHash1, ref residueBbHash1); GetResidueBb(chain2, ref residueAtomsHash2, ref residueBbHash2); double contactCutoffSquare = Math.Pow(AppSettings.parameters.contactParams.cutoffAtomDist, 2); foreach (string seqId1 in residueBbHash1.Keys) { foreach (string seqId2 in residueBbHash2.Keys) { // bounding box overlap if (((BoundingBox)residueBbHash1[seqId1]).MayOverlap ((BoundingBox)residueBbHash2[seqId2], AppSettings.parameters.contactParams.cutoffAtomDist)) { double dX2 = 0.0; // inter-atomic contacts between 2 residues bool contactCompDone = false; foreach (AtomInfo atom1 in residueAtomsHash1[seqId1]) { if (contactCompDone) { break; } foreach (AtomInfo atom2 in residueAtomsHash2[seqId2]) { // inter-atomic distance dX2 = Math.Pow(atom1.xyz.X - atom2.xyz.X, 2); if (dX2 > contactCutoffSquare) { continue; } else { double dXY2 = Math.Pow(atom1.xyz.Y - atom2.xyz.Y, 2) + dX2; if (dXY2 > contactCutoffSquare) { continue; } // X else { double dXYZ2 = Math.Pow(atom1.xyz.Z - atom2.xyz.Z, 2) + dXY2; if (dXYZ2 > contactCutoffSquare) { continue; } // Y else { AtomPair atomPair = new AtomPair(); atomPair.firstAtom = atom1; atomPair.secondAtom = atom2; atomPair.distance = Math.Sqrt(dXYZ2); string seqIdString = atom1.seqId + "_" + atom2.seqId; chainContactInfo.atomContactHash.Add(seqIdString, atomPair); contactCompDone = true; break; } //Z } // X, Y, Z } // inter-atomic distance } } // inter-atomic contacts } // bounding box overlap } } // loop chains }
/// <summary> /// Contacts between two chains /// update the treeB when it is necessary /// </summary> /// <param name="treeA">center tree</param> /// <param name="treeB">the tree need to be translated by translateVectorA</param> /// <param name="translateVectorA"></param> private void IntersectResidues(BVTree treeA, BVTree treeB) { if (!treeA.Root.BoundBox.MayOverlap (treeB.Root.BoundBox, AppSettings.parameters.contactParams.cutoffResidueDist)) { return; } // if it is a leaf node of tree A if (treeA.LeftBranch == null && treeA.RightBranch == null) { // it is a leaf node of tree B if (treeB.LeftBranch == null && treeB.RightBranch == null) { foreach (AtomInfo atomA in treeA.Root.AtomList) { foreach (AtomInfo atomB in treeB.Root.AtomList) { float atomDist = (float)(atomA - atomB); if ((atomA.atomName == "CB" || atomA.atomName == "CA") && (atomB.atomName == "CB" || atomB.atomName == "CA") && atomDist < AppSettings.parameters.contactParams.cutoffResidueDist) { AtomPair atomPair = new AtomPair(); atomPair.firstAtom = atomA; atomPair.secondAtom = atomB; atomPair.distance = atomDist; string seqIdString = atomA.seqId + "_" + atomB.seqId; if (!chainContactInfo.cbetaContactHash.ContainsKey(seqIdString)) { chainContactInfo.cbetaContactHash.Add(seqIdString, atomPair); } else { // give priority to Cbeta then Calpha /* if (atomPair.firstAtom.atomName == "CB" && atomPair.secondAtom.atomName == "CB") * { * chainContactInfo.cbetaContactHash[seqIdString] = atomPair; * }*/ // minimum distance between bb atoms double dist = ((AtomPair)chainContactInfo.cbetaContactHash[seqIdString]).distance; if (dist > atomDist) { chainContactInfo.cbetaContactHash[seqIdString] = atomPair; } } } // if distance is less than the threshold // atomic contact if (atomDist < AppSettings.parameters.contactParams.cutoffAtomDist) { string seqIdString = atomA.seqId + "_" + atomB.seqId; if (!chainContactInfo.atomContactHash.ContainsKey(seqIdString)) { AtomPair atomPair = new AtomPair(); atomPair.firstAtom = atomA; atomPair.secondAtom = atomB; atomPair.distance = atomDist; chainContactInfo.atomContactHash.Add(seqIdString, atomPair); } else { // find the atom pair with minimum distance AtomPair atomPair = (AtomPair)chainContactInfo.atomContactHash[seqIdString]; if (atomDist < atomPair.distance) { atomPair.firstAtom = atomA; atomPair.secondAtom = atomB; atomPair.distance = atomDist; chainContactInfo.atomContactHash[seqIdString] = atomPair; } } } } } } else { IntersectResidues(treeA, treeB.LeftBranch); IntersectResidues(treeA, treeB.RightBranch); } } else { IntersectResidues(treeA.LeftBranch, treeB); IntersectResidues(treeA.RightBranch, treeB); } }
/// <summary> /// Contacts between two chains /// update the treeB when it is necessary /// </summary> /// <param name="treeA">center tree</param> /// <param name="treeB">the tree need to be translated by translateVectorA</param> /// <param name="translateVectorA"></param> public void Intersect(BVTree treeA, BVTree treeB, double[] translateVectorA) { if (treeA == null || treeB == null) { return; } BoundingBox bb = treeB.Root.BoundBox.UpdateBoundingBox(translateVectorA); if (!treeA.Root.BoundBox.MayOverlap(bb, AppSettings.parameters.contactParams.cutoffAtomDist)) { return; } // if it is a leaf node of tree A if (treeA.LeftBranch == null && treeA.RightBranch == null) { // it is a leaf node of tree B if (treeB.LeftBranch == null && treeB.RightBranch == null) { Node leafNode = new Node(treeB.Root); leafNode.UpdateLeafNode(translateVectorA); foreach (AtomInfo atomA in treeA.Root.AtomList) { foreach (AtomInfo atomB in leafNode.AtomList) { float atomDist = (float)(atomA - atomB); // if distance is less than the threshold // possible atomic contact if (atomDist < AppSettings.parameters.contactParams.cutoffAtomDist) { AtomPair atomPair = new AtomPair(); atomPair.firstAtom = atomA; atomPair.secondAtom = atomB; atomPair.distance = atomDist; string seqIdString = atomA.seqId + "_" + atomB.seqId; if (!chainContactInfo.atomContactHash.ContainsKey(seqIdString)) { chainContactInfo.atomContactHash.Add(seqIdString, atomPair); } else { // give priority to Cbeta if (atomPair.firstAtom.atomName == "CB" && atomPair.secondAtom.atomName == "CB") { chainContactInfo.atomContactHash[seqIdString] = atomPair; } } } } } } else { Intersect(treeA, treeB.LeftBranch, translateVectorA); Intersect(treeA, treeB.RightBranch, translateVectorA); } } else { Intersect(treeA.LeftBranch, treeB, translateVectorA); Intersect(treeA.RightBranch, treeB, translateVectorA); } }