I’m currently working on analysis of PCR markers in whole chromosome DNA sequences. In this case the markers are SSR primers. The data are digitally rendered in character strings of letters, each representing an amino acid. In the actual laboratory procedures, “primers” (short nucleotide sequences of 12-24 amino acids) are chosen that will hopefully “code” (fluoresce) across a longer target sequence (500 to 3000 in length) for occurrences of a specific “allele” (a very short sequence along one side of a DNA strand). Chemically, the process is an analog equivalent of convolution. For more information see Plant Genotyping, ed. Batley, ISSN 1064-3745.
In my application I am comparing the results of convolution with actual locations of an allele in both target sequences and across entire plant chromosomes which are 16 million to 2 billion in length - depending on species. So computational efficiency is a concern in the long run - literally!
Here is my current algorithm, illustrating a primer sequence that doesn’t perform well for the target allele:
targetAllele = "AAAC";
primer = "ATTAAACTCTTCATTCATCAGT"; (* analog kernel *)
primerLength = StringLength[primer];
sequence =
"GATGAAAAACACAAAAGTACGAATTAATTTGGTACGTTTCCACCATAATTATTGGTAAAAAGTCGTT\
ACAAACCCTAGTAAACACGATGAAACAAAGAGA";
padding = StringRepeat["X", primerLength];
primerChrs = Characters[primer];
sequenceChrs = Characters[padding <> sequence <> padding];
sequenceChrsLength = Length[sequenceChrs];
convolution = Table[
{i,
Total[Table[
If[primerChrs[[j]] == sequenceChrs[[i + j - 1]], 1, 0],
{j, 1, primerLength}
]]},
{i, 1, sequenceChrsLength - primerLength}
];
compValue = Max[convolution[[;; , 2]]] + 1;
allelePositions = ({# + primerLength, compValue} & /@
StringPosition[sequence, targetAllele][[;; , 1]]);
Print[ListPlot[{convolution, allelePositions},
PlotStyle -> {Black, Red}, AxesStyle -> Directive[Black, 10],
ImageSize -> Medium]];
