我们如何有效地压缩DNA弦

时间:2018-08-15 13:02:20

标签: c++ algorithm compression dna-sequence lossless-compression

DNA字符串的长度可以是5个字母(A,T,G,C,N)的任意组合。
压缩包含5个字母(A,T,G,C,N)的字母的DNA字符串的有效方法是什么。不用考虑每个字母3位,我们可以使用更少的位有效地压缩和检索吗?有人可以建议使用伪代码进行有效的压缩和检索吗?

5 个答案:

答案 0 :(得分:7)

如果愿意(a)每个字符都有不同的位大小,并且(b)您始终从头开始阅读,而从中间不读,则可以。然后,您可以输入类似以下的代码:

  • A-00
  • T-01
  • G-10
  • C-110
  • N-111

从左向右读取,您只能以一种方式将比特流拆分为char。您一次读取2位,如果它们是“ 11”,则需要再读取一位以了解它是什么字符。

This is based on Huffman Coding Algorithm

注意:
我对DNA不太了解,但是如果字符的概率不相等(意味着20%)。您应该将最短的代码分配给概率更高的代码。

答案 1 :(得分:3)

您有5个唯一值,因此您需要以5为底的编码(例如A = 0,T = 1,G = 2,C = 3,N = 4)。

在32位中,您可以容纳log 5 (2 32 )= 13 以5为基数的值。

在64位中,您可以容纳log 5 (2 64 )= 27 以5为基数的值。

编码过程为:

uint8_t *input = /* base-5 encoded DNA letters */;
uint64_t packed = 0;
for (int i = 0; i < 27; ++i) {
    packed = packed * 5 + *input++;
}

然后解码:

uint8_t *output = /* allocate buffer */;
uint64_t packed = /* next encoded chunk */;
for (int i = 0; i < 27; ++i) {
    *output++ = packed % 5;
    packed /= 5;
}

答案 2 :(得分:1)

有很多压缩方法,但是主要问题是您要压缩哪些数据?  1.来自定序机(fastq)的未对齐原始数据  2.对齐的数据(sam / bam / cram)  3.参考基因组

  1. 您应该重新排列读段的顺序,以使彼此接近的基因组位置的读段相互靠近。例如,这将使通常的gzip压缩效果提高3倍。有很多方法可以做到这一点。例如,您可以将fastq与bam对齐,然后将其导出回fastq。使用后缀树/数组来查找类似的读段,这是大多数对齐程序的工作方式(需要大量内存)。使用最小化器-速度非常快,内存不足的解决方案,但不适用于长读取且错误很多的情况。可以使用debruijn图构建(即重新对齐)来获得良好的结果。 像霍夫曼/算术这样的统计编码将压缩到1/3(可以将霍夫曼流传递给二进制算术编码器以获取另外20%的数据。)
  2. 最好的结果来自此处基于参考的压缩-仅存储参考和对齐的读取之间的差异。
  3. 这里几乎无能为力。使用统计编码,每个核苷酸可以获得2-3位。

答案 3 :(得分:0)

我们可以结合使用Roee Gavirel的想法和以下想法来获得更严格的结果。由于Roee的想法仍然规定将五个字符中的两个映射到一个3位单词,因此该序列中的五个字符中至少一个不会出现,而一个3位单词却会出现的部分位的字,降低了最终结果。

切换映射的条件是,如果存在一个部分,其中五个字符中的至少一个不出现,并且一个3位字中的一个出现,只是我们的节前缀长度(以位为单位)的两倍多。如果我们对可能的字符进行排序(例如,按字母顺序排列),给定三位表示一个特定的缺失字符(如果有多个缺失,则按顺序选择第一个)或不缺失,我们可以立即分配一致的2位映射其他四个字符。

关于前缀的两个想法:

(1)

  • 3位:缺少的字符(如果没有,我们将对该部分使用Roee编码);

  • x位:表示段长度的恒定位数。对于最大长度为65000的部分,我们可以将x = 16分配。

要证明使用前缀的合理性,我们需要一个部分,其中五个字符之一不会出现,而三位字之一会出现39次或更多。

(2)

  • 3位:缺少的字符(如果没有,我们将对该部分使用Roee编码);

  • x位:前缀下一部分的位数-取决于最长部分的位数。 x = 6意味着最大段长度可能是2 ^(2 ^ 6)!不太可能。对于最大长度为65000的段,我们可以将x = 4;

  • 前缀的前面部分中指示的位数,指示当前节的长度。

在上面的示例中,我们的前缀长度可以在11到23位之间变化,这意味着要证明其使用的合理性,我们需要一个不出现五个字符之一且其中一个3位字符的部分。单词出现23到47次或更多。

答案 4 :(得分:0)

坦率地说,我将从某种版本的Lempel-Ziv压缩开始(一类压缩算法,其中包括通用gzip压缩格式)。我注意到,有些评论说通用压缩算法不适用于原始基因组数据,但是其有效性取决于数据如何呈现给他们。

请注意,大多数通用压缩程序(如gzip)都是按字节检查输入的。这意味着以3位/碱基“预压缩”基因组数据会产生反作用。相反,在通过通用压缩程序运行之前,应将未压缩的基因组数据格式化为每个碱基一个字节。只要您不通过添加空格,换行符或大写字母的变体来增加干扰,Ascii“ AGTCN”编码就可以了。

Lempel-Ziv压缩方法的工作原理是识别其输入中的重复子字符串,然后通过参考之前的数据对它们进行编码;我希望这类方法应该在适当呈现的基因组数据上做得相当好。一种更特定于基因组的压缩方法可能会对此有所改善,但是除非我不知道对基因组编码存在一些强烈的,非局部性的限制,否则我预计不会有重大的改进。