public static TransformSequenceAlignment Reversed(TransformSequenceAlignment other) { TransformSequenceAlignment result = new TransformSequenceAlignment(other); result.Reverse(); return(result); }
/// <summary> /// Returns sequence alignments that could join all of the input structures /// </summary> /// <param name="structures"></param> /// <param name="chains">IChain indices for each structure that should be </param> /// <returns></returns> public static TransformSequenceAlignment[][] GetRepeatFilteredTransformAlignments(IStructure[] structures, int[][] chains) { TransformSequenceAlignment[][] result = new TransformSequenceAlignment[structures.Length - 1][]; for (int i = 0; i < structures.Length - 1; i++) { List <TransformSequenceAlignment> alignments = new List <TransformSequenceAlignment>(); foreach (int chainIndex1 in chains[i]) { foreach (int chainIndex2 in chains[i + 1]) { IChain chain1 = structures[i][chainIndex1]; IChain chain2 = structures[i + 1][chainIndex2]; // Shorten the List <TransformSequenceAlignment> chainAlignments = GetRepeatFilteredTransformAlignments(structures[i], chainIndex1, false, structures[i + 1], chainIndex2, i != structures.Length - 2 && structures[i + 1].Count == 1, SS.Helix | SS.Extended); foreach (TransformSequenceAlignment alignment in chainAlignments) { alignment.ChainIndex1 = chainIndex1; alignment.ChainIndex2 = chainIndex2; } alignments.AddRange(chainAlignments); } } result[i] = alignments.ToArray(); } return(result); }
public TransformSequenceAlignment(TransformSequenceAlignment other) : this(other.ChainIndex1, other.Range1, other.ChainIndex2, other.Range2) { Align2 = other.Align2; Align1 = other.Align1; Centroid1 = other.Centroid1; Centroid2 = other.Centroid2; }
/// <summary> /// Find splicing alignment ranges for two peptides that would retain a full secondary structure block for at least one of the two peptides. This prevents /// short splice overlaps that remove some of the secondary structure on both sides of the alignment. Basically, the alignment must result in either: /// 1) one secondary structure block being fully included in the other /// 2) the N-terminal peptide being spliced has the end of its block fully in the resultant alignment, thus preserving the entire N-side block /// 3) the C-terminal peptide being spliced has the start of its block fully in the resultant alignment, thus preserving the entire C-side block /// </summary> /// <param name="chain1"></param> /// <param name="chain2"></param> /// <param name="allowedTypes"></param> /// <param name="minAlignmentLength"></param> /// <returns></returns> public static List <TransformSequenceAlignment> GetTransformAlignments(IChain chain1, IChain chain2, SS allowedTypes, int minAlignmentLength = DefaultMinAlignmentLength, float maxRmsd = DefaultRmsdThreshold) { List <TransformSequenceAlignment> alignments = new List <TransformSequenceAlignment>(); List <SSBlock> nBlocks = SecondaryStructure.GetPhiPsiSSBlocksOfType(chain1, allowedTypes, minAlignmentLength).Where(block => block.Length >= minAlignmentLength).ToList(); List <SSBlock> cBlocks = SecondaryStructure.GetPhiPsiSSBlocksOfType(chain2, allowedTypes, minAlignmentLength).Where(block => block.Length >= minAlignmentLength).ToList(); // Previously, calling this function with peptides A,B vs B,A returns different numbers of alignments. The original intent was for the first chain passed in to be at the // N-terminus and the second at the C-terminus (post-fusion), so these post-fusion lengths were being calculated here and culled differently based on order. foreach (SSBlock nBlock in nBlocks) { foreach (SSBlock cBlock in cBlocks) { for (int nAlignmentOfBlockC = nBlock.End - minAlignmentLength + 1; nAlignmentOfBlockC + cBlock.Length >= nBlock.Start + minAlignmentLength; nAlignmentOfBlockC--) { // Figure out the start and ends of the overlap region int nStart = Math.Max(nBlock.Start, nAlignmentOfBlockC); int nEnd = Math.Min(nBlock.End, nAlignmentOfBlockC + cBlock.Length - 1); int alignmentLength = nEnd - nStart + 1; int cStart = Math.Max(cBlock.Start, cBlock.Start + (nStart - nAlignmentOfBlockC)); int cEnd = cStart + alignmentLength - 1; //Debug.WriteLine("Comparing {0}-{1} vs {2}-{3}", nStart, nEnd, cStart, cEnd); Debug.Assert(nBlock.Start <= nStart && nEnd <= nBlock.End); Debug.Assert(cBlock.Start <= cStart && cEnd <= cBlock.End); Debug.Assert(nEnd - nStart == cEnd - cStart); //bool cFullyIncluded = (cBlock.Start == cStart && cBlock.End == cEnd); //bool nFullyIncluded = (nBlock.Start == nStart && nBlock.End == nEnd); //if (!nFullyIncluded && !cFullyIncluded && cStart != cBlock.Start && nEnd != nBlock.End) // continue; Trace.Assert(nEnd - nStart + 1 >= minAlignmentLength); float rmsd = float.NaN; Matrix matrix = Rmsd.GetRmsdAndTransform(chain1, nStart, nEnd, chain2, cStart, cEnd, out rmsd); bool fail = rmsd > maxRmsd; #if DEBUG && false float rmsd2 = float.NaN; Matrix matrix2 = Rmsd.GetRmsdAndTransform(chain2, cStart, cEnd, chain1, nStart, nEnd, out rmsd2); bool fail2 = rmsd2 > maxRmsd; Trace.Assert(fail == fail2); #endif if (rmsd > maxRmsd) { continue; } TransformSequenceAlignment alignment = new TransformSequenceAlignment(nStart, nEnd, cStart, cEnd); alignment.Centroid1 = Geometry.GetCenterNCAC(chain1[nStart, nEnd]); alignment.Centroid2 = Geometry.GetCenterNCAC(chain2[cStart, cEnd]); alignment.Align1 = matrix; alignment.Align2 = Matrix.Invert(matrix); alignments.Add(alignment); } } } return(alignments); }
/// <summary> /// Tests whether either N fused to C or C fused to N has a valid combination. If both are being tested, the function /// returns whether either has a valid combination /// </summary> /// <param name="multiplicity"></param> /// <param name="cn"></param> /// <param name="other"></param> /// <param name="alignment"></param> /// <param name="ntermCnTest"></param> /// <param name="ctermCnTest"></param> /// <param name="minSubstructureLength"></param> /// <returns></returns> public static bool TestClashCn(int multiplicity, IStructure cn, IStructure other, TransformSequenceAlignment alignment, bool ntermCnTest = true, bool ctermCnTest = true, int minSubstructureLength = 0) { Trace.Assert(minSubstructureLength >= 0); IChain cnChain = cn[alignment.ChainIndex1]; IChain otherChain = other[alignment.ChainIndex2]; if (ntermCnTest) { int finalOtherIndex = Math.Min(otherChain.Count - 1, alignment.Range2.End + minSubstructureLength - 1); Trace.Assert(alignment.Range1.Start < cnChain.Count); Trace.Assert(0 <= alignment.Range2.End && alignment.Range2.End < otherChain.Count && finalOtherIndex < otherChain.Count); IChain copyCn = new Chain(cnChain[0, alignment.Range1.Start]); IChain copyOther = new Chain(otherChain[alignment.Range2.End, finalOtherIndex], true); copyOther.Transform(alignment.Align2); if (!Clash.AnyContact(copyCn, copyOther, Clash.ContactType.MainchainMainchainClash)) { copyCn.AddRange(copyOther); AxisPattern <IChain> pattern = new AxisPattern <IChain>(Vector3.UnitZ, multiplicity, copyCn); IChain[] neighbors = pattern[1, multiplicity - 1].ToArray(); //IChain[] pattern = CxUtilities.Pattern(copyCn, Vector3.UnitZ, multiplicity, new int[] { 0 }, true); if (!Clash.AnyContact(new IChain[] { copyCn }, neighbors, Clash.ContactType.MainchainMainchainClash)) { return(false); } } } if (ctermCnTest) { int firstOtherIndex = Math.Max(0, alignment.Range2.Start - minSubstructureLength + 1); Trace.Assert(0 <= alignment.Range1.End && alignment.Range1.End < cnChain.Count); Trace.Assert(0 <= firstOtherIndex && firstOtherIndex < otherChain.Count && alignment.Range2.Start < otherChain.Count); IChain copyCn = new Chain(cnChain[alignment.Range1.End, cnChain.Count - 1]); IChain copyOther = new Chain(otherChain[firstOtherIndex, alignment.Range2.Start], true); copyOther.Transform(alignment.Align2); if (!Clash.AnyContact(copyCn, copyOther, Clash.ContactType.MainchainMainchainClash)) { copyCn.AddRange(copyOther); AxisPattern <IChain> pattern = new AxisPattern <IChain>(Vector3.UnitZ, multiplicity, copyCn); IChain[] neighbors = pattern[1, multiplicity - 1].ToArray(); //IChain[] pattern = CxUtilities.Pattern(copyCn, Vector3.UnitZ, multiplicity, new int[] { 0 }, true); if (!Clash.AnyContact(new IChain[] { copyCn }, neighbors, Clash.ContactType.MainchainMainchainClash)) { return(false); } } } return(true); }