/* Algorithm: * 1. Calculate all of the interatomic distances between the proteins in one structure * and lable these Dij, Eij for the other * 2. Wij = 1 - ((min(Dij, Eij) / Doff)^2) if min(Dij, Eij) < Doff * Wij = 0 if min(Dij, Eij) >= Doff * 3. Score function: * Q = Sum(Wij * exp(-k|Dij - Eij|)) / sum(Wij) (k = 0.5) * Q is close to 1 if two structures are similar. */ /// <summary> /// weighted Q function /// Input: two structures with exactly same sequences /// but may exist missing residues /// Output: weighted Q score /// </summary> /// <param name="interChain1"></param> /// <param name="interChain2"></param> public double WeightQFunc(ChainContact interfaceChain1, ChainContact interfaceChain2) { // match residue sequence numbers // in case there are missing residues in coordinates in a protein double weightDistSum = 0.0; double weightSum = 0.0; Dictionary <string, AtomPair> atomContactHash1 = interfaceChain1.ChainContactInfo.atomContactHash; Dictionary <string, AtomPair> atomContactHash2 = interfaceChain2.ChainContactInfo.atomContactHash; foreach (string conKey in atomContactHash1.Keys) { AtomPair atomPair = (AtomPair)atomContactHash1[conKey]; double dist1 = atomPair.distance; if (atomContactHash2.ContainsKey(conKey)) { double dist2 = ((AtomPair)atomContactHash2[conKey]).distance; double weightTemp = Math.Pow((Math.Min(dist1, dist2) / AppSettings.parameters.contactParams.cutoffResidueDist), 2); double weight = Math.Pow(1 - weightTemp, 2); weightSum += weight; weightDistSum += weight * Math.Exp(Math.Abs(dist1 - dist2) * -0.5); } } if (weightSum == 0) { return(-1.0); } return(weightDistSum / weightSum); }
/// <summary> /// get the interfaces in an ASU /// </summary> /// <param name="asuChainsHash"></param> public InterfaceChains[] GetInterfacesInAsu(string pdbId, Dictionary <string, AtomInfo[]> asymUnit) { // build trees for the biological unit Dictionary <string, BVTree> asuChainTreesHash = BuildBVtreesForAsu(asymUnit); // calculate interfaces List <InterfaceChains> interfaceList = new List <InterfaceChains> (); List <string> chainAndSymOpList = new List <string> (asuChainTreesHash.Keys); chainAndSymOpList.Sort(); int interChainId = 0; for (int i = 0; i < chainAndSymOpList.Count - 1; i++) { for (int j = i + 1; j < chainAndSymOpList.Count; j++) { ChainContact chainContact = new ChainContact(chainAndSymOpList[i].ToString(), chainAndSymOpList[j].ToString()); ChainContactInfo contactInfo = chainContact.GetChainContactInfo((BVTree)asuChainTreesHash[chainAndSymOpList[i]], (BVTree)asuChainTreesHash[chainAndSymOpList[j]]); if (contactInfo != null) { interChainId++; InterfaceChains interfaceChains = new InterfaceChains(chainAndSymOpList[i].ToString(), chainAndSymOpList[j].ToString()); // no need to change the tree node data // only assign the refereces interfaceChains.chain1 = ((BVTree)asuChainTreesHash[chainAndSymOpList[i]]).Root.CalphaCbetaAtoms(); interfaceChains.chain2 = ((BVTree)asuChainTreesHash[chainAndSymOpList[j]]).Root.CalphaCbetaAtoms(); interfaceChains.interfaceId = interChainId; interfaceChains.firstSymOpString = (string)chainAndSymOpList[i]; interfaceChains.secondSymOpString = (string)chainAndSymOpList[j]; interfaceChains.seqDistHash = chainContact.ChainContactInfo.GetBbDistHash(); interfaceList.Add(interfaceChains); //chainContact = null; } } } // return interface chains return(interfaceList.ToArray()); }
/// <summary> /// /// </summary> /// <param name="interChain1"></param> /// <param name="interChain2"></param> /// <returns></returns> public double CountQFunc(ChainContact contactInfo1, ChainContact contactInfo2) { int matchPairNum = 0; Dictionary <string, AtomPair> contactHash1 = contactInfo1.ChainContactInfo.atomContactHash; Dictionary <string, AtomPair> contactHash2 = contactInfo2.ChainContactInfo.atomContactHash; int totalPairNum = contactHash1.Count + contactHash2.Count; foreach (string seqIdPair in contactHash1.Keys) { if (contactHash2.ContainsKey(seqIdPair)) { matchPairNum++; // for those pairs in both structures // only count once totalPairNum--; } } if (totalPairNum == 0) { return(-1.0); } return((double)matchPairNum / (double)totalPairNum); }