假设当前的碱基序列为 ref=ATTCCAGTCGGGTATCCAAGGACT,根据Burrows-Wheeler Transform(short read)文中的建立O表的方法,建立O表如下:
(Table O)
ref |A |T |T |C |C |A |G |T |C |G |G |G |T |A |T |C |C |A |A |G |G |A |C |T |
pos |0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |10|11|12|13|14|15|16|17|18|19|20|21|22|23|
---------------------------------------------------------------------------------
A |1 |1 |1 |1 |1 |2 |2 |2 |2 |2 |2 |2 |2 |3 |3 |3 |3 |4 |5 |5 |5 |6 |6 |6 |
T |0 |1 |2 |2 |2 |2 |2 |3 |3 |3 |3 |3 |4 |4 |5 |5 |5 |5 |5 |5 |5 |5 |5 |6 |
C |0 |0 |0 |1 |2 |2 |2 |2 |3 |3 |3 |3 |3 |3 |3 |4 |5 |5 |5 |5 |5 |5 |6 |6 |
G |0 |0 |0 |0 |0 |0 |1 |1 |1 |2 |3 |4 |4 |4 |4 |4 |4 |4 |4 |5 |6 |6 |6 |6 |
当碱基序列很长时(如序列数据量大小达到G级别),对于表中的0,1,2……这些数据在RAM中以32bits存储,这样要存储一个ref的O表需要4x24x32/8 byte = 384 byte.
实际中,我们采用如下方法对O表进行压缩:
1.将ref拆分成8bits一组
拆分之后如下:
ref = ATTCCAGT | CGGGTATC | CAAGGACT
对于每一组,我们需要存储的信息如下:
1.每组中的元素;
2.每组中最后一个元素对应的O表中的内容;
2.建立压缩表
表头数据为:
[|0|0|0|0|]
将第一组内容放入压缩表:
----表头------A---T---T---C---C---A---G---T---O表在pos=7处的ATCG表中数据
[|0|0|0|0|][|100|111|111|101|101|100|110|111|][|2|3|2|1|]
note:
parameter Symbol sym_A= 3'b100;
parameter Symbol sym_C= 3'b101;
parameter Symbol sym_G= 3'b110;
parameter Symbol sym_T = 3'b111;
建立的完整压缩表:
[|0|0|0|0|][|100|111|111|101|101|100|110|111|][|2|3|2|1|][|101|110|110|110|111|100|111|101|]\
[|3|5|4|4|][|101|100|100|110|110|100|110|101|][|6|6|6|6|]
这样要存储一个ref的O表需要4x4x32/8 + 3x24/8 byte = 73 byte.
对于长度为8N的ref序列的O表,其压缩比为:
origin: 4x8xNx32/8 byte = 128N byte
compress: 3x8xN/8 + (N+1)x4x32/8 byte = 19N + 16 byte
当N-->+∞时,压缩比为19/128=14.84%
3.解压
将压缩表分块,每块大小为32x4+3x8=152bits.
分块之后示意图如下:
[|0|0|0|0|][|100|111|111|101|101|100|110|111|]
[|2|3|2|1|][|101|110|110|110|111|100|111|101|]
[|3|5|4|4|][|101|100|100|110|110|100|110|101|]
[|6|6|6|6|]
举第一块为例,解压时根据[|0|0|0|0|]确定当前O表中的A,T,C,G起始个数都为0,
再根据[|100|111|111|101|101|100|110|111|]可知当前块的元素为ATTCCAGT。
如第一个元素为A,即在O表的A部分设置值为base+1,即0+1=1,其余的T,C,G表中的值保持不变。
如第二个元素为T,即在O表的T部分设置值为base+1,即0+1=1,其余的A,C,G表中的值保持不变(A表中的值仍为1)。
……
从而将O表解压出来。
Note:
在压缩时引入这些块头数据([|0|0|0|0|],[|2|3|2|1|]……)是为了可以将压缩后的O表分块并行解压,互不干扰,只要最后将解压的数据再拼凑回来即可,提高了程序的并行性,可以加快解压的计算速度。