using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sunweaver.Mutations { /// /// Functions to mutate a codule or chromosome. Mutation types are: /// Point - Change a single BasePair to another BasePair /// Insertion - Insert a stream of new BasePairs in to the middle of a stream of BasePairs. /// Deletion - Delete a sequence of BasePairs in the middle of a stream of BasePairs. /// Reversal - Reverse a sequence of BasePairs in the middle of a stream of BasePairs. /// public static class Mutator { public static void PointMutation(ref Codule codule, BasePair mutateTo, int bpIndex) { if(bpIndex < 0 || bpIndex >= codule.BasePairs.Count) { throw new Exception("Point mutation index is out of range of the codule's base pairs."); } codule.BasePairs[bpIndex] = mutateTo; } public static void InsertionMutation(ref Codule codule, IEnumerable insertDNA, int bpIndex) { // bpIndex is the index before which to insert insertDNA. if (bpIndex < 0 || bpIndex > codule.BasePairs.Count) { throw new Exception("Point mutation index is out of range of the codule's base pairs."); } codule.BasePairs.InsertRange(bpIndex, insertDNA); } public static void DeletionMutation(ref Codule codule, int bpStartIndex, int bpCount) { if (bpStartIndex < 0 || bpStartIndex >= codule.BasePairs.Count) { throw new Exception("Point mutation index is out of range of the codule's base pairs."); } if (bpStartIndex + bpCount > codule.BasePairs.Count) { throw new Exception("Point mutation index is out of range of the codule's base pairs."); } codule.BasePairs.RemoveRange(bpStartIndex, bpCount); } public static void ReversalMutation(ref Codule codule, int bpStartIndex, int bpCount) { if (bpStartIndex < 0 || bpStartIndex >= codule.BasePairs.Count) { throw new Exception("Point mutation index is out of range of the codule's base pairs."); } if (bpStartIndex + bpCount > codule.BasePairs.Count) { throw new Exception("Point mutation index is out of range of the codule's base pairs."); } codule.BasePairs.Reverse(bpStartIndex, bpCount); } public static void MoveMutation(ref Codule codule, int exciseLocation, int length, int insertionLocation) { if (exciseLocation < 0 || exciseLocation >= codule.BasePairs.Count) { throw new Exception("Translocation mutation index is out of range of the codule's base pairs."); } if (length < 0 || exciseLocation + length > codule.BasePairs.Count) { throw new Exception("Translocation mutation's length is part the end of the codule."); } if (insertionLocation < 0 || insertionLocation > codule.BasePairs.Count - length) { throw new Exception("Translocation mutation's insertionLocation is outside a valid range."); } var excised = codule.BasePairs.GetRange(exciseLocation, length); codule.BasePairs.RemoveRange(exciseLocation, length); codule.BasePairs.InsertRange(insertionLocation, excised); } public static void InsertionMutation(ref Chromosome chromosome, IList insertDNA, int bpIndex) { if (bpIndex < 0 || bpIndex >= chromosome.TotalBasePairs) { throw new Exception("Insertion mutation index is out of range of the chromosome's base pairs."); } for (int i = 0; i < chromosome.Codules.Values.Count; ++i) { var codule = chromosome.Codules.Values.ElementAt(i); if (bpIndex < codule.BasePairs.Count) { InsertionMutation(ref codule, insertDNA, bpIndex); return; } else { bpIndex -= codule.BasePairs.Count; } } } public static void PointMutation(ref Chromosome chromosome, BasePair mutateTo, int bpIndex) { if (bpIndex < 0 || bpIndex >= chromosome.TotalBasePairs) { throw new Exception("Point mutation index is out of range of the chromosome's base pairs."); } for (int i = 0; i < chromosome.Codules.Values.Count; ++i) { var codule = chromosome.Codules.Values.ElementAt(i); if (bpIndex < codule.BasePairs.Count) { PointMutation(ref codule, mutateTo, bpIndex); return; } else { bpIndex -= codule.BasePairs.Count; } } } public static void PointMutation(ref Chromosome chromosome, Func getRandomIndex = null) { PointMutation(ref chromosome, DNASystem.RandomBasePair(getRandomIndex ?? DNASystem.rand.Next), getRandomIndex(chromosome.TotalBasePairs)); } } }