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));
}
}
}