Esempio n. 1
0
        public static Selection GetContactSelectionInFocusSet(IList <IChain> focus, IList <IChain> other, ContactType contactType = ContactType.Atomic)
        {
            Selection selection = new Selection();

            for (int focusIndex = 0; focusIndex < focus.Count; focusIndex++)
            {
                for (int otherIndex = 0; otherIndex < other.Count; otherIndex++)
                {
                    IChain focusChain = focus[focusIndex];
                    IChain otherChain = other[otherIndex];

                    for (int focusAaIndex = 0; focusAaIndex < focusChain.Count; focusAaIndex++)
                    {
                        IAa aaFocus = focusChain[focusAaIndex];
                        for (int otherAaIndex = 0; otherAaIndex < otherChain.Count; otherAaIndex++)
                        {
                            IAa aaOther = otherChain[otherAaIndex];
                            Trace.Assert(aaFocus != aaOther);
                            if (AnyContact(aaFocus, aaOther, contactType))
                            {
                                selection.Aas.Add(aaFocus);
                                break;
                            }
                        }
                    }
                }
            }
            return(selection);
        }
Esempio n. 2
0
 public MainchainMirrorAa(IAa template, int residueNumber, bool nTerminus, bool cTerminus)
     : base(residueNumber, nTerminus, cTerminus)
 {
     Trace.Assert(template != null);
     _template   = template;
     base.Parent = template;
 }
Esempio n. 3
0
        public static void SetChiAngleRadians(IAa residue, int chiIndex, float radians)
        {
            RotamerDefinition rotamerDefinition = definitions_[residue.ResidueNumber]; Debug.Assert(rotamerDefinition.ResidueName == residue.Name, "JSON for rotamer definitions and residue definitions is out of sync, rotamer definition=" + rotamerDefinition.ResidueName + ", residue definition=" + residue.Name);

            List <string> torsionBackboneNames = rotamerDefinition.GetBackboneAtomNames(chiIndex);
            List <string> dependentNames       = rotamerDefinition.GetDependentAtomNames(chiIndex);

            Debug.Assert(dependentNames.Contains(torsionBackboneNames[3]), "The last atom that defines a torsion should move when that torsion is changed. Fix JSON 'dependents' for residue '" + residue.Name + "' atom '" + torsionBackboneNames[3] + "'");

            string name1 = torsionBackboneNames[0];
            string name2 = torsionBackboneNames[1];
            string name3 = torsionBackboneNames[2];
            string name4 = torsionBackboneNames[3];

            double currentTorsionRadians = VectorMath.GetDihedralAngleRadians(residue[name1].Xyz, residue[name2].Xyz, residue[name3].Xyz, residue[name4].Xyz);
            double deltaDegrees          = radians - currentTorsionRadians;

            Vector3    coord2   = residue[name2].Xyz;
            Vector3    coord3   = residue[name3].Xyz;
            Vector3    axis     = Vector3.Normalize(coord3 - coord2);
            Quaternion rotation = Quaternion.CreateFromAxisAngle(axis, radians);

            foreach (string dependentName in dependentNames)
            {
                IAtom atom = residue[dependentName];
                atom.Xyz -= coord3;
                atom.Xyz  = Vector3.Transform(atom.Xyz, rotation);
                atom.Xyz += coord3;
            }
        }
Esempio n. 4
0
        public static Selection GetContactSelection(IChain[] chains, ContactType contactType = ContactType.Atomic)
        {
            Selection selection = new Selection();

            for (int chainIndex1 = 0; chainIndex1 < chains.Length - 1; chainIndex1++)
            {
                for (int chainIndex2 = chainIndex1 + 1; chainIndex2 < chains.Length; chainIndex2++)
                {
                    IChain chain1 = chains[chainIndex1];
                    IChain chain2 = chains[chainIndex2];
                    Trace.Assert(chain1 != chain2);

                    for (int aaIndex1 = 0; aaIndex1 < chain1.Count; aaIndex1++)
                    {
                        IAa aa1 = chain1[aaIndex1];
                        for (int aaIndex2 = 0; aaIndex2 < chain2.Count; aaIndex2++)
                        {
                            IAa aa2 = chain2[aaIndex2];
                            Trace.Assert(aa1 != aa2);

                            if (AnyContact(aa1, aa2, contactType))
                            {
                                selection.Aas.Add(aa1);
                                selection.Aas.Add(aa2);
                            }
                        }
                    }
                }
            }
            return(selection);
        }
Esempio n. 5
0
        public static Selection GetContactSelection(IEnumerable <Selection> regions, ContactType contactType = ContactType.Atomic)
        {
            IAa[][]   arrays    = regions.Select((Func <Selection, IAa[]>)(region => Enumerable.ToArray <IAa>(region.Aas))).ToArray();
            Selection selection = new Selection();

            for (int arrayIndex1 = 0; arrayIndex1 < arrays.Length - 1; arrayIndex1++)
            {
                for (int arrayIndex2 = arrayIndex1 + 1; arrayIndex2 < arrays.Length; arrayIndex2++)
                {
                    IAa[] set1 = arrays[arrayIndex1];
                    IAa[] set2 = arrays[arrayIndex2];

                    for (int index1 = 0; index1 < set1.Length; index1++)
                    {
                        for (int index2 = 0; index2 < set2.Length; index2++)
                        {
                            IAa aa1 = set1[index1];
                            IAa aa2 = set2[index2];
                            Trace.Assert(aa1 != aa2);

                            if (AnyContact(aa1, aa2, contactType))
                            {
                                selection.Aas.Add(aa1);
                                selection.Aas.Add(aa2);
                            }
                        }
                    }
                }
            }

            return(selection);
        }
