/* 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> /// check the interactions between protein chain and DNA/RNA interactions /// </summary> /// <param name="pdbId"></param> /// <param name="pfamLigandTable"></param> private void RetrieveChainDnaRnaInteractionsInAsu(string pdbId, string[] protChainNames, string[] dnaRnaChainNames) { string gzCoordXmlFile = Path.Combine(ProtCidSettings.dirSettings.coordXmlPath, pdbId + ".xml.gz"); if (!File.Exists(gzCoordXmlFile)) { ProtCidSettings.progressInfo.progStrQueue.Enqueue(pdbId + ".xml.gz file not exist"); return; } string coordXmlFile = ParseHelper.UnZipFile(gzCoordXmlFile, ProtCidSettings.tempDir); // read data from crystal xml file XmlSerializer xmlSerializer = new XmlSerializer(typeof(EntryCrystal)); FileStream xmlFileStream = new FileStream(coordXmlFile, FileMode.Open); EntryCrystal thisEntryCrystal = (EntryCrystal)xmlSerializer.Deserialize(xmlFileStream); xmlFileStream.Close(); File.Delete(coordXmlFile); // no coordinates for waters ChainAtoms[] chains = thisEntryCrystal.atomCat.ChainAtomList; foreach (string dnaRnaChain in dnaRnaChainNames) { AtomInfo[] dnaRnaAtoms = GetChainAtoms(chains, dnaRnaChain); foreach (string protChainName in protChainNames) { AtomInfo[] protChainAtoms = GetChainAtoms(chains, protChainName); ChainContactInfo contactInfo = atomContact.GetAllChainContactInfo(dnaRnaAtoms, protChainAtoms); if (contactInfo == null) { continue; } foreach (string seqPair in contactInfo.atomContactHash.Keys) { string[] seqIds = seqPair.Split('_'); AtomPair atomPair = (AtomPair)contactInfo.atomContactHash[seqPair]; double distance = atomPair.distance; DataRow chainDnaRnaRow = chainDnaRnaTable.NewRow(); chainDnaRnaRow["PdbID"] = pdbId; chainDnaRnaRow["BuID"] = "0"; chainDnaRnaRow["AsymID"] = dnaRnaChain; chainDnaRnaRow["SymmetryString"] = "1_555"; chainDnaRnaRow["ChainAsymID"] = protChainName; chainDnaRnaRow["ChainSymmetryString"] = "1_555"; chainDnaRnaRow["SeqID"] = seqIds[0]; chainDnaRnaRow["ChainSeqID"] = seqIds[1]; chainDnaRnaRow["Distance"] = distance; chainDnaRnaRow["Atom"] = atomPair.firstAtom.atomName; chainDnaRnaRow["ChainAtom"] = atomPair.secondAtom.atomName; chainDnaRnaRow["Residue"] = atomPair.firstAtom.residue; chainDnaRnaRow["ChainResidue"] = atomPair.secondAtom.residue; chainDnaRnaTable.Rows.Add(chainDnaRnaRow); } } } dbInsert.InsertDataIntoDBtables(ProtCidSettings.buCompConnection, chainDnaRnaTable); chainDnaRnaTable.Clear(); }
/// <summary> /// /// </summary> /// <param name="pdbId"></param> /// <param name="buId"></param> /// <param name="buHash"></param> /// <param name="protChains"></param> /// <param name="dnaRnaChains"></param> private void RetrieveProtDnaRnaInteractions(string pdbId, string buId, Dictionary <string, AtomInfo[]> buHash, string[] protChains, string[] dnaRnaChains) { string[] dnaRnaChainsWithSymOp = GetChainsWithSymOps(dnaRnaChains, buHash); string[] protChainsWithSymOp = GetChainsWithSymOps(protChains, buHash); foreach (string dnaRnaChainSymOp in dnaRnaChainsWithSymOp) { AtomInfo[] dnaRnaAtoms = buHash[dnaRnaChainSymOp]; string[] dnaRnaChainSymOpFields = GetChainSymOpFields(dnaRnaChainSymOp); foreach (string protChainSymOp in protChainsWithSymOp) { string[] protChainSymOpFields = GetChainSymOpFields(protChainSymOp); AtomInfo[] protAtoms = (AtomInfo[])buHash[protChainSymOp]; ChainContactInfo contactInfo = atomContact.GetAllChainContactInfo(dnaRnaAtoms, protAtoms); if (contactInfo == null) { continue; } foreach (string seqPair in contactInfo.atomContactHash.Keys) { string[] seqIds = seqPair.Split('_'); AtomPair atomPair = (AtomPair)contactInfo.atomContactHash[seqPair]; double distance = atomPair.distance; DataRow chainDnaRnaRow = chainDnaRnaTable.NewRow(); chainDnaRnaRow["PdbID"] = pdbId; chainDnaRnaRow["BuID"] = buId; chainDnaRnaRow["AsymID"] = dnaRnaChainSymOpFields[0]; chainDnaRnaRow["SymmetryString"] = dnaRnaChainSymOpFields[1]; chainDnaRnaRow["ChainAsymID"] = protChainSymOpFields[0]; chainDnaRnaRow["ChainSymmetryString"] = protChainSymOpFields[1]; chainDnaRnaRow["SeqID"] = seqIds[0]; chainDnaRnaRow["ChainSeqID"] = seqIds[1]; chainDnaRnaRow["Distance"] = distance; chainDnaRnaRow["Atom"] = atomPair.firstAtom.atomName; chainDnaRnaRow["ChainAtom"] = atomPair.secondAtom.atomName; chainDnaRnaRow["Residue"] = atomPair.firstAtom.residue; chainDnaRnaRow["ChainResidue"] = atomPair.secondAtom.residue; chainDnaRnaTable.Rows.Add(chainDnaRnaRow); } } } dbInsert.InsertDataIntoDBtables(ProtCidSettings.buCompConnection, chainDnaRnaTable); chainDnaRnaTable.Clear(); }
public static string FormatInteractionOutput(string pdbId, List <AtomPair> interactionsList, FormatInternationOutputStyle formatInternationOutputStyle = FormatInternationOutputStyle.DefaultStyle) { var sb = new StringBuilder(); sb.AppendLine("List of atom-atom interactions across protein-protein proteinInterface "); sb.AppendLine("--------------------------------------------------------------- "); sb.AppendLine(" "); sb.AppendLine(" PDB code: " + pdbId + " "); sb.AppendLine(" ------------------------------ "); sb.AppendLine(" "); sb.AppendLine(" "); sb.AppendLine(" <----- A T O M 1 -----> <----- A T O M 2 -----> "); sb.AppendLine(" "); sb.AppendLine(" Atom Atom Res Res Atom Atom Res Res "); sb.AppendLine(" no. name name no. Chain no. name name no. Chain Distance"); for (int interactionIndex = 0; interactionIndex < interactionsList.Count; interactionIndex++) { AtomPair interactingPair = interactionsList[interactionIndex]; string line = (interactionIndex + 1).ToString().PadLeft(3) + ". " + interactingPair.Atom1.serial.FieldValue.PadLeft(6) + " " + interactingPair.Atom1.name.FieldValue.PadRight(4) + interactingPair.Atom1.resName.FieldValue.PadLeft(3) + interactingPair.Atom1.resSeq.FieldValue.PadLeft(5) + " " + interactingPair.Atom1.chainID.FieldValue + " <-->" + interactingPair.Atom2.serial.FieldValue.PadLeft(6) + " " + interactingPair.Atom2.name.FieldValue.PadRight(4) + interactingPair.Atom2.resName.FieldValue.PadLeft(3) + interactingPair.Atom2.resSeq.FieldValue.PadLeft(5) + " " + interactingPair.Atom2.chainID.FieldValue + Math.Round(interactingPair.Distance, 2).ToString("0.00").PadLeft(10); sb.AppendLine(line); } sb.AppendLine(" "); sb.AppendLine("Number of interactions: " + interactionsList.Count.ToString().PadLeft(3) + " "); sb.AppendLine(" "); sb.AppendLine(" "); return(sb.ToString()); }
private bool FusionPointInversion(AtomPair pair) { // not candidates for inversion // > 3 bonds if (pair.bndAt.Count != 3) { return(false); } // we want *!@*@*!@* if (!pair.bndAt[0].IsInRing || pair.bndAt[1].IsInRing || pair.bndAt[2].IsInRing) { return(false); } // non-terminals if (adjList[pair.fst].Length > 1 || adjList[pair.snd].Length > 1) { return(false); } IAtom fst = atoms[pair.fst]; // choose which one to invert, preffering hydrogens stackBackup.Clear(); if (fst.AtomicNumber == 1) { stackBackup.Push(pair.fst); } else { stackBackup.Push(pair.snd); } Reflect(stackBackup, pair.bndAt[0].Begin, pair.bndAt[0].End); congestion.Update(stackBackup.xs, stackBackup.len); return(true); }
/// <summary> /// Stretch all bonds in the shortest path between a pair of atoms in an /// attempt to resolve the overlap. The stretch that produces the minimum /// congestion is stored in the provided stack and coordinates with the congestion /// score returned. /// </summary> /// <param name="pair">congested atom pair</param> /// <param name="stack">best result vertices</param> /// <param name="coords">best result coordinates</param> /// <param name="firstVisit">visit map to avoid repeating work</param> /// <returns>congestion score of best result</returns> private double Stretch(AtomPair pair, IntStack stack, Vector2[] coords, Dictionary <IBond, AtomPair> firstVisit) { stackBackup.Clear(); var score = congestion.Score(); var min = score; foreach (var bond in pair.bndAt) { // don't stretch ring bonds if (bond.IsInRing) { continue; } if (bfix.Contains(bond)) { continue; } // has this bond already been tested as part of another pair if (!firstVisit.TryGetValue(bond, out AtomPair first)) { firstVisit[bond] = first = pair; } if (first != pair) { continue; } var beg = bond.Begin; var end = bond.End; var begIdx = idxs[beg]; var endIdx = idxs[end]; var begPriority = beg.GetProperty <int>(AtomPlacer.Priority); var endPriority = end.GetProperty <int>(AtomPlacer.Priority); Arrays.Fill(visited, false); if (begPriority < endPriority) { stack.len = Visit(visited, stack.xs, endIdx, begIdx, 0); } else { stack.len = Visit(visited, stack.xs, begIdx, endIdx, 0); } BackupCoords(backup, stack); if (begPriority < endPriority) { Stretch(stack, end, beg, pair.attempt * StrechStep); } else { Stretch(stack, beg, end, pair.attempt * StrechStep); } congestion.Update(visited, stack.xs, stack.len); if (PercDiff(score, congestion.Score()) >= ImprovementPrecThreshold && congestion.Score() < min) { BackupCoords(coords, stack); min = congestion.Score(); stackBackup.CopyFrom(stack); } RestoreCoords(stack, backup); congestion.Update(visited, stack.xs, stack.len); congestion.score = score; } stack.CopyFrom(stackBackup); return(min); }
/// <summary> /// Bend all bonds in the shortest path between a pair of atoms in an attempt /// to resolve the overlap. The bend that produces the minimum congestion is /// stored in the provided stack and coords with the congestion score /// returned. /// </summary> /// <param name="pair">congested atom pair</param> /// <param name="stack">best result vertices</param> /// <param name="coords">best result coords</param> /// <param name="firstVisit">visit map to avoid repeating work</param> /// <returns>congestion score of best result</returns> private double Bend(AtomPair pair, IntStack stack, Vector2[] coords, Dictionary <IBond, AtomPair> firstVisit) { stackBackup.Clear(); Trace.Assert(stack.len == 0); double score = congestion.Score(); double min = score; // special case: if we have an even length path where the two // most central bonds are cyclic but the next two aren't we bend away // from each other if (pair.bndAt.Count > 4 && (pair.bndAtCode & 0x1F) == 0x6) { var bndA = pair.bndAt[2]; var bndB = pair.bndAt[3]; if (bfix.Contains(bndA) || bfix.Contains(bndB)) { return(int.MaxValue); } var pivotA = GetCommon(bndA, pair.bndAt[1]); var pivotB = GetCommon(bndB, pair.bndAt[0]); if (pivotA == null || pivotB == null) { return(int.MaxValue); } Arrays.Fill(visited, false); int split = Visit(visited, stack.xs, idxs[pivotA], idxs[bndA.GetOther(pivotA)], 0); stack.len = Visit(visited, stack.xs, idxs[pivotB], idxs[bndB.GetOther(pivotB)], split); // perform bend one way BackupCoords(backup, stack); Bend(stack.xs, 0, split, pivotA, BendStep); Bend(stack.xs, split, stack.len, pivotB, -BendStep); congestion.Update(stack.xs, stack.len); if (PercDiff(score, congestion.Score()) >= ImprovementPrecThreshold) { BackupCoords(coords, stack); stackBackup.CopyFrom(stack); min = congestion.Score(); } // now bend the other way RestoreCoords(stack, backup); Bend(stack.xs, 0, split, pivotA, -BendStep); Bend(stack.xs, split, stack.len, pivotB, BendStep); congestion.Update(stack.xs, stack.len); if (PercDiff(score, congestion.Score()) >= ImprovementPrecThreshold && congestion.Score() < min) { BackupCoords(coords, stack); stackBackup.CopyFrom(stack); min = congestion.Score(); } // restore original coordinates and reset score RestoreCoords(stack, backup); congestion.Update(stack.xs, stack.len); congestion.score = score; } // general case: try bending acyclic bonds in the shortest // path from inside out else { // try bending all bonds and accept the best one foreach (var bond in pair.bndAt) { if (bond.IsInRing) { continue; } if (bfix.Contains(bond)) { continue; } // has this bond already been tested as part of another pair if (!firstVisit.TryGetValue(bond, out AtomPair first)) { firstVisit[bond] = first = pair; } if (first != pair) { continue; } var beg = bond.Begin; var end = bond.End; var begPriority = beg.GetProperty <int>(AtomPlacer.Priority); var endPriority = end.GetProperty <int>(AtomPlacer.Priority); Arrays.Fill(visited, false); if (begPriority < endPriority) { stack.len = Visit(visited, stack.xs, idxs[beg], idxs[end], 0); } else { stack.len = Visit(visited, stack.xs, idxs[end], idxs[beg], 0); } BackupCoords(backup, stack); // bend one way if (begPriority < endPriority) { Bend(stack.xs, 0, stack.len, beg, pair.attempt * BendStep); } else { Bend(stack.xs, 0, stack.len, end, pair.attempt * BendStep); } congestion.Update(visited, stack.xs, stack.len); if (PercDiff(score, congestion.Score()) >= ImprovementPrecThreshold && congestion.Score() < min) { BackupCoords(coords, stack); stackBackup.CopyFrom(stack); min = congestion.Score(); } // bend other way if (begPriority < endPriority) { Bend(stack.xs, 0, stack.len, beg, pair.attempt * -BendStep); } else { Bend(stack.xs, 0, stack.len, end, pair.attempt * -BendStep); } congestion.Update(visited, stack.xs, stack.len); if (PercDiff(score, congestion.Score()) >= ImprovementPrecThreshold && congestion.Score() < min) { BackupCoords(coords, stack); stackBackup.CopyFrom(stack); min = congestion.Score(); } RestoreCoords(stack, backup); congestion.Update(visited, stack.xs, stack.len); congestion.score = score; } } stack.CopyFrom(stackBackup); return(min); }
// For substituents attached to macrocycles we may be able to point these in/out // of the ring private bool MacroCycleInversion(AtomPair pair) { foreach (var v in pair.seqAt) { IAtom atom = mol.Atoms[v]; if (!atom.IsInRing || adjList[v].Length == 2) { continue; } if (atom.GetProperty <object>(MacroCycleLayout.MACROCYCLE_ATOM_HINT) == null) { continue; } var acyclic = new List <IBond>(2); var cyclic = new List <IBond>(2); foreach (var w in adjList[v]) { IBond bond = bondMap[v, w]; if (bond.IsInRing) { cyclic.Add(bond); } else { acyclic.Add(bond); } } if (cyclic.Count > 2) { continue; } foreach (var bond in acyclic) { if (bfix.Contains(bond)) { continue; } Arrays.Fill(visited, false); stackBackup.len = Visit(visited, stackBackup.xs, v, idxs[bond.GetOther(atom)], 0); Vector2 a = atom.Point2D.Value; Vector2 b = bond.GetOther(atom).Point2D.Value; Vector2 perp = new Vector2(b.X - a.X, b.Y - a.Y); perp = Vector2.Normalize(perp); double score = congestion.Score(); BackupCoords(backup, stackBackup); Reflect(stackBackup, new Vector2(a.X - perp.Y, a.Y + perp.X), new Vector2(a.X + perp.Y, a.Y - perp.X)); congestion.Update(visited, stackBackup.xs, stackBackup.len); if (PercDiff(score, congestion.Score()) >= ImprovementPrecThreshold) { return(true); } RestoreCoords(stackBackup, backup); } } return(false); }
/// <summary> /// This method finds interactions between detected proteinInterfaces. It is specific to dimers with exactly two chains. [Chain A /// ProteinInterface Index, Chain B ProteinInterface Index] /// </summary> /// <param name="cancellationToken"></param> /// <param name="pdbFilename"></param> /// <param name="pdbFileChains"></param> /// <param name="chainInteractingAtomLists"></param> /// <param name="fullClusteringResult"></param> /// <param name="proteinInterfacesClusteringResult"></param> /// <param name="detectedFinalStageIndexes"></param> /// <param name="pdbIdChainIdList"></param> /// <returns></returns> public static InteractionBetweenProteinInterfacesListContainer FindInteractionsBetweenAnyProteinInterfaces( CancellationToken cancellationToken, decimal maxAtomInterationDistance, string pdbFilename, Dictionary<string, List<string>> pdbIdChainIdList, ProteinChainListContainer pdbFileChains, ProteinChainListContainer chainInteractingAtomLists, ClusteringFullResultListContainer fullClusteringResult, ClusteringFullResultListContainer proteinInterfacesClusteringResult, int[] detectedFinalStageIndexes) { if (string.IsNullOrWhiteSpace(pdbFilename)) { throw new ArgumentOutOfRangeException(nameof(pdbFilename)); } if (!File.Exists(pdbFilename)) { throw new FileNotFoundException("File not found", pdbFilename); } if (ParameterValidation.IsProteinChainListContainerNullOrEmpty(chainInteractingAtomLists)) { throw new ArgumentOutOfRangeException(nameof(chainInteractingAtomLists)); } if (ParameterValidation.IsClusteringFullResultListContainerNullOrEmpty(fullClusteringResult)) { throw new ArgumentOutOfRangeException(nameof(fullClusteringResult)); } if (ParameterValidation.IsClusteringFullResultListContainerNullOrEmpty(proteinInterfacesClusteringResult)) { throw new ArgumentOutOfRangeException(nameof(proteinInterfacesClusteringResult)); } if (ParameterValidation.IsIntArrayNullOrEmpty(detectedFinalStageIndexes)) { throw new ArgumentOutOfRangeException(nameof(detectedFinalStageIndexes)); } string proteinId = ProteinDataBankFileOperations.PdbIdFromPdbFilename(pdbFilename); var interactionBetweenProteinInterfacesListContainer = new InteractionBetweenProteinInterfacesListContainer(); List<AtomPair> interactionList; if (pdbFileChains != null && pdbFileChains.ChainList != null && pdbFileChains.ChainList.Count > 0) { interactionList = SearchInteractions.FindInteractions(cancellationToken, maxAtomInterationDistance, proteinId, pdbIdChainIdList, pdbFileChains); //, false, -1, pdbFileChains); } else { interactionList = SearchInteractions.FindInteractions(cancellationToken, maxAtomInterationDistance, pdbFilename, pdbIdChainIdList); } var interactionInsideProteinInterfaceArray = new bool[interactionList.Count]; ////////Console.WriteLine(""); ////////Console.WriteLine(""); ////////Console.WriteLine("------------------ START ------------------"); //int c = 0; for (int chainIndexA = 0; chainIndexA < proteinInterfacesClusteringResult.ChainList.Count; chainIndexA++) { for (int chainIndexB = 0; chainIndexB < proteinInterfacesClusteringResult.ChainList.Count; chainIndexB++) { if (chainIndexA == chainIndexB || chainIndexB < chainIndexA) { continue; } List<ClusteringFullResultListContainer.Chain.Stage.Cluster> proteinInterfaceListA = proteinInterfacesClusteringResult.ChainList[chainIndexA].StageList[detectedFinalStageIndexes[chainIndexA]].ClusterList; List<ClusteringFullResultListContainer.Chain.Stage.Cluster> proteinInterfaceListB = proteinInterfacesClusteringResult.ChainList[chainIndexB].StageList[detectedFinalStageIndexes[chainIndexB]].ClusterList; int realProteinInterfaceIndexA = -1; for (int proteinInterfaceIndexA = 0; proteinInterfaceIndexA < proteinInterfaceListA.Count; proteinInterfaceIndexA++) { int realProteinInterfaceIndexB = -1; List<int> proteinInterfaceMemberIndexListA = proteinInterfaceListA[proteinInterfaceIndexA].AtomIndexList; List<ATOM_Record> proteinInterfaceAtomListA = proteinInterfaceMemberIndexListA.Select(proteinInterfaceMemberIndexA => chainInteractingAtomLists.ChainList[chainIndexA].AtomList[proteinInterfaceMemberIndexA]).ToList(); proteinInterfaceAtomListA = proteinInterfaceAtomListA.OrderBy(a => ProteinDataBankFileOperations.NullableTryParseInt32(a.resSeq.FieldValue)).ToList(); if (proteinInterfaceAtomListA.Count > 0) { realProteinInterfaceIndexA++; } else { continue; } for (int proteinInterfaceIndexB = 0; proteinInterfaceIndexB < proteinInterfaceListB.Count; proteinInterfaceIndexB++) { List<int> proteinInterfaceMemberIndexListB = proteinInterfaceListB[proteinInterfaceIndexB].AtomIndexList; List<ATOM_Record> proteinInterfaceAtomListB = proteinInterfaceMemberIndexListB.Select(proteinInterfaceMemberIndexB => chainInteractingAtomLists.ChainList[chainIndexB].AtomList[proteinInterfaceMemberIndexB]).ToList(); proteinInterfaceAtomListB = proteinInterfaceAtomListB.OrderBy(b => ProteinDataBankFileOperations.NullableTryParseInt32(b.resSeq.FieldValue)).ToList(); if (proteinInterfaceAtomListB.Count > 0) { realProteinInterfaceIndexB++; } else { continue; } for (int proteinInterfaceAtomListIndexA = 0; proteinInterfaceAtomListIndexA < proteinInterfaceAtomListA.Count; proteinInterfaceAtomListIndexA++) { ATOM_Record atomA = proteinInterfaceAtomListA[proteinInterfaceAtomListIndexA]; for (int proteinInterfaceAtomListIndexB = 0; proteinInterfaceAtomListIndexB < proteinInterfaceAtomListB.Count; proteinInterfaceAtomListIndexB++) { ATOM_Record atomB = proteinInterfaceAtomListB[proteinInterfaceAtomListIndexB]; //c++; ////////Console.WriteLine(c.ToString().PadLeft(5) + // " Chain " + chainIndexA + " (" + proteinInterfaceListA.Count(a => a.AtomIndexList.Count > 0) + " proteinInterfaces) ProteinInterface " + realProteinInterfaceIndexA + " (" + proteinInterfaceAtomListA.Count + " atoms) <--->" + // " Chain " + chainIndexB + " (" + proteinInterfaceListB.Count(a => a.AtomIndexList.Count > 0) + " proteinInterfaces) ProteinInterface " + realProteinInterfaceIndexB + " (" + proteinInterfaceAtomListB.Count + " atoms) --->" + // " chainID " + atomA.chainID.FieldValue + " resName " + atomA.resName.FieldValue + " resSeq " + atomA.resSeq.FieldValue + " <--->" + // " chainID " + atomB.chainID.FieldValue + " resName " + atomB.resName.FieldValue + " resSeq " + atomB.resSeq.FieldValue); for (int interactionIndex = 0; interactionIndex < interactionList.Count; interactionIndex++) { AtomPair interaction = interactionList[interactionIndex]; if ((interaction.Atom1 == atomA && interaction.Atom2 == atomB) || (interaction.Atom1 == atomB && interaction.Atom2 == atomA)) { interactionInsideProteinInterfaceArray[interactionIndex] = true; var interactionBetweenProteinInterfaces = new InteractionBetweenProteinInterfaces(); interactionBetweenProteinInterfacesListContainer.InteractionBetweenProteinInterfacesList.Add(interactionBetweenProteinInterfaces); interactionBetweenProteinInterfaces.Atom1.Atom = atomA; interactionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinId = proteinId; interactionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ChainId = chainIndexA; interactionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinInterfaceId = realProteinInterfaceIndexA; interactionBetweenProteinInterfaces.Atom2.Atom = atomB; interactionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinId = proteinId; interactionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ChainId = chainIndexB; interactionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinInterfaceId = realProteinInterfaceIndexB; } } } } } } } } for (int interactionIndex = 0; interactionIndex < interactionInsideProteinInterfaceArray.Length; interactionIndex++) { bool interactionInsideProteinInterface = interactionInsideProteinInterfaceArray[interactionIndex]; if (!interactionInsideProteinInterface) { var interactionBetweenNonProteinInterfaces = new InteractionBetweenProteinInterfaces(); interactionBetweenProteinInterfacesListContainer.InteractionBetweenNonProteinInterfacesList.Add(interactionBetweenNonProteinInterfaces); interactionBetweenNonProteinInterfaces.Atom1.Atom = interactionList[interactionIndex].Atom1; interactionBetweenNonProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinId = proteinId; interactionBetweenNonProteinInterfaces.Atom1.FullProteinInterfaceId.ChainId = interactionList[interactionIndex].Atom1FullProteinInterfaceId.ChainId; interactionBetweenNonProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinInterfaceId = -1; interactionBetweenNonProteinInterfaces.Atom2.Atom = interactionList[interactionIndex].Atom2; interactionBetweenNonProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinId = proteinId; interactionBetweenNonProteinInterfaces.Atom2.FullProteinInterfaceId.ChainId = interactionList[interactionIndex].Atom2FullProteinInterfaceId.ChainId; interactionBetweenNonProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinInterfaceId = -1; } } ////////Console.WriteLine("------------------ END ------------------"); // ensure sorted order interactionBetweenProteinInterfacesListContainer.InteractionBetweenProteinInterfacesList = interactionBetweenProteinInterfacesListContainer.InteractionBetweenProteinInterfacesList .OrderBy(a => a.Atom1.FullProteinInterfaceId.ChainId) .ThenBy(a => a.Atom1.FullProteinInterfaceId.ProteinInterfaceId) .ThenBy(a => ProteinDataBankFileOperations.NullableTryParseInt32(a.Atom1.Atom.resSeq.FieldValue)) .ThenBy(a => a.Atom2.FullProteinInterfaceId.ChainId) .ThenBy(a => a.Atom2.FullProteinInterfaceId.ProteinInterfaceId) .ThenBy(a => ProteinDataBankFileOperations.NullableTryParseInt32(a.Atom2.Atom.resSeq.FieldValue)) .ToList(); interactionBetweenProteinInterfacesListContainer.InteractionBetweenNonProteinInterfacesList = interactionBetweenProteinInterfacesListContainer.InteractionBetweenNonProteinInterfacesList .OrderBy(a => a.Atom1.FullProteinInterfaceId.ChainId) .ThenBy(a => a.Atom1.FullProteinInterfaceId.ProteinInterfaceId) .ThenBy(a => ProteinDataBankFileOperations.NullableTryParseInt32(a.Atom1.Atom.resSeq.FieldValue)) .ThenBy(a => a.Atom2.FullProteinInterfaceId.ChainId) .ThenBy(a => a.Atom2.FullProteinInterfaceId.ProteinInterfaceId) .ThenBy(a => ProteinDataBankFileOperations.NullableTryParseInt32(a.Atom2.Atom.resSeq.FieldValue)) .ToList(); // remove duplicates (as the list is sorted, duplicates will always be together in the list) for (int index = interactionBetweenProteinInterfacesListContainer.InteractionBetweenProteinInterfacesList.Count - 1; index > 0; index--) { InteractionBetweenProteinInterfaces lastInteractionBetweenProteinInterfaces = interactionBetweenProteinInterfacesListContainer.InteractionBetweenProteinInterfacesList[index - 1]; InteractionBetweenProteinInterfaces thisInteractionBetweenProteinInterfaces = interactionBetweenProteinInterfacesListContainer.InteractionBetweenProteinInterfacesList[index]; if (lastInteractionBetweenProteinInterfaces == null || thisInteractionBetweenProteinInterfaces == null) { continue; } if (thisInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinId == lastInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinId && thisInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ChainId == lastInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ChainId && thisInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinInterfaceId == lastInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinInterfaceId && thisInteractionBetweenProteinInterfaces.Atom1.Atom == lastInteractionBetweenProteinInterfaces.Atom1.Atom && thisInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinId == lastInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinId && thisInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ChainId == lastInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ChainId && thisInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinInterfaceId == lastInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinInterfaceId && thisInteractionBetweenProteinInterfaces.Atom2.Atom == lastInteractionBetweenProteinInterfaces.Atom2.Atom) { interactionBetweenProteinInterfacesListContainer.InteractionBetweenProteinInterfacesList.RemoveAt(index - 1); //////Console.WriteLine("removed duplicate"); } } for (int index = interactionBetweenProteinInterfacesListContainer.InteractionBetweenNonProteinInterfacesList.Count - 1; index > 0; index--) { InteractionBetweenProteinInterfaces lastInteractionBetweenProteinInterfaces = interactionBetweenProteinInterfacesListContainer.InteractionBetweenNonProteinInterfacesList[index - 1]; InteractionBetweenProteinInterfaces thisInteractionBetweenProteinInterfaces = interactionBetweenProteinInterfacesListContainer.InteractionBetweenNonProteinInterfacesList[index]; if (lastInteractionBetweenProteinInterfaces == null || thisInteractionBetweenProteinInterfaces == null) { continue; } if (thisInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinId == lastInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinId && thisInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ChainId == lastInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ChainId && thisInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinInterfaceId == lastInteractionBetweenProteinInterfaces.Atom1.FullProteinInterfaceId.ProteinInterfaceId && thisInteractionBetweenProteinInterfaces.Atom1.Atom == lastInteractionBetweenProteinInterfaces.Atom1.Atom && thisInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinId == lastInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinId && thisInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ChainId == lastInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ChainId && thisInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinInterfaceId == lastInteractionBetweenProteinInterfaces.Atom2.FullProteinInterfaceId.ProteinInterfaceId && thisInteractionBetweenProteinInterfaces.Atom2.Atom == lastInteractionBetweenProteinInterfaces.Atom2.Atom) { interactionBetweenProteinInterfacesListContainer.InteractionBetweenNonProteinInterfacesList.RemoveAt(index - 1); //////Console.WriteLine("removed duplicate"); } } return interactionBetweenProteinInterfacesListContainer; }
public static List <AtomPair> FindInteractions(CancellationToken cancellationToken, decimal maxAtomInterationDistance /*= 8.0m*/, string proteinId, Dictionary <string, List <string> > pdbIdChainIdList, ProteinChainListContainer proteinFileChains, bool breakWhenFirstInteractionFound = false, int totalThreads = -1, bool sort = true, int requiredChains = -1) { //const decimal maxInterationDistance = 8.0m; bool useCache = false; if (useCache && !string.IsNullOrWhiteSpace(proteinId)) { var cachedInteractions = InteractionsCache.LoadPdbInteractionCache(proteinId, requiredChains); if (cachedInteractions != null) { return(cachedInteractions); } } // check required number of chains are found if (proteinFileChains == null || proteinFileChains.ChainList == null || (requiredChains > -1 && proteinFileChains.ChainList.Count != requiredChains)) { return(null); } // check that all chains have atoms if (proteinFileChains.ChainList.Any(chain => chain.AtomList == null || chain.AtomList.Count == 0)) { return(null); } // Make list of 3D positions of atoms. var positions = new List <Point3D> [proteinFileChains.ChainList.Count]; for (int chainIndex = 0; chainIndex < proteinFileChains.ChainList.Count; chainIndex++) { positions[chainIndex] = Clustering.AtomRecordListToPoint3DList(proteinFileChains.ChainList[chainIndex]); } var tasks = new List <Task <List <AtomPair> > >(); for (int chainIndexA = 0; chainIndexA < proteinFileChains.ChainList.Count; chainIndexA++) { for (int chainIndexB = 0; chainIndexB < proteinFileChains.ChainList.Count; chainIndexB++) { if (chainIndexB == chainIndexA || chainIndexB < chainIndexA) { continue; } WorkDivision <List <AtomPair> > workDivision = new WorkDivision <List <AtomPair> >(proteinFileChains.ChainList[chainIndexA].AtomList.Count, totalThreads); bool breakOut = false; var lockBreakOut = new object(); for (int threadIndex = 0; threadIndex < workDivision.ThreadCount; threadIndex++) { int localThreadIndex = threadIndex; int localChainIndexA = chainIndexA; int localChainIndexB = chainIndexB; WorkDivision <List <AtomPair> > localWorkDivision = workDivision; Task <List <AtomPair> > task = Task.Run(() => { var taskResult = new List <AtomPair>(); for (int atomIndexA = localWorkDivision.ThreadFirstIndex[localThreadIndex]; atomIndexA <= localWorkDivision.ThreadLastIndex[localThreadIndex]; atomIndexA++) { if (breakOut) { break; } for (int atomIndexB = 0; atomIndexB < proteinFileChains.ChainList[localChainIndexB].AtomList.Count; atomIndexB++) { if (breakOut || (breakWhenFirstInteractionFound && taskResult.Count > 0)) { lock (lockBreakOut) { breakOut = true; } break; } if ((!positions[localChainIndexA][atomIndexA].ParseOK) || (!positions[localChainIndexB][atomIndexB].ParseOK)) { continue; } decimal atomicDistanceAngstroms3D = Point3D.Distance3D(positions[localChainIndexA][atomIndexA], positions[localChainIndexB][atomIndexB], true); // Chemical proteinInterface bonds found at 5 angstrom or less. if (atomicDistanceAngstroms3D <= 0.0m || atomicDistanceAngstroms3D > maxAtomInterationDistance) { continue; } var atomPair = new AtomPair( proteinId, proteinFileChains.ChainList[localChainIndexA].AtomList[atomIndexA], localChainIndexA, proteinId, localChainIndexB, proteinFileChains.ChainList[localChainIndexB].AtomList[atomIndexB], atomicDistanceAngstroms3D); taskResult.Add(atomPair); } } if (taskResult.Count == 0) { return(null); } return(taskResult); }, cancellationToken); workDivision.TaskList.Add(task); } tasks.AddRange(workDivision.TaskList); } } try { Task[] tasksToWait = tasks.Where(task => task != null && !task.IsCompleted).ToArray <Task>(); if (tasksToWait.Length > 0) { Task.WaitAll(tasksToWait); } } catch (AggregateException) { } // merge all results var atomPairList = new List <AtomPair>(); foreach (var task in tasks.Where(t => t != null && t.IsCompleted && !t.IsCanceled && !t.IsFaulted && t.Result != null && t.Result.Count > 0)) { atomPairList.AddRange(task.Result); } if (sort && atomPairList != null && atomPairList.Count > 1) { atomPairList = atomPairList .OrderBy(i => ProteinDataBankFileOperations.NullableTryParseInt32(i.Atom1.resSeq.FieldValue)) .ThenBy(i => ProteinDataBankFileOperations.NullableTryParseInt32(i.Atom1.serial.FieldValue)) .ThenBy(j => ProteinDataBankFileOperations.NullableTryParseInt32(j.Atom2.resSeq.FieldValue)) .ThenBy(j => ProteinDataBankFileOperations.NullableTryParseInt32(j.Atom2.serial.FieldValue)) .ToList(); } if (useCache) { InteractionsCache.SavePdbInteractionCache(proteinId, atomPairList, requiredChains); } return(atomPairList); }