Esempio n. 6
0
        public static Matrix GetRmsdTransform(IAa move, IAa stay)
        {
            IAa[]  arrayMove = new IAa[] { move };
            IAa[]  arrayStay = new IAa[] { stay };
            Matrix matrix    = GetRmsdTransform(arrayMove, arrayStay);

            return(matrix);
        }
Esempio n. 7
0
 public void UnionWith(IAa aa)
 {
     _aas.Add(aa);
     foreach (IAtom atom in aa)
     {
         this.UnionWith(atom);
     }
 }
Esempio n. 8
0
        //public void LoadAtomNamingTable()
        //{
        //    foreach(PdbFormat format in Enum.GetValues(typeof(PdbFormat)))
        //    {
        //        alternateAtomNamesByFormat_[format] = new Dictionary<string, string>();
        //    }

        //    foreach (string line in File.ReadAllLines(Path.Combine("Database", "PdbFormatAtomNames.csv")))
        //    {
        //        if (line.StartsWith("#") || String.IsNullOrWhiteSpace(line))
        //            continue;
        //        string[] words = line.Split('\t');
        //        Debug.Assert(words.Length == 3);

        //        string residue = words[0];
        //        string atomNamePdbV3=words[1];
        //        string atomNameBmrb=words[2];
        //        string atomnamePdbV1=words[3];
        //        string key = residue + "_" + atomNamePdbV3;
        //        alternateAtomNamesByFormat_[PdbFormat.DefaultPdbV3][key] = atomNamePdbV3;
        //        alternateAtomNamesByFormat_[PdbFormat.BMRB][key] = atomNameBmrb;
        //        alternateAtomNamesByFormat_[PdbFormat.DefaultPdbV3][key] = atomNamePdbV3;
        //    }
        //}

        public static void Save(string file, IAa residue, char chainId = 'A')
        {
            using (StreamWriter writer = new StreamWriter(file))
            {
                int atomNumber    = 1;
                int residueNumber = 1;
                Save(writer, chainId, residue, ref atomNumber, ref residueNumber);
            }
        }
Esempio n. 9
0
        static void AddDisulfides(Chain peptide)
        {
            for (int i = 0; i < peptide.Count - 1; i++)
            {
                IAa residue1 = peptide[i];
                if (residue1.Name != "CYH")
                {
                    continue;
                }
                for (int j = i + 1; j < peptide.Count; j++)
                {
                    IAa residue2 = peptide[j];
                    if (residue2.Name != "CYH")
                    {
                        continue;
                    }

                    Vector3 SG1 = residue1["SG"].Xyz;
                    Vector3 SG2 = residue2["SG"].Xyz;
                    if (!VectorMath.IsValid(SG1) || !VectorMath.IsValid(SG2))
                    {
                        continue;
                    }

                    if (Vector3.Distance(SG1, SG2) < 2.5)
                    {
                        IAa replace1 = new Aa("CYS", residue1.IsNTerminus, residue1.IsCTerminus);
                        replace1.AlignToNCAC(residue1);
                        foreach (IAtom atom in residue1)
                        {
                            IAtom match = replace1[atom.Name];
                            if (match != null)
                            {
                                match.Xyz = atom.Xyz;
                            }
                        }

                        IAa replace2 = new Aa("CYS", residue2.IsNTerminus, residue2.IsCTerminus);
                        replace2.AlignToNCAC(residue2);
                        foreach (IAtom atom in residue2)
                        {
                            IAtom match = replace2[atom.Name];
                            if (match != null)
                            {
                                match.Xyz = atom.Xyz;
                            }
                        }

                        peptide[i, true] = replace1;
                        peptide[j, true] = replace2;
                        break;
                    }
                }
            }
        }
Esempio n. 10
0
        public static List <int> GetContactIndices(IChain peptide, Range[] ranges, ContactType type)
        {
            // Since the
            if ((type & ContactType.SidechainMainchain | type & ContactType.MainchainSidechain) != 0)
            {
                type |= ContactType.SidechainMainchain | ContactType.MainchainSidechain;
            }

            bool[] contacts = new bool[peptide.Count];
            for (int rangeIndex1 = 0; rangeIndex1 < ranges.Length - 1; rangeIndex1++)
            {
                Range range1 = ranges[rangeIndex1];
                for (int i = range1.Start; i <= range1.End; i++)
                {
                    IAa residue1 = peptide[i];
                    for (int rangeIndex2 = rangeIndex1 + 1; rangeIndex2 < ranges.Length; rangeIndex2++)
                    {
                        Range range2 = ranges[rangeIndex2];
                        for (int j = range2.Start; j <= range2.End; j++)
                        {
                            IAa residue2 = peptide[j];
                            if (contacts[i] && contacts[j])
                            {
                                continue;
                            }

                            bool contact = false;

                            // Check mainchain-mainchain only. This only applies to residues separated by 1 or more
                            // residues. Otherwise, covalently bound atoms would be considered clashing.
                            if ((type & ContactType.MainchainMainchain) != 0 && Math.Abs(i - j) > 1)
                            {
                                contact |= AnyContact(residue1, residue2, type & ContactType.MainchainMainchainClash);
                            }

                            // Check everything except for mainchain-mainchain
                            if (contact == false)
                            {
                                contact |= AnyContact(residue1, residue2, type & ~ContactType.MainchainMainchain);
                                contact |= AnyContact(residue2, residue1, type & ~ContactType.MainchainMainchain);
                            }

                            contacts[i] |= contact;
                            contacts[j] |= contact;
                        }
                    }
                }
            }

            List <int> list = ConvertArrayToList(contacts);

            return(list);
        }
Esempio n. 11
0
        public static bool[,] GetContactVectorDim2(IChain chain, IChain other, ContactType contactType = ContactType.Atomic)
        {
            bool[,] contacts = new bool[chain.Count, other.Count];
            for (int i = 0; i < chain.Count; i++)
            {
                IAa residue1 = chain[i];
                for (int j = 0; j < other.Count; j++)
                {
                    IAa residue2 = other[j];
                    contacts[i, j] = AnyContact(residue1, residue2, contactType);
                }
            }

            return(contacts);
        }
Esempio n. 12
0
 public static bool AnyContact(IAa[] set1, IAa[] set2, ContactType type)
 {
     for (int i = 0; i < set1.Length; i++)
     {
         IAa aa1 = set1[i];
         for (int j = 0; j < set2.Length; j++)
         {
             IAa aa2 = set2[j];
             if (AnyContact(aa1, aa2, type))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Esempio n. 13
0
        public static bool IsInContact(IAa aa1, int index1, IAa aa2, int index2, ContactType contactType = ContactType.Atomic)
        {
            bool MCMC           = (contactType & ContactType.MainchainMainchain) != 0;
            bool SCSC           = (contactType & ContactType.SidechainSidechain) != 0;
            bool SCMC           = (contactType & ContactType.SidechainMainchain) != 0;
            bool MCSC           = (contactType & ContactType.MainchainSidechain) != 0;
            bool ignoreInvalid  = (contactType & ContactType.IgnoreInvalidCoordinates) != 0;
            bool ignoreHydrogen = (contactType & ContactType.IgnoreHydrogen) != 0;
            bool clash          = (contactType & ContactType.Clash) != 0;
            bool vectorCACB     = (contactType & ContactType.VectorCACB) != 0;

            Trace.Assert(!vectorCACB, "Vector CACB contact is an IAa test, not IAtom test");

            IAtom atom1 = aa1[index1];
            IAtom atom2 = aa2[index2];

            if (ignoreHydrogen && (atom1.Element == Element.H || atom2.Element == Element.H))
            {
                return(false);
            }

            bool applies =
                (MCMC && atom1.IsMainchain && atom2.IsMainchain) ||
                (SCMC && atom1.IsSidechain && atom2.IsMainchain) ||
                (MCSC && atom1.IsMainchain && atom2.IsSidechain) ||
                (SCSC && atom1.IsSidechain && atom2.IsSidechain);

            if (!applies)
            {
                return(false);
            }

            Vector3 v1 = atom1.Xyz;
            Vector3 v2 = atom2.Xyz;

            CheckInvalidCoordinates(v1, ignoreInvalid);
            CheckInvalidCoordinates(v2, ignoreInvalid);

            float d2      = Vector3.DistanceSquared(v1, v2);
            float cutoff2 = clash ? ElementProperties.VdwClashSum2[(int)atom1.Element, (int)atom2.Element]
                : ElementProperties.VdwRadiusSum2[(int)atom1.Element, (int)atom2.Element];

            bool contact = d2 < cutoff2;

            return(contact);
        }
Esempio n. 14
0
 public static int[] GetSidechainContactCounts(IChain peptide1, IChain peptide2, Range range1, Range range2, ContactType contactType)
 {
     int[] counts = new int[peptide1.Count];
     for (int i = range1.Start; i <= range1.End; i++)
     {
         IAa residue1 = peptide1[i];
         for (int j = range2.Start; j <= range2.End; j++)
         {
             IAa residue2 = peptide2[j];
             if (AnyContact(residue1, residue2, contactType))
             {
                 counts[i]++;
             }
         }
     }
     return(counts);
 }
Esempio n. 15
0
        public Aa(IAa other, bool nTerminus, bool cTerminus)
        {
            _atoms = new ArraySource <IAtom>(this, other);

            ResidueNumber = other.ResidueNumber;
            IsNTerminus   = nTerminus;
            IsCTerminus   = cTerminus;

            AtomDefinition[] definitions = AaTable.GetAtomDefinitions(ResidueNumber, IsNTerminus, IsCTerminus);

            Matrix unidentifiedAtomTransform = Matrix.Identity;

            //if (TransformSetting == TransformSettings.Transform)
            {
                Vector3[] vLocal = new Vector3[] { definitions[N_].Xyz, definitions[CA_].Xyz, definitions[C_].Xyz };
                Vector3[] vOther = new Vector3[] { other[N_].Xyz, other[CA_].Xyz, other[C_].Xyz };
                unidentifiedAtomTransform = VectorMath.GetRmsdAlignmentMatrix(vLocal, false, vOther, false);
            }

            // Create atoms at final positions
            for (int i = 0; i < definitions.Length; i++)
            {
                Vector3 position = Vector3.Transform(definitions[i].Xyz, unidentifiedAtomTransform);
                Atom    atom     = new Atom(definitions[i], position);
                Add(atom);
            }

            this[N_].Xyz  = other[N_].Xyz;
            this[CA_].Xyz = other[CA_].Xyz;
            this[C_].Xyz  = other[C_].Xyz;
            this[O_].Xyz  = other[O_].Xyz;

            for (int i = Aa.SidechainStart_; i < other.Count; i++)
            {
                IAtom otherAtom = other[i];
                IAtom thisAtom  = this[otherAtom.Name];
                if (thisAtom != null)
                {
                    thisAtom.Xyz = otherAtom.Xyz;
                }
            }

            // Remove parent context - this will result in atoms NOT BEING IN THE ORIGINAL LOCATION
            this.Parent = null;
        }
Esempio n. 16
0
 public IAa this[int index, bool reposition]
 {
     set
     {
         if (reposition)
         {
             IAa     current = this[index];
             Vector3 N       = current[Aa.N_].Xyz;
             Vector3 CA      = current[Aa.CA_].Xyz;
             Vector3 C       = current[Aa.C_].Xyz;
             this[index] = value;
             this[index].AlignToNCAC(N, CA, C);
         }
         else
         {
             this[index] = value;
         }
     }
 }
Esempio n. 17
0
        // This function requires set1 and set2 to be disjoint - otherwise desired behavior for self-contact
        // would be unknown
        public static Selection GetContactSelection(IAa[] set1, IAa[] set2, ContactType contactType = ContactType.Atomic)
        {
            Selection selection = new Selection();

            for (int index1 = 0; index1 < set1.Length; index1++)
            {
                for (int index2 = 0; index2 < set2.Length; index2++)
                {
                    IAa aa1 = set1[index1];
                    IAa aa2 = set2[index2];
                    Trace.Assert(aa1 != aa2);

                    if (AnyContact(aa1, aa2, contactType))
                    {
                        selection.Aas.Add(aa1);
                        selection.Aas.Add(aa2);
                    }
                }
            }
            return(selection);
        }
Esempio n. 18
0
        static void Save(TextWriter stream, char chainId, IAa residue, ref int atomNumber, ref int residueSequenceNumber)
        {
            foreach (IAtom atom in residue)
            {
                if (float.IsNaN(atom.Xyz.Length()) || atom.Element == Element.H && atom.Xyz == Vector3.Zero)
                {
                    continue;
                }

                AtomRecord record = new AtomRecord(atom, chainId, residue.Name.ToString(), residueSequenceNumber, atomNumber++);
                atomNumber %= 100000;
                switch (OutputPdbFormat)
                {
                case PdbFormat.DefaultPdbV3: break;

                case PdbFormat.BMRB: break;

                case PdbFormat.RosettaPdbV1:
                    string name = record.Name;
                    if (alternateAtomNamesByFormat_[OutputPdbFormat].TryGetValue(residue.Letter + "_" + name, out name) ||
                        alternateAtomNamesByFormat_[OutputPdbFormat].TryGetValue("X_" + name, out name))
                    {
                        record.Name = name;
                    }
                    break;

                default: throw new InvalidDataException();
                }
                stream.WriteLine(record.Text);
            }
            residueSequenceNumber++;
            residueSequenceNumber %= 10000;
            if (residueSequenceNumber == 0)
            {
                residueSequenceNumber++;
            }
        }
Esempio n. 19
0
        public static Aa2[] GetContactsAa2(Selection set1, Selection set2, ContactType contactType = ContactType.Atomic)
        {
            List <Aa2> results = new List <Aa2>();

            IAa[] s1 = set1.Aas.ToArray();
            IAa[] s2 = set2.Aas.ToArray();

            for (int index1 = 0; index1 < s1.Length; index1++)
            {
                for (int index2 = 0; index2 < s2.Length; index2++)
                {
                    IAa aa1 = s1[index1];
                    IAa aa2 = s2[index2];
                    Trace.Assert(aa1 != aa2);

                    if (AnyContact(aa1, aa2, contactType))
                    {
                        results.Add(new Aa2(aa1, aa2));
                    }
                }
            }

            return(results.ToArray());
        }
Esempio n. 20
0
 public void AlignToNCAC(IAa other)
 {
     AlignToNCAC(other[N_].Xyz, other[CA_].Xyz, other[C_].Xyz);
 }
Esempio n. 21
0
 public Aa(IAa other)
     : this(other, other.IsNTerminus, other.IsCTerminus)
 {
 }
Esempio n. 22
0
        /// <summary>
        /// Outputs a structure that is a fusion of the chains indicated by the sequence alignments. In the case of a cycle (wherein the last structure
        /// is a copy of the first at a different position), only one set of chains for the two endpoint structures is included.
        /// </summary>
        /// <param name="structures">structures to fuse</param>
        /// <param name="alignments">the sequence positions at which to fuse</param>
        /// <param name="ncDirections">the directionality of the alignment: true -> the first structure is N-terminal, false -> C-terminal</param>
        /// <param name="cycle">whether the structure forms a cycle, in which case the first and last fusions affect both ends</param>
        /// <param name="partialChain">a partial chain has been created due to cyclization whose entirety will be restored only through asu pattering</param>
        /// <returns></returns>
        public static IStructure GetStructure(IStructure[] structures, SequenceAlignment[] alignments, bool[] ncDirections, bool cycle, out IChain partialChain)
        {
            partialChain = null;

            // Note: The fusion product's middle residue from the alignment range comes from the N-terminal chain, i.e the N-term range is [0, Middle] and C-term is [Middle + 1, Len-1]
            Trace.Assert(structures != null && alignments != null && ncDirections != null);
            Trace.Assert(structures.Length > 0);
            Trace.Assert(structures.Length == alignments.Length + 1);
            Trace.Assert(alignments.Length == ncDirections.Length);

            // Data for the cyclization case - the chain that the final fusion should be joined with fused back onto fusion products of the first chain should be tracked so that the last chain can be fused back onto that chain
            IChain cycleDoubleFusedChain = null;                                                                     // Track what chain the first fusion chain ends up in
            bool   isCycleDoubleFused    = cycle && alignments.First().ChainIndex1 == alignments.Last().ChainIndex2; // Whether the first chain is fused both to the next chain and to the last/prior (wrap-around) chain
            Matrix cycleAlignment        = isCycleDoubleFused? Rmsd.GetRmsdTransform(structures.First()[0][0], structures.Last()[0][0]) : Matrix.Identity;


            // Mark which aas to remove without actually removing them, so that their indices remain unchanged while
            // those to be removed are being computed
            Selection remove = new Selection();

            for (int alignmentIndex = 0; alignmentIndex < alignments.Length; alignmentIndex++)
            {
                bool ncDirection              = ncDirections[alignmentIndex];
                SequenceAlignment alignment   = alignments[alignmentIndex];
                SequenceAlignment ncAlignment = ncDirection? alignment : SequenceAlignment.Reversed(alignment); // N as chain1
                IStructure        structureN  = ncDirection ? structures[alignmentIndex] : structures[alignmentIndex + 1];
                IStructure        structureC  = ncDirection ? structures[alignmentIndex + 1] : structures[alignmentIndex];
                IChain            chainN      = structureN[ncAlignment.ChainIndex1];
                IChain            chainC      = structureC[ncAlignment.ChainIndex2];
                remove.Aas.UnionWith(chainN[ncAlignment.Range1.Middle + 1, chainN.Count - 1]);
                remove.Aas.UnionWith(chainC[0, ncAlignment.Range2.Middle]);

                // If a cycle exists, then for each chain in the first and last structure (which are identical, modulo a transform), only one copy should be
                // preserved. If that copy is fused on both sides, then it must be trimmed according to both the first and final sequence alignments. In such a
                // case, remove the entire last structure.
                // Cycle and fusion is to the same chain on both sides:
                // -> remove all of the second copy
                // -> transform the second copy neighbor chain onto the first
                // Cycle and fusion is to separate chains on either side:
                // -> remove all of the second copy except for the fused chain
                // -> remove from the first copy the chain that was fused on the second copy
                if (cycle && alignmentIndex == alignments.Length - 1)
                {
                    if (isCycleDoubleFused)
                    {
                        // Mark all chains from second copy for deletion
                        foreach (IChain chain in structures[structures.Length - 1])
                        {
                            remove.Aas.UnionWith(chain);
                        }

                        // Mark the first structure residues for deletion on one side of the fusion point
                        IChain chain0 = structures[0][alignment.ChainIndex2];
                        if (ncDirection)
                        {
                            remove.Aas.UnionWith(chain0[0, alignment.Range2.Middle]);
                        }
                        else
                        {
                            remove.Aas.UnionWith(chain0[alignment.Range2.Middle + 1, chain0.Count - 1]);
                        }
                    }
                    else
                    {
                        // Mark all chains from the second copy for deletion, except the one being fused
                        IChain keep = structures[alignmentIndex + 1][alignment.ChainIndex2];
                        foreach (IChain chain in structures[alignmentIndex + 1])
                        {
                            if (chain != keep)
                            {
                                remove.Aas.UnionWith(chain);
                            }
                        }

                        // For the one being fused, remove that index from the first structure
                        remove.Aas.UnionWith(structures[0][alignment.ChainIndex2]);
                    }
                }
            }

            // Remove them
            for (int alignmentIndex = 0; alignmentIndex < alignments.Length; alignmentIndex++)
            {
                SequenceAlignment alignment  = alignments[alignmentIndex];
                IStructure        structure1 = structures[alignmentIndex];
                IStructure        structure2 = structures[alignmentIndex + 1];
                IChain            chain1     = structure1[alignment.ChainIndex1];
                IChain            chain2     = structure2[alignment.ChainIndex2];

                for (int i = chain1.Count - 1; i >= 0; i--)
                {
                    IAa aa = chain1[i];
                    if (remove.Aas.Contains(aa))
                    {
                        Matrix desired = aa.TotalTransform;
                        chain1.RemoveAt(i);
                        aa.Transform(desired * Matrix.Invert(aa.TotalTransform));
#if DEBUG_TRANSFORMS
                        Debug.Assert((desired - aa.TotalTransform).Translation.Length() < 0.1);
#endif
                    }
                }

                for (int i = chain2.Count - 1; i >= 0; i--)
                {
                    IAa aa = chain2[i];
                    if (remove.Aas.Contains(aa))
                    {
                        Matrix desired = aa.TotalTransform;
                        chain2.RemoveAt(i);
                        aa.Transform(desired * Matrix.Invert(aa.TotalTransform));
#if DEBUG_TRANSFORMS
                        Debug.Assert((desired - aa.TotalTransform).Translation.Length() < 0.1);
#endif
                    }
                }

                if (cycle && alignmentIndex == 0)
                {
                    foreach (IChain chain in structure1)
                    {
                        for (int i = chain.Count - 1; i >= 0; i--)
                        {
                            IAa aa = chain[i];
                            if (remove.Aas.Contains(aa))
                            {
                                Matrix desired = aa.TotalTransform;
                                chain.RemoveAt(i);
                                aa.Transform(desired * Matrix.Invert(aa.TotalTransform));
#if DEBUG_TRANSFORMS
                                Debug.Assert((desired - aa.TotalTransform).Translation.Length() < 0.1);
#endif
                            }
                        }
                    }
                }

                if (cycle && alignmentIndex == alignments.Length - 1)
                {
                    foreach (IChain chain in structure2)
                    {
                        for (int i = chain.Count - 1; i >= 0; i--)
                        {
                            IAa aa = chain[i];
                            if (remove.Aas.Contains(aa))
                            {
                                Matrix desired = aa.TotalTransform;
                                chain.RemoveAt(i);
                                aa.Transform(desired * Matrix.Invert(aa.TotalTransform));
#if DEBUG_TRANSFORMS
                                Debug.Assert((desired - aa.TotalTransform).Translation.Length() < 0.1);
#endif
                            }
                        }
                    }
                }
            }

            // Join the chains and allocate the result to the second structure so as to preserve the indexes for the next fusion step
            for (int alignmentIndex = 0; alignmentIndex < alignments.Length; alignmentIndex++)
            {
                bool ncDirection             = ncDirections[alignmentIndex];
                SequenceAlignment alignment  = alignments[alignmentIndex];
                IStructure        structure1 = structures[alignmentIndex];
                IStructure        structure2 = structures[alignmentIndex + 1];
                IChain            chain1     = structure1[alignment.ChainIndex1];
                IChain            chain2     = structure2[alignment.ChainIndex2];

                if (ncDirection)
                {
#if DEBUG_MIRRORS
                    foreach (IAa aa2 in chain2.ToArray())
                    {
                        chain1.AddInPlace(aa2);
                    }
#else
                    chain1.AddArraySourceInPlace(chain2);
#endif
                    structure2[alignment.ChainIndex2, true] = chain1;
                }
                else
                {
#if DEBUG_MIRRORS
                    foreach (IAa aa1 in chain1.ToArray())
                    {
                        chain2.AddInPlace(aa1);
                    }
#else
                    chain2.AddArraySourceInPlace(chain1);
#endif
                }

                // Track which chain contains the first chain in the cycle so that the final chain in the cycle can fuse to it
                if (isCycleDoubleFused && (alignmentIndex == 0 || chain1 == cycleDoubleFusedChain || chain2 == cycleDoubleFusedChain))
                {
                    cycleDoubleFusedChain = ncDirection? chain1 : chain2;
                }

                if (isCycleDoubleFused && alignmentIndex == alignments.Length - 1)
                {
                    // If it's a cycle on the same chain, move the chain back to where it fuses to the first structure
                    IChain combined = ncDirection ? chain1 : chain2;
                    combined.Transform(cycleAlignment);

                    if (combined == cycleDoubleFusedChain)
                    {
                        // If the structure[0] fusion chain has been fused all the way through, there is no need to move the
                        // current chain to meet the first, since they're already joined
                        partialChain = cycleDoubleFusedChain;
                    }
                    else
                    {
                        if (ncDirection)
                        {
                            combined.AddArraySourceInPlace(cycleDoubleFusedChain);
                            IStructure cycleDoubleFusedParent = (IStructure)cycleDoubleFusedChain.Parent;
                        }
                        else
                        {
                            cycleDoubleFusedChain.AddArraySourceInPlace(combined);
                        }
                    }
                }
            }

            // Add all unique chains to a new structure
            Structure total = new Structure();
            structures.SelectMany(s => s).Distinct().Where(c => c.Count > 0).ToList().ForEach(c => total.AddInPlace(c));
            return(total);
        }
Esempio n. 23
0
        public static IChain GetChain(IChain[] peptides, SequenceAlignment[] alignments, Selection immutableAas)
        {
            IChain fusion = new Chain();

            // Do all pairwise analysis
            for (int i = 0; i < peptides.Length - 1; i++)
            {
                // Determine the ranges outside of the splice
                int start1 = i == 0 ? 0 : alignments[i - 1].Range2.End + 1;
                int end1   = alignments[i].Range1.Start - 1;
                int start2 = alignments[i].Range2.End + 1;
                int end2   = i < alignments.Length - 1 ? alignments[i + 1].Range1.Start - 1 : peptides[i + 1].Count - 1;

                // Add the non-overlapping region of the first peptide
                if (start1 <= end1)
                {
                    foreach (Aa aa in peptides[i][start1, end1])
                    {
                        Aa copy = new Aa(aa, i == 0 && start1 == 0, false);
                        copy.NodeTransform = aa.TotalTransform;
                        fusion.Add(copy);
                    }
                }

                // Add the alignment region, selecting either from the first or second peptide so as to minimize clashes with the sidechains that
                // are for sure being kept on either side
                SequenceAlignment alignment = alignments[i];
                Debug.Assert(alignment.Range1.Length == alignment.Range2.Length);
                for (int alignmentOffset = 0; alignmentOffset < alignment.Range1.Length; alignmentOffset++)
                {
                    int  index1    = alignment.Range1.Start + alignmentOffset;
                    int  index2    = alignment.Range2.Start + alignmentOffset;
                    IAa  option1   = peptides[i][index1];
                    IAa  option2   = peptides[i + 1][index2];
                    bool nTerminus = i == 0 && index1 == 0;
                    bool cTerminus = (i == peptides.Length - 2) && (index2 == peptides[i + 1].Count - 1);

                    if (immutableAas.Aas.Contains(option1))
                    {
                        Aa copy = new Aa(option1, nTerminus, cTerminus);
                        copy.NodeTransform = option1.TotalTransform;
                        fusion.Add(copy);
                    }
                    else if (immutableAas.Aas.Contains(option2))
                    {
                        Aa copy = new Aa(option2, nTerminus, cTerminus);
                        copy.NodeTransform = option2.TotalTransform;
                        fusion.Add(copy);
                    }
                    else
                    {
                        if (option2.Letter == 'P' && index1 >= 4)
                        {
                            SS[] ss1 = SecondaryStructure.GetPhiPsiSS(peptides[i], 5);

                            bool allHelical = (ss1[index1] | ss1[index1 - 1] | ss1[index1 - 2] | ss1[index1 - 3] | ss1[index1 - 4]) == SS.Helix;
                            if (allHelical)
                            {
                                Aa copy = new Aa(option1, nTerminus, cTerminus);
                                copy.NodeTransform = option1.TotalTransform;
                                fusion.Add(copy);
                                continue;
                            }
                        }

                        // Otherwise, select the residue with fewer clashes
                        int clashCount1 = end2 >= start2? peptides[i + 1][start2, end2].Select(other => Clash.AnyContact(other, option1, Clash.ContactType.SidechainSidechainClash) ? 1 : 0).Aggregate(0, (a, b) => a + b) : 0;
                        int clashCount2 = end1 >= start1? peptides[i][start1, end1].Select(other => Clash.AnyContact(other, option2, Clash.ContactType.SidechainSidechainClash) ? 1 : 0).Aggregate(0, (a, b) => a + b) : 0;

                        if (clashCount1 <= clashCount2)
                        {
                            Aa copy = new Aa(option1, nTerminus, cTerminus);
                            copy.NodeTransform = option1.TotalTransform;
                            fusion.Add(copy);
                            continue;
                        }

                        if (clashCount2 < clashCount1)
                        {
                            Aa copy = new Aa(option2, nTerminus, cTerminus);
                            copy.NodeTransform = option2.TotalTransform;
                            fusion.Add(copy);
                            continue;
                        }
                    }
                }

                // Add the non-overlapping region of the last peptide
                if (i == peptides.Length - 2 && start2 <= end2)
                {
                    foreach (Aa aa in peptides[i + 1][start2, end2])
                    {
                        Aa copy = new Aa(aa, false, aa.IsCTerminus);
                        copy.NodeTransform = aa.TotalTransform;
                        fusion.Add(copy);
                    }
                }
            }
            return(fusion);
        }
Esempio n. 24
0
        public static bool AnyContact(IAa aa1, IAa aa2, ContactType type)
        {
            bool ignoreInvalid = (type & ContactType.IgnoreInvalidCoordinates) != 0;
            bool clash         = (type & ContactType.Clash) != 0;
            bool MCMC          = (type & ContactType.MainchainMainchain) != 0;
            bool SCSC          = (type & ContactType.SidechainSidechain) != 0;
            bool SCMC          = (type & ContactType.SidechainMainchain) != 0;
            bool MCSC          = (type & ContactType.MainchainSidechain) != 0;
            bool CACB          = (type & ContactType.VectorCACB) != 0;

            Vector3 iCA = aa1[Aa.CA_].Xyz;
            Vector3 jCA = aa2[Aa.CA_].Xyz;

            int   count1           = aa1.Count;
            int   count2           = aa2.Count;
            float contactDistance2 = clash ? AtomClashDistance2 : AtomContactDistance2;

            // If they're pretty far apart, sidechains can't reach
            if (ContactThresholdCA2 < Vector3.DistanceSquared(iCA, jCA))
            {
                return(false);
            }

            if (MCMC || SCMC || MCSC || CACB)
            {
                Vector3[] MC1 = new Vector3[4] {
                    iCA, aa1[Aa.C_].Xyz, aa1[Aa.N_].Xyz, aa1[Aa.O_].Xyz
                };
                Vector3[] MC2 = new Vector3[4] {
                    jCA, aa2[Aa.C_].Xyz, aa2[Aa.N_].Xyz, aa2[Aa.O_].Xyz
                };

                if (MCMC)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        CheckInvalidCoordinates(ref MC1[i], ignoreInvalid);

                        for (int j = 0; j < 4; j++)
                        {
                            CheckInvalidCoordinates(ref MC2[j], ignoreInvalid);

                            if (Vector3.DistanceSquared(MC1[i], MC2[j]) < contactDistance2)
                            {
                                return(true);
                            }
                        }
                    }
                }

                if (MCSC)
                {
                    // Invert the loop order for MC1:SC2 to reduce the number of residue lookups and element checks, which are slower than simple  array lookups
                    for (int j = Aa.SidechainStart_; j < count2; j++)
                    {
                        IAtom atom2 = aa2[j];
                        if (atom2.Element == Element.H)
                        {
                            continue;
                        }

                        CheckInvalidCoordinates(atom2.Xyz, ignoreInvalid);
                        for (int i = 0; i < 4; i++)
                        {
                            CheckInvalidCoordinates(MC1[i], ignoreInvalid);
                            if (Vector3.DistanceSquared(MC1[i], atom2.Xyz) < contactDistance2)
                            {
                                return(true);
                            }
                        }
                    }
                }

                if (SCMC)
                {
                    for (int i = Aa.SidechainStart_; i < count1; i++)
                    {
                        IAtom atom1 = aa1[i];
                        if (atom1.Element == Element.H)
                        {
                            continue;
                        }

                        CheckInvalidCoordinates(atom1.Xyz, ignoreInvalid);
                        for (int j = 0; j < 4; j++)
                        {
                            CheckInvalidCoordinates(MC2[j], ignoreInvalid);
                            if (Vector3.DistanceSquared(atom1.Xyz, MC2[j]) < contactDistance2)
                            {
                                return(true);
                            }
                        }
                    }
                }

                if (CACB)
                {
                    // Check that each sidechain points in the direction of the other, with a distance-based scaling factor s.t. a distance of 10 pointing exactly in the same
                    // direction would count as "in contact"
                    // Note: CA-CB isn't really used (due to GLY), instead CA->CB is approximated with ( k1 * unit(N->CA + C->CA) + k2 * (unit(N->CA cross C->CA) )
                    // U = unit(N->CA + C->CA)
                    // V = unit(N->CA cross C->CA)
                    Vector3 NCA1       = MC1[0] - MC1[2]; // MC1/2 order: CA, C, N, O
                    Vector3 NCA2       = MC2[0] - MC2[2];
                    Vector3 CCA1       = MC1[0] - MC1[1];
                    Vector3 CCA2       = MC2[0] - MC2[1];
                    Vector3 U1         = Vector3.Normalize(NCA1 + CCA1);
                    Vector3 U2         = Vector3.Normalize(NCA2 + CCA2);
                    Vector3 V1         = Vector3.Normalize(Vector3.Cross(NCA1, CCA1));
                    Vector3 V2         = Vector3.Normalize(Vector3.Cross(NCA2, CCA2));
                    Vector3 CACB1      = 0.577f * U1 + 0.817f * V1; // Constants are cosine and sine of 109.5/2 degrees
                    Vector3 CACB2      = 0.577f * U2 + 0.817f * V2; // Constants are cosine and sine of 109.5/2 degrees
                    Vector3 CA1CA2     = jCA - iCA;
                    Vector3 unitCA1CA2 = Vector3.Normalize(CA1CA2);

                    float dot1   = Vector3.Dot(CACB1, unitCA1CA2);
                    float dot2   = Vector3.Dot(CACB2, -unitCA1CA2);
                    float scaled = (dot1 + dot2 + 1 /* 90 degree angle can definitely clash/interact, but dot1/2 == 0 */) / 2 * ContactDistanceCA1CA2 / CA1CA2.Length();
                    if (scaled > 1)
                    {
                        return(true);
                    }
                }
            }

            if (SCSC)
            {
                for (int i = Aa.SidechainStart_; i < count1; i++)
                {
                    IAtom atom1 = aa1[i];
                    if (atom1.Element == Element.H)
                    {
                        continue;
                    }
                    Vector3 xyz1 = atom1.Xyz;

                    for (int j = Aa.SidechainStart_; j < count2; j++)
                    {
                        IAtom atom2 = aa2[j];
                        if (atom2.Element == Element.H)
                        {
                            continue;
                        }

                        Vector3 xyz2 = atom2.Xyz;
                        CheckInvalidCoordinates(xyz1, ignoreInvalid);
                        CheckInvalidCoordinates(xyz2, ignoreInvalid);
                        if (Vector3.DistanceSquared(xyz1, xyz2) < contactDistance2)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Esempio n. 25
0
 public MainchainMirrorAa(IAa template, int residueNumber)
     : this(template, residueNumber, false, false)
 {
 }
Esempio n. 26
0
 public MirrorAa(IAa template)
     : base(template)
 {
     _template = template;
 }
Esempio n. 27
0
 public Selection(IAa aa)
 {
     this.UnionWith(aa);
 }
Esempio n. 28
0
 public MirrorAa(IAa template, bool root, ITransformNode parent)
     : base(template, root, false, parent)
 {
     _template = template;
 }
Esempio n. 29
0
 public static void SetChiAngleDegrees(IAa residue, int chiIndex, float degrees)
 {
     SetChiAngleRadians(residue, chiIndex, (float)(degrees * Math.PI / 180));
 }