这是用户在 2024-9-19 10:51 为 https://app.immersivetranslate.com/pdf-pro/1278e129-84c3-433c-99af-fee32bda17e5 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?


CRAM 格式规范(3.1 版)

samtools-devel@lists.sourceforge.net

 2024 年 9 月 4 日

 摘要


本文件的主版本可在 https://github.com/samtools/hts-specs 上找到。本次打印的是该版本库中的第 4127441 版,最后修改日期如上所示。

 许可证:Apache 2.0

 1 概述


本规范描述了 CRAM 3.0 和 3.1 格式。


CRAM 的主要目标如下

  1. 无损压缩效果明显优于 BAM

  2. 与 BAM 完全兼容

  3. 从使用 BAM 文件轻松过渡到 CRAM

  4. 支持有控制地丢失 BAM 数据

前三个目标允许用户立即利用 CRAM 格式的优势,同时提供了从使用 BAM 文件的平稳过渡途径。第四个目标支持探索不同的有损压缩策略,并提供一个框架来实现这些选择。请注意,CRAM 格式并没有对哪些数据应该或不应该保留作出任何规定。相反,CRAM 支持多种无损和有损数据保存策略,使用户能够选择保存哪些数据。


CRAM 中的数据以 CRAM 记录的形式存储,或使用其中一种通用压缩器(gzip、bzip2)存储。CRAM 记录使用多种不同的编码策略进行压缩。例如,通过编码碱基差异而不是存储碱基本身来压缩碱基。 1 1 ^(1){ }^{1}

 2 数据类型


CRAM 规范使用逻辑数据类型和存储数据类型;逻辑数据类型以单词(如 int)的形式书写,而物理数据类型则以单个字母(如 i)的形式书写。两者的区别在于,存储数据类型定义了逻辑数据类型在 CRAM 中的存储方式。CRAM 中的数据以位或字节的形式存储。下面将详细介绍以位和字节形式写入值。

 2.1 逻辑数据类型

 字节


有符号字节(8 位)。

 整数

 有符号 32 位整数。

 

 有符号 64 位整数。

 阵列


任何逻辑数据类型的数组: array<type>


2.2 将比特写入比特流


比特流由 1 s 和 0 s 的序列组成,比特最显著位先写入,新比特向右堆叠,左侧的完整字节被写出。在比特流中,如果写入的比特少于 8 位,则最后一个字节将是不完整的。在这种情况下,最后一个字节中的位会向左移动。


写入比特流的示例


让我们来看看下面的例子。下表显示了一系列写操作:
 操作顺序  之前的缓冲状态  书面位  后的缓冲状态  发布字节
1 0 × 0 0 × 0 0xx00 \times 0 1 0 × 1 0 × 1 0xx10 \times 1 -
2 0 × 1 0 × 1 0xx10 \times 1 0 0 × 2 0 × 2 0xx20 \times 2 -
3 0 × 2 0 × 2 0xx20 \times 2 11 0 × B 0 × B 0xx B0 \times B -
4 0 × B 0 × B 0xx B0 \times B 00000111 0 × 7 0 × 7 0xx70 \times 7 0 × B 0 0 × B 0 0xx B00 \times B 0
Operation order Buffer state before Written bits Buffer state after Issued bytes 1 0xx0 1 0xx1 - 2 0xx1 0 0xx2 - 3 0xx2 11 0xx B - 4 0xx B 00000111 0xx7 0xx B0| Operation order | Buffer state before | Written bits | Buffer state after | Issued bytes | | :--- | :--- | :--- | :--- | :--- | | 1 | $0 \times 0$ | 1 | $0 \times 1$ | - | | 2 | $0 \times 1$ | 0 | $0 \times 2$ | - | | 3 | $0 \times 2$ | 11 | $0 \times B$ | - | | 4 | $0 \times B$ | 00000111 | $0 \times 7$ | $0 \times B 0$ |

刷新上述位流后,将写入以下字节: 0 x B 0 0 x B 0 0xB00 x B 0 0x70。请注意,最后一个字节在左移之前是 0 × 7 0 × 7 0xx70 \times 7 ,左移之后变成了 0 x 70 0 x 70 0x 700 x 70
> echo "obase=16; ibase=2; 00000111" | bc
7
> echo "obase=16; ibase=2; 01110000" | bc
7 0

还有整个位面序列:

echo "obase=2; ibase=16; B070" | bc| bc

1011000001110000

从比特序列中读取比特时,必须知道只有 12 比特是有意义的,之后的比特流不应再读取。


关于写入比特流的说明


向位流中写入数值时,必须知道数值和数值中的位数。这是因为编程语言通常使用字节(8 位)进行操作,而要指定写入的位数,就需要一个比特位,例如一个整数,以及其中的比特位数。同样,从位流中读取数值时,也必须事先知道位数。如果是前缀码(如哈夫曼),所有可能的比特组合要么事先已经知道,要么可以根据前几个比特计算出后面的比特数。另外,也可以将两个编码组合在一起,其中第一个编码包含要读取的比特数。


2.3 将字节写入字节流


字节流的解释非常简单。CRAM 在适用情况下对字节使用小端位,并定义了以下存储数据类型:

 布尔型 (bool)


布尔值以 1 字节表示, 0 x 0 0 x 0 0x00 x 0 表示 "假",0 x 1 表示 "真"。

 整数 (int32)


带符号的 32 位整数,按小双位字节顺序写成 4 个字节。

 长 (int64)


带符号的 64 位整数,按小双位字节顺序写成 8 个字节。

 ITF-8 整数 (itf8)


这是写入整数值的另一种方法。其思想类似于 UTF-8 编码,因此这种编码被称为 ITF-8(整数转换格式 - 8 位)。


第一个字节的最重要位具有特殊意义,称为 "前缀"。它们是 0 至 4 个真实比特,后面跟一个 0。1 的个数表示后面的字节数。为了容纳 32 位,这种表示法需要 5 个字节,最后一个字节 5 只使用 4 个低位。

LTF-8 long (ltf8)


详情请参见 ITF-8。ITF-8 和 LTF-8 的唯一区别在于编码单个值所需的字节数。要做到这一点,需要 64 位,而这最多可以用 9 个字节来完成,其中第一个字节仅包含 1 s 或 0 xFF 值。

 数组 (array<type>)


明确写入维数的可变大小数组。数组长度首先写为整数 (itf8),然后写入数组元素。


此外,还使用隐式或固定大小的数组,例如写为类型 [ ] 或类型 [4]。这些数组在文件格式中没有明确的尺寸,而是依靠规范本身来记录数组的大小。

 编码


编码是一种数据类型,用于指定数据序列的压缩方式。编码定义为 encoding<type>,其中类型是逻辑数据类型,而不是存储数据类型。


编码的写法如下。第一个整数(itf8)表示编解码器 ID,第二个整数(itf8)表示以下编码特定值的字节数。


次指数编码示例
 价值  类型  名称
0x7 itf8  编解码器 id
0x2 itf8
后续字节数
0x0 itf8  胶印
0x1 itf8  K 参数
Value Type Name 0x7 itf8 codec id 0x2 itf8 number of bytes to follow 0x0 itf8 offset 0x1 itf8 K parameter| Value | Type | Name | | :--- | :--- | :--- | | 0x7 | itf8 | codec id | | 0x2 | itf8 | number of bytes to follow | | 0x0 | itf8 | offset | | 0x1 | itf8 | K parameter |

第一个字节 " 0 × 7 0 × 7 0xx70 \times 7 " 是编解码器 ID。


下一个字节 " 0 x 2 " 表示后面的字节长度 (2)。


亚指数编码有 2 个参数:整数 (itf8) 偏移和整数 (itf8) K。

 偏移量 = 0 x 0 = 0 = 0 x 0 = 0 =0x0=0=0 \mathrm{x} 0=0
K = 0 x 1 = 1 K = 0 x 1 = 1 K=0x1=1\mathrm{K}=0 \mathrm{x} 1=1
 地图

映射是键和相关值的集合。具有 N N NN 键的映射的写法如下:
 字节大小 N  关键 1  值 1  关键...  价值...  键 N  值 N
size in bytes N key 1 value 1 key... value ... key N value N| size in bytes | N | key 1 | value 1 | key... | value ... | key N | value N | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |

以字节为单位的大小和键的数量都以整数(itf8)形式写入。键和值根据其数据类型书写,并针对每个映射。

 字符串


字符串使用 UTF-8 格式表示为字节数组。类型为" Z Z ZZ "的读取名称、引用序列名称和标记值以 UTF-8 格式存储。

 3 编码


编码是一种数据结构,用于捕捉解压缩数据序列所需的压缩细节信息。这可能是初始化特定解压缩算法所需的常量集或数据序列的统计属性,如果数据序列存储在外部块中,则可能是块内容 ID。

编码符号定义为关键字 "encoding"(编码),后面是括号中的数据类型,例如,"encoding<byte> "表示对数据类型为 "字节 "的数据系列进行操作的编码。


编码可能有不同数据类型的参数,例如 EXTERNAL 编码只有一个参数,即外部数据块的整数 ID。定义了以下编码
 编解码器 ID  参数  评论
NULL 0    未保存的系列
EXTERNAL 1  int 块内容 id

块内容标识符,用于将外部数据块与数据系列关联起来
the block content identifier used to associate external data blocks with data series| the block content identifier used to | | :--- | | associate external data blocks with | | data series |
 已停用(GOLOMB) 2 int offset, int M  戈隆编码
HUFFMAN 3 array<int>, array<int>
用入/字节值编码
BYTE_ARRAY_LEN 4

编码<int> 数组长度,编码<byte> 字节
encoding<int> array length, encoding<byte> bytes| encoding<int> array length, | | :--- | | encoding<byte> bytes |

使用数组长度对字节数组进行编码
coding of byte arrays with array length| coding of byte arrays with array | | :--- | | length |
BYTE_ARRAY_STOP 5

byte stop, int 外部块内容 ID
byte stop, int external block content id| byte stop, int external block | | :--- | | content id |

用 stopvalue 对字节数组进行编码
coding of byte arrays with a stop value| coding of byte arrays with a stop | | :--- | | value |
BETA 6
int 偏移,int 位数
 二进制编码
SUBEXP 7  int 偏移,int K  次指数编码
 已停用(GOLOMB_RICE) 8
int 偏移,int log 2 m log 2 m log_(2)m\log _{2} \mathrm{~m}
 戈隆-瑞斯编码
GAMMA 9  int 偏移  埃利亚斯伽马编码
Codec ID Parameters Comment NULL 0 none series not preserved EXTERNAL 1 int block content id "the block content identifier used to associate external data blocks with data series" Deprecated (GOLOMB) 2 int offset, int M Golomb coding HUFFMAN 3 array<int>, array<int> coding with int/byte values BYTE_ARRAY_LEN 4 "encoding<int> array length, encoding<byte> bytes" "coding of byte arrays with array length" BYTE_ARRAY_STOP 5 "byte stop, int external block content id" "coding of byte arrays with a stop value" BETA 6 int offset, int number of bits binary coding SUBEXP 7 int offset, int K subexponential coding Deprecated (GOLOMB_RICE) 8 int offset, int log_(2)m Golomb-Rice coding GAMMA 9 int offset Elias gamma coding| Codec | ID | Parameters | Comment | | :--- | :--- | :--- | :--- | | NULL | 0 | none | series not preserved | | EXTERNAL | 1 | int block content id | the block content identifier used to <br> associate external data blocks with <br> data series | | Deprecated (GOLOMB) | 2 | int offset, int M | Golomb coding | | HUFFMAN | 3 | array<int>, array<int> | coding with int/byte values | | BYTE_ARRAY_LEN | 4 | encoding<int> array length, <br> encoding<byte> bytes | coding of byte arrays with array <br> length | | BYTE_ARRAY_STOP | 5 | byte stop, int external block <br> content id | coding of byte arrays with a stop <br> value | | BETA | 6 | int offset, int number of bits | binary coding | | SUBEXP | 7 | int offset, int K | subexponential coding | | Deprecated (GOLOMB_RICE) | 8 | int offset, int $\log _{2} \mathrm{~m}$ | Golomb-Rice coding | | GAMMA | 9 | int offset | Elias gamma coding |

有关上述所有编码算法及其参数的详细说明,请参见第 13 节。

 4 校验和


校验和用于确保数据完整性。CRAM 中使用了以下校验和算法。

4.1 CRC32


这是一个循环冗余校验和,长度为 32 位,多项式为 0x04C11DB7。详情请参阅 ITU-T V. 42。CRC32 哈希函数的值写成整数。

 4.2 CRC32 和


CRC32 求和是将所有单个 CRC32 值取模为 2 32 2 32 2^(32)2^{32} 求和后的 CRC32 值组合。

 5 文件结构


本节将介绍 CRAM 文件的整体结构。更多详细信息请参阅本文件的其他章节。


CRAM 文件由一个固定长度的文件定义、一个 CRAM 头容器、零个或多个数据容器以及一个特殊的文件结束容器组成。
 归档定义
File definition| File | | :---: | | definition |
 CRAM 标头容器
CRAM Header Container| CRAM Header | | :---: | | Container |
 数据容器
Data Container| Data | | :---: | | Container |
cdots\cdots
 数据容器
Data Container| Data | | :---: | | Container |
CRAM EOF
Container
CRAM EOF Container| CRAM EOF | | :---: | | Container |
"File definition" "CRAM Header Container" "Data Container" cdots "Data Container" "CRAM EOF Container"| File <br> definition | CRAM Header <br> Container | Data <br> Container | $\cdots$ | Data <br> Container | CRAM EOF <br> Container | | :---: | :---: | :---: | :---: | :---: | :---: |

图 1:CRAM 文件由文件定义、文件头容器和其他容器组成。


容器由一个或多个块组成。第一个容器称为 CRAM 标头容器,用于存储 SAM 规范中描述的文本标头(见第 7.1 节)。该容器可能会有额外的填充字节,以允许内联重写 SAM 标头,但大小变化不大。这些填充字节是未定义的,但我们建议使用 nuls 填充。填充字节可以是明确的未压缩块结构,也可以是未分配的额外空间,即容器的大小大于其中所包含块的总和。

图 2:第一个容器包含 CRAM 标题文本。


每个容器都以一个容器头结构开始,然后是一个或多个块。每个容器中的第一个块是压缩头块,详细说明如何解码后续块中的数据。每个区块都以区块头结构开始,然后是区块数据。

图 3:作为一系列区块的容器


压缩头之后的数据块在逻辑上被组织成片段。例如,一个片段可包含一个连续的对齐数据区域。片段以片头块开始,后面是一个或多个数据块。这些数据块是 CRAM 数据的主要部分。数据块进一步细分为一个核心数据块和一个或多个外部数据块。

图 4:由一系列连接块形成的切片

 6 文件定义


每个 CRAM 文件都以固定长度(26 字节)的定义开始,其中包含以下字段:
 数据类型  名称  价值
 字节[4]  格式魔数 CRAM (0x43 0x52 0x41 0x4d)
 无符号字节  主要格式号 3 ( 0 x 3 ) 3 ( 0 x 3 ) 3(0x3)3(0 x 3)
 无符号字节  次要格式号 1 (0x1)
 字节[20]  文件 id
CRAM 文件标识符(如文件名或 SHA1 校验和)。
Data type Name Value byte[4] format magic number CRAM (0x43 0x52 0x41 0x4d) unsigned byte major format number 3(0x3) unsigned byte minor format number 1 (0x1) byte[20] file id CRAM file identifier (e.g. file name or SHA1 checksum)| Data type | Name | Value | | :--- | :--- | :--- | | byte[4] | format magic number | CRAM (0x43 0x52 0x41 0x4d) | | unsigned byte | major format number | $3(0 x 3)$ | | unsigned byte | minor format number | 1 (0x1) | | byte[20] | file id | CRAM file identifier (e.g. file name or SHA1 checksum) |

有效的 CRAM 主版本号和次版本号如下:


1.0 最初的公开 CRAM 版本。


2.0 第一个以 Java 和 C 语言实现的 CRAM 版本;整理了 1.0 版本中实现与规范之间的差异。


2.1 获得文件末尾标记;与 2.0 兼容。


3.0 新增压缩方法;标题和数据校验和;改进未排序数据的处理。


3.1 仅附加外部压缩编解码器。

CRAM 3.0 和 3.1 的区别仅在于可用的压缩方法列表不同,因此输出 CRAM 3 而不使用任何 3.1 编解码器的工具应在标头中注明 3.0,以实现最大的兼容性。


7 集装箱头结构


文件定义之后是一个或多个容器,其标题结构如下,容器内容存储在 "块 "字段中:
 数据类型  名称  价值
int32  长度

该容器中所有块(标头和数据)的长度与任何填充字节的长度之和(仅限 CRAM 标头容器);等于容器的总字节长度减去该标头结构的字节长度
the sum of the lengths of all blocks in this container (headers and data) and any padding bytes (CRAM header container only); equal to the total byte length of the container minus the byte length of this header structure| the sum of the lengths of all blocks in this container | | :--- | | (headers and data) and any padding bytes (CRAM header | | container only); equal to the total byte length of the | | container minus the byte length of this header structure |
itf8  参考序列 ID

该容器中的所有片段都必须有一个与该值匹配的参考序列 ID。
reference sequence identifier or -1 for unmapped reads -2 for multiple reference sequences. All slices in this container must have a reference sequence id matching this value.| reference sequence identifier or | | :--- | | -1 for unmapped reads | | -2 for multiple reference sequences. | | All slices in this container must have a reference sequence | | id matching this value. |
itf8

起始位置
starting position on the reference| starting position on the | | :--- | | reference |

对齐起始位置
itf8  对齐跨度
长度
itf8  记录数
容器中的记录数
ltf8  记数器
文件/数据流中记录的基于 1 的顺序索引。
ltf8  基地  读数基数
itf8  块数
该容器中的区块总数
 数组<itf8>  地标

该容器中分片的位置,作为从该容器标头末尾开始的字节偏移量,用于随机存取索引。由于第一个分片之前的块是压缩头,因此 landmarks[0] 等于压缩头的字节长度。
the locations of slices in this container as byte offsets from the end of this container header, used for random access indexing. For sequence data containers, the landmark count must equal the slice count. Since the block before the first slice is the compression header, landmarks[0] is equal to the byte length of the compression header.| the locations of slices in this container as byte offsets from | | :--- | | the end of this container header, used for random access | | indexing. For sequence data containers, the landmark | | count must equal the slice count. | | Since the block before the first slice is the compression | | header, landmarks[0] is equal to the byte length of the | | compression header. |
int crc32
容器中前面所有字节的 CRC32 哈希值。
 字节  大厦
容器中包含的区块。
Data type Name Value int32 length "the sum of the lengths of all blocks in this container (headers and data) and any padding bytes (CRAM header container only); equal to the total byte length of the container minus the byte length of this header structure" itf8 reference sequence id "reference sequence identifier or -1 for unmapped reads -2 for multiple reference sequences. All slices in this container must have a reference sequence id matching this value." itf8 "starting position on the reference" the alignment start position itf8 alignment span the length of the alignment itf8 number of records number of records in the container ltf8 record counter 1-based sequential index of records in the file/stream. ltf8 bases number of read bases itf8 number of blocks the total number of blocks in this container array<itf8> landmarks "the locations of slices in this container as byte offsets from the end of this container header, used for random access indexing. For sequence data containers, the landmark count must equal the slice count. Since the block before the first slice is the compression header, landmarks[0] is equal to the byte length of the compression header." int crc32 CRC32 hash of the all the preceding bytes in the container. byte[ blocks The blocks contained within the container.| Data type | Name | Value | | :---: | :---: | :---: | | int32 | length | the sum of the lengths of all blocks in this container <br> (headers and data) and any padding bytes (CRAM header <br> container only); equal to the total byte length of the <br> container minus the byte length of this header structure | | itf8 | reference sequence id | reference sequence identifier or <br> -1 for unmapped reads <br> -2 for multiple reference sequences. <br> All slices in this container must have a reference sequence <br> id matching this value. | | itf8 | starting position on the <br> reference | the alignment start position | | itf8 | alignment span | the length of the alignment | | itf8 | number of records | number of records in the container | | ltf8 | record counter | 1-based sequential index of records in the file/stream. | | ltf8 | bases | number of read bases | | itf8 | number of blocks | the total number of blocks in this container | | array<itf8> | landmarks | the locations of slices in this container as byte offsets from <br> the end of this container header, used for random access <br> indexing. For sequence data containers, the landmark <br> count must equal the slice count. <br> Since the block before the first slice is the compression <br> header, landmarks[0] is equal to the byte length of the <br> compression header. | | int | crc32 | CRC32 hash of the all the preceding bytes in the container. | | byte[ | blocks | The blocks contained within the container. |

在初始 CRAM 标头容器中,读取时必须忽略参考序列 ID、参考起始位置和排列跨度字段。对于 CRAM 标头来说,地标数组是可选的,但如果存在,则应指向块偏移而不是片段,第一个块包含文本标头。

在指定未映射读数或多个参考序列(即参考序列 ID < 0 < 0 < 0<0 )的数据容器中,读取时必须忽略参考和排列跨度字段的起始位置。写入时,建议将每个忽略字段的值设置为 0。


7.1 CRAM 标头容器


CRAM 文件的第一个容器包含一个或多个块中的文本标头。有关这些块中的数据布局以及适用于 SAM 标头内容的限制的更多详情,请参阅第 8.3 节。

容器标头结构的地标字段可用于指示标头容器中使用的块的偏移量。如果指定数组大小为零,则可以省略这些偏移。

 8 块结构


容器由一个或多个数据块组成。除了用于压缩块内数据的编码外,块压缩是独立应用的。数据块具有以下标题结构,数据存储在 "数据块数据 "字段中:
 数据类型  名称  价值
 字节  方法
块压缩方法(以及第一个 CRAM 版本):
 0:未处理(无)*
1: gzip
2: bzip2 (v2.0)
3: lzma (v3.0)
4: rans4x8 (v3.0)
5: rans4x16 (v3.1)

6:自适应算术编码器(V3.1)
7: fqzcomp (v3.1)
 8:名称标记器(v3.1)
 字节  块内容类型 id
块内容类型标识符
itf8  大小(字节)*
用于关联外部数据的块内容标识符
 原始大小(以字节为单位)*  数据系列块
itf8  块数据
应用块压缩后的块数据大小
itf8
在应用数据块压缩之前存储的数据
byte[]
・ CRAM 记录的比特流(核心数据块)

\bullet 字节流(外部数据块)
CRC32
附加字段(标头块)
 字节[4]
数据块中前面所有字节的 CRC32 哈希值
Data type Name Value byte method the block compression method (and first CRAM version): 0: raw (none)* 1: gzip 2: bzip2 (v2.0) 3: lzma (v3.0) 4: rans4x8 (v3.0) 5: rans4x16 (v3.1) 6: adaptive arithmetic coder (v3.1) 7: fqzcomp (v3.1) 8: name tokeniser (v3.1) byte block content type id the block content type identifier itf8 size in bytes* the block content identifier used to associate external data raw size in bytes* blocks with data series itf8 block data size of the block data after applying block compression itf8 the data stored in the before applying block compression byte[] ・ bit stream of CRAM records (core data block) ∙ byte stream (external data block) CRC32 additional fields ( header blocks) byte[4] CRC32 hash value for all preceding bytes in the block | Data type | Name | Value | | :--- | :--- | :--- | | byte | method | the block compression method (and first CRAM version): | | | | 0: raw (none)* | | | | 1: gzip | | | | 2: bzip2 (v2.0) | | | | 3: lzma (v3.0) | | | | 4: rans4x8 (v3.0) | | | | 5: rans4x16 (v3.1) | | | | 6: adaptive arithmetic coder (v3.1) | | | | 7: fqzcomp (v3.1) | | | | 8: name tokeniser (v3.1) | | byte | block content type id | the block content type identifier | | itf8 | size in bytes* | the block content identifier used to associate external data | | | raw size in bytes* | blocks with data series | | itf8 | block data | size of the block data after applying block compression | | itf8 | | the data stored in the before applying block compression | | byte[] | ・ bit stream of CRAM records (core data block) | | | | | $\bullet$ byte stream (external data block) | | | CRC32 | additional fields ( header blocks) | | byte[4] | CRC32 hash value for all preceding bytes in the block | |

  • 原始方法注意事项:压缩大小和原始大小必须设置为相同的值。

文件中可能会出现空块。原始(未压缩)大小为零的块将被视为空块,与其 "方法 "字节无关。这相当于将它们解释为方法为零(原始)、压缩后大小为零。

 8.1 块内容类型


CRAM 具有以下块内容类型:
 区块内容类型
 块内容类型 id
Block content type id| Block | | :--- | | content | | type id |
 名称  目录
FILE_HEADER 0  CRAM 标头块  CRAM 标头
COMPRESSION_HEADER 1  压缩头块  参见具体章节
SLICE_HEADER a ^("a "){ }^{\text {a }} 2  切片头块  参见具体章节
3  矜持
EXTERNAL_DATA 4  外部数据块

外部编码产生的数据
data produced by external encodings| data produced by | | :--- | | external encodings |
CORE_DATA 5  核心数据块

除外部编码外的所有编码的比特流
bit stream of all encodings except for external encodings| bit stream of all | | :--- | | encodings except for | | external encodings |
Block content type "Block content type id" Name Contents FILE_HEADER 0 CRAM header block CRAM header COMPRESSION_HEADER 1 Compression header block See specific section SLICE_HEADER ^("a ") 2 Slice header block See specific section 3 reserved EXTERNAL_DATA 4 external data block "data produced by external encodings" CORE_DATA 5 core data block "bit stream of all encodings except for external encodings"| Block content type | Block <br> content <br> type id | Name | Contents | | :--- | :--- | :--- | :--- | | FILE_HEADER | 0 | CRAM header block | CRAM header | | COMPRESSION_HEADER | 1 | Compression header block | See specific section | | SLICE_HEADER ${ }^{\text {a }}$ | 2 | Slice header block | See specific section | | | 3 | | reserved | | EXTERNAL_DATA | 4 | external data block | data produced by <br> external encodings | | CORE_DATA | 5 | core data block | bit stream of all <br> encodings except for <br> external encodings |

 8.2 区块内容 ID


块内容 id 用于区分同一片段中的外部块。每个外部编码都有一个 id 参数,它必须是外部块内容 id 之一。对于外部区块,内容 id 是一个正整数。对于所有其他区块,内容 id 应为 0。因此,所有外部编码不得使用小于 1 的内容 id。

 数据块


数据存储在数据块中。数据块有两种类型:核心数据块和外部数据块。核心数据块和外部数据块的区别在于,核心数据块由使用位编码压缩的数据序列组成,而外部数据块则是字节压缩的。每个片段关联一个核心数据块和任意数量的外部数据块。


对核心和外部数据块的写入和读取是通过 CRAM 记录来组织的。每个数据序列都与编码相关联。在外部编码的情况下,数据块内容 ID 用于识别存储数据序列的数据块。请注意,外部数据块可以有多个与之相关的数据序列;在这种情况下,这些数据序列的值将交错排列。

 8.3 CRAM 标头块


SAM 标头存储在 CRAM 标头容器的第一个块中(见第 7.1 节)。该块可以是未压缩的,也可以是 gzip 压缩的。该块之后是零个或多个未压缩的扩展块。如果存在这些扩展块,就可以对 CRAM 标头进行就地编辑,通过对子扩展块进行补偿性大小更改来实现标头的增大或缩小,从而避免重写文件的其余部分。任何扩展块的内容都应为零字节(nul 字符)。


SAM 首部数据块的格式是一个 32 位小二进制整数,其长度为 SAM 首部文本的长度减去无效终止字节,然后是文本本身。虽然是 32 位,但允许的最大值是 2 31 2 31 2^(31)2^{31} ,而且所有长度都必须是正数。


以下限制适用于 SAM 标头文本:

  • 除非参考序列已嵌入文件,否则需要 SQ:MD5 校验和。


8.4 压缩头块


压缩头块由 3 部分组成:保存图、数据序列编码图和标签编码图。

 保护地图


保存映射包含 CRAM 文件中哪些数据被保存的信息。它以字节[2]键的映射形式存储:
 钥匙  值数据类型  名称  价值
RN bool  阅读名称包括
如果所有读取都保留读取名称,则为 true
AP bool  AP 数据系列 delta
如果 AP 数据序列为 delta,则为 true,否则为 false
RR bool  所需参考资料

如果需要参考序列才能完全恢复数据,则为 true
true if reference sequence is required to restore the data completely| true if reference sequence is required to restore | | :--- | | the data completely |
SM  字节[5]  置换矩阵  置换矩阵
TD  数组<byte>  标签 ID 词典
标签 ID 列表,参见标签编码部分
Key Value data type Name Value RN bool read names included true if read names are preserved for all reads AP bool AP data series delta true if AP data series is delta, false otherwise RR bool reference required "true if reference sequence is required to restore the data completely" SM byte[5] substitution matrix substitution matrix TD array<byte> tag ids dictionary a list of lists of tag ids, see tag encoding section| Key | Value data type | Name | Value | | :--- | :--- | :--- | :--- | | RN | bool | read names included | true if read names are preserved for all reads | | AP | bool | AP data series delta | true if AP data series is delta, false otherwise | | RR | bool | reference required | true if reference sequence is required to restore <br> the data completely | | SM | byte[5] | substitution matrix | substitution matrix | | TD | array<byte> | tag ids dictionary | a list of lists of tag ids, see tag encoding section |

布尔值为可选项,不存在时默认为 true,但建议明确设置。SM 和 TD 为强制值。

 数据系列编码


每个数据序列都有一个编码。这些编码存储在一个以字节[2]为键的映射中,解码顺序大致为 2 2 ^(2){ }^{2}
 钥匙  值数据类型  名称  价值
BF  编码<int>  BAM 位标志  见单独章节
CF  编码<int>  CRAM 位标志  参见具体章节
RI  编码<int>  参考编号
SAM 文件头中的记录引用标识
RL  编码<int>  阅读长度  阅读长度
AP  编码<int>  序列内位置

如果 AP-Delta = true:与前一条记录中的 AP 值的对齐起始三角洲值为 0。注意该三角洲值可能为负,例如在多参考分片中切换参考时。如果 AP-Delta = false:直接编码对齐起始位置。
if AP-Delta = true: 0-based alignment start delta from the AP value in the previous record. Note this delta may be negative, for example when switching references in a multi-reference slice. When the record is the first in the slice, the previous position used is the slice alignment-start field (hence the first delta should be zero for single-reference slices, or the AP value itself for multi-reference slices). if AP-Delta = false: encodes the alignment start position directly| if AP-Delta = true: 0-based alignment start | | :--- | | delta from the AP value in the previous record. | | Note this delta may be negative, for example | | when switching references in a multi-reference | | slice. When the record is the first in the slice, the | | previous position used is the slice alignment-start | | field (hence the first delta should be zero for | | single-reference slices, or the AP value itself for | | multi-reference slices). | | if AP-Delta = false: encodes the alignment start | | position directly |
RG  编码<int>  阅读小组

读取组。特殊值"-1 "代表无组。
read groups. Special value ' -1 ' stands for no group.| read groups. Special value ' -1 ' stands for no | | :--- | | group. |
RN a RN a RN^(a)\mathrm{RN}^{\mathrm{a}}  编码<byte[ ]>  阅读名称  阅读名称
MF  编码<int>  下一个队友位标志  参见具体章节
NS  编码<int>

下一个片段参考序列 ID
next fragment reference sequence id| next fragment | | :--- | | reference sequence id |

下一个片段的参考序列 ID
NP  编码<int>
 下一个对齐开始
next mate alignment start| next mate alignment | | :--- | | start |

下一个片段的对齐位置
TS  编码<int>  模板尺寸  模板尺寸
NF  编码<int>
 到下一个分段的距离
distance to next fragment| distance to next | | :--- | | fragment |

跳转到下一个片段的记录数 b b ^(b){ }^{b}
TL C TL C TL^(C)\mathrm{TL}^{\mathrm{C}}  编码<int>  标签 id
标签 id 列表,参见标签编码部分
FN  编码<int>
 阅读次数
number of read features| number of read | | :--- | | features |

每条记录中的读取特征数
FC  编码<byte>  读取功能代码  见单独章节
FP  编码<int>  读入位置

读取特征的位置;最后一个位置的正 delta 值(从零开始)
positions of the read features; a positive delta to the last position (starting with zero)| positions of the read features; a positive delta to | | :--- | | the last position (starting with zero) |
DL  编码<int>  删除长度
碱基对缺失长度
BB  编码<byte[]>  基地  基地
QQ  编码<byte[ ]>

质量分数线的长度
stretches of quality scores| stretches of quality | | :--- | | scores |
 质量得分
BS  编码<byte>
 基本替换代码
base substitution codes| base substitution | | :--- | | codes |
 碱基替换码
IN  编码<byte[]>  插入  插入式基座
RS  编码<int>  参考跳读长度
N "读数特征的跳过碱基数
PD  编码<int>  衬垫  垫底数量
HC  编码<int>  硬夹
硬剪切基数
SC  编码<byte[ ]>  软夹  软剪裁底座
MQ  编码<int>  绘图质量  绘制质量分数
BA  编码<byte>  基地  基地
QS  编码<byte>  质量得分  质量得分
TC d TC d TC^(d)\mathrm{TC}^{\mathrm{d}}  不适用  遗留字段  置之不理
TN d TN d TN^(d)\mathrm{TN}^{\mathrm{d}}  不适用  遗留字段  置之不理
Key Value data type Name Value BF encoding<int> BAM bit flags see separate section CF encoding<int> CRAM bit flags see specific section RI encoding<int> reference id record reference id from the SAM file header RL encoding<int> read lengths read lengths AP encoding<int> in-seq positions "if AP-Delta = true: 0-based alignment start delta from the AP value in the previous record. Note this delta may be negative, for example when switching references in a multi-reference slice. When the record is the first in the slice, the previous position used is the slice alignment-start field (hence the first delta should be zero for single-reference slices, or the AP value itself for multi-reference slices). if AP-Delta = false: encodes the alignment start position directly" RG encoding<int> read groups "read groups. Special value ' -1 ' stands for no group." RN^(a) encoding<byte[ ]> read names read names MF encoding<int> next mate bit flags see specific section NS encoding<int> "next fragment reference sequence id" reference sequence ids for the next fragment NP encoding<int> "next mate alignment start" alignment positions for the next fragment TS encoding<int> template size template sizes NF encoding<int> "distance to next fragment" number of records to skip to the next fragment ^(b) TL^(C) encoding<int> tag ids list of tag ids, see tag encoding section FN encoding<int> "number of read features" number of read features in each record FC encoding<byte> read features codes see separate section FP encoding<int> in-read positions "positions of the read features; a positive delta to the last position (starting with zero)" DL encoding<int> deletion lengths base-pair deletion lengths BB encoding<byte[]> stretches of bases bases QQ encoding<byte[ ]> "stretches of quality scores" quality scores BS encoding<byte> "base substitution codes" base substitution codes IN encoding<byte[]> insertion inserted bases RS encoding<int> reference skip length number of skipped bases for the ' N ' read feature PD encoding<int> padding number of padded bases HC encoding<int> hard clip number of hard clipped bases SC encoding<byte[ ]> soft clip soft clipped bases MQ encoding<int> mapping qualities mapping quality scores BA encoding<byte> bases bases QS encoding<byte> quality scores quality scores TC^(d) N/A legacy field to be ignored TN^(d) N/A legacy field to be ignored| Key | Value data type | Name | Value | | :---: | :---: | :---: | :---: | | BF | encoding<int> | BAM bit flags | see separate section | | CF | encoding<int> | CRAM bit flags | see specific section | | RI | encoding<int> | reference id | record reference id from the SAM file header | | RL | encoding<int> | read lengths | read lengths | | AP | encoding<int> | in-seq positions | if AP-Delta = true: 0-based alignment start <br> delta from the AP value in the previous record. <br> Note this delta may be negative, for example <br> when switching references in a multi-reference <br> slice. When the record is the first in the slice, the <br> previous position used is the slice alignment-start <br> field (hence the first delta should be zero for <br> single-reference slices, or the AP value itself for <br> multi-reference slices). <br> if AP-Delta = false: encodes the alignment start <br> position directly | | RG | encoding<int> | read groups | read groups. Special value ' -1 ' stands for no <br> group. | | $\mathrm{RN}^{\mathrm{a}}$ | encoding<byte[ ]> | read names | read names | | MF | encoding<int> | next mate bit flags | see specific section | | NS | encoding<int> | next fragment <br> reference sequence id | reference sequence ids for the next fragment | | NP | encoding<int> | next mate alignment <br> start | alignment positions for the next fragment | | TS | encoding<int> | template size | template sizes | | NF | encoding<int> | distance to next <br> fragment | number of records to skip to the next fragment ${ }^{b}$ | | $\mathrm{TL}^{\mathrm{C}}$ | encoding<int> | tag ids | list of tag ids, see tag encoding section | | FN | encoding<int> | number of read <br> features | number of read features in each record | | FC | encoding<byte> | read features codes | see separate section | | FP | encoding<int> | in-read positions | positions of the read features; a positive delta to <br> the last position (starting with zero) | | DL | encoding<int> | deletion lengths | base-pair deletion lengths | | BB | encoding<byte[]> | stretches of bases | bases | | QQ | encoding<byte[ ]> | stretches of quality <br> scores | quality scores | | BS | encoding<byte> | base substitution <br> codes | base substitution codes | | IN | encoding<byte[]> | insertion | inserted bases | | RS | encoding<int> | reference skip length | number of skipped bases for the ' N ' read feature | | PD | encoding<int> | padding | number of padded bases | | HC | encoding<int> | hard clip | number of hard clipped bases | | SC | encoding<byte[ ]> | soft clip | soft clipped bases | | MQ | encoding<int> | mapping qualities | mapping quality scores | | BA | encoding<byte> | bases | bases | | QS | encoding<byte> | quality scores | quality scores | | $\mathrm{TC}^{\mathrm{d}}$ | N/A | legacy field | to be ignored | | $\mathrm{TN}^{\mathrm{d}}$ | N/A | legacy field | to be ignored |

a a ^(a){ }^{a} 请注意,如果记录与队友分离,且我们正试图自动生成读取名称,则 RN 会在 MF 之后解码。


b b ^(b){ }^{\mathrm{b}} 每个片段的计数都会被重置,因此 NF 只能在该片段的后面引用记录。


c c ^(c){ }^{c} TL 之后,将按照标签字典中出现的顺序对标签值本身进行解码。


d TC d TC ^(d)TC{ }^{\mathrm{d}} \mathrm{TC} 和 TN 是 CRAM 1.0 中的遗留数据系列。它们在 CRAM 3.0 中没有任何功能,不应出现。不过,有些实现确实会输出它们,解码器必须静默地跳过这些字段。TC 和 TN 不允许包含任何数据值,尽管可能存在与之相关的空块。

 标签编码


标签字典 (TD) 描述了每个对齐记录中出现的标签 id / 类型的唯一组合。例如,如果我们搜索每条记录中出现的标识/类型,发现只有两种组合--X1:i BC:Z SA:Z: 和 X1:i: BC:Z --那么在 TD 地图中就有两个字典条目。


假设 L i = { T i 0 , T i 1 , , T i x } L i = T i 0 , T i 1 , , T i x L_(i)={T_(i0),T_(i1),dots,T_(ix)}L_{i}=\left\{T_{i 0}, T_{i 1}, \ldots, T_{i x}\right\} 是记录 R i R i R_(i)R_{i} 的所有标记 ID 列表,其中 i i ii 是顺序记录索引, T i j T i j T_(ij)T_{i j} 表示记录中的 j j jj 个标记 ID。唯一的 L i L i L_(i)L_{i} 列表作为 TD 值保存在保存映射中。保持顺序不是编码器的要求(因此称为 "组合"),但它是允许的,因此解码器应支持不同的排列,每种排列在 TD 中都有自己的编码元素。TD 中的每个 L i L i L_(i)L_{i} 元素都被分配了一个从 0 开始的连续整数。这些整数由 TL 数据序列表示。使用 TD,可以将 TL 数据序列中的整数映射回标签 ID 列表。因此,我们只需存储每个对齐记录的标签值,而无需存储标签 id 和类型。


TD 被写成一个字节数组,由 L i L i L_(i)L_{i} 值组成,并用 0 0 \\0\backslash 0 分隔。每个 L i L i L_(i)L_{i} 值都以 3 个字节 T i j T i j T_(ij)T_{i j} 元素的连接形式写入:标签 ID,后跟 BAM 标签类型代码(A、c、C、s、S、i、I、f、Z、H 或 B 之一,如 SAM 规范所述)。例如,标签列表 X1:i BC:Z SA:Z 和 X1:i BC:Z 的 TD 可以编码为 X1CBCZSAZ 0 X 1 CBCZ 0 0 X 1 CBCZ 0 \\0X1CBCZ\\0\backslash 0 \mathrm{X} 1 \mathrm{CBCZ} \backslash 0 ,其中 X 1 C 表示标签 X 1 的 1 字节无符号值。

 标签值


不同标记使用的编码存储在一个映射中。键是由 BAM 标记 ID 和类型代码组成的 3 个字节,与上述 TD 字典相匹配。与数据系列编码映射表不同的是,键以 ITF8 编码整数形式存储在映射表中,使用(char 1 << 16 ) + ( 1 << 16 ) + ( 1<<16)+(1<<16)+( char 2 << 8 ) + 2 << 8 ) + 2<<8)+2<<8)+ 类型)构建。例如,OQ:Z 的 3 字节表示为 { 0 x 4 F , 0 x 51 , 0 × 5 A } { 0 x 4 F , 0 x 51 , 0 × 5 A } {0x4F,0x51,0xx5A}\{0 \mathrm{x} 4 \mathrm{~F}, 0 \mathrm{x} 51,0 \times 5 \mathrm{~A}\} ,这些字节被解释为整数键 0 x 004 F 515 A,从而产生一个 ITF8 字节流 { 0 xE 0 , 0 x 4 F , 0 x 51 , 0 x 5 A } { 0 xE 0 , 0 x 4 F , 0 x 51 , 0 x 5 A } {0xE0,0x4F,0x51,0x5A}\{0 \mathrm{xE} 0,0 \mathrm{x} 4 \mathrm{~F}, 0 \mathrm{x} 51,0 \mathrm{x} 5 \mathrm{~A}\}
 钥匙  值数据类型  名称  价值

标签 ID 1:标签类型 1
 编码<byte[ ]>  读标签 1

标签值(名称和类型见数据序列代码)
tag values (names and types are available in the data series code)| tag values (names and types are | | :--- | | available in the data series code) |
dots\ldots dots\ldots dots\ldots

标签 ID n:标签类型 n
 编码<byte[]>  读标签 N dots\ldots
Key Value data type Name Value TAG ID 1:TAG TYPE 1 encoding<byte[ ]> read tag 1 "tag values (names and types are available in the data series code)" dots dots dots TAG ID N:TAG TYPE N encoding<byte[]> read tag N dots| Key | Value data type | Name | Value | | :--- | :--- | :--- | :--- | | TAG ID 1:TAG TYPE 1 | encoding<byte[ ]> | read tag 1 | tag values (names and types are <br> available in the data series code) | | $\ldots$ | | $\ldots$ | $\ldots$ | | TAG ID N:TAG TYPE N | encoding<byte[]> | read tag N | $\ldots$ |

请注意,标签值是以字节数组的形式编码的。将标记值转换为字节数组并返回的例程与 BAM 中的例程相同,不同之处在于值的类型是在标记键中而不是在值中捕获的。因此,"C "和 "c "类型需要消耗 1 个字节,"S "和 "s "类型需要消耗 2 个字节,"I"、"i "和 "f "类型需要消耗 4 个字节," H H HH "、" Z Z ZZ "和" B B BB "类型需要消耗不同数量的字节。

 8.5 片头区块


切片标头块从不压缩(块方法=原始)。对于参考映射读数,片段标头还定义了与片段相关的数据块的参考序列上下文。映射读数可与同一片段中同一参考上的未映射 3 3 ^(3){ }^{3} 读数一起存储。


片头序列 ID 设置了多重参考标志(-2)的片段可能包含映射到多个外部参考的读数,包括未映射的 3 3 ^(3){ }^{3} 读数(放置在这些参考上或未放置),但多个嵌入参考不能以这种方式组合。当使用多个参考文献时,RI 数据系列将用于确定每条记录的参考序列 ID。如果片段中只使用了单个参考文献,则不会出现该数据序列。

标头中的未映射(-1)序列 ID 适用于只包含未置位未映射 3 3 ^(3){ }^{3} 读取的片段。


包含未在任何序列中使用外部参照的数据的片段可能会将参照 MD5 和设为零。出现这种情况的原因可能是数据未映射,或者序列是逐字存储而不是通过参考差分存储的。后一种情况建议用于未排序或非坐标排序的数据。

片头块包含以下字段。
 数据类型  名称  价值
itf8  参考序列 ID

该值必须与其外层容器的值相匹配。
reference sequence identifier or -1 for unmapped reads -2 for multiple reference sequences. This value must match that of its enclosing container.| reference sequence identifier or | | :--- | | -1 for unmapped reads | | -2 for multiple reference sequences. | | This value must match that of its enclosing | | container. |
itf8  对齐开始
对齐起始位置
itf8  对齐跨度
长度
itf8  记录数
片段中的记录数
ltf8  记数器

文件/流中记录的基于 1 的顺序索引
1-based sequential index of records in the file/stream| 1-based sequential index of records in the | | :--- | | file/stream |
itf8  块数
分片中的区块数
itf8[]
嵌入式基准块内容 ID

切片中区块的内容 id,表示嵌入式引用序列库的区块内容 id,无则为 -1
block content ids of the blocks in the slice block content id for the embedded reference sequence bases or -1 for none| block content ids of the blocks in the slice | | :--- | | block content id for the embedded reference | | sequence bases or -1 for none |
itf8  参考 md5

片边界内引用碱基的 MD5 校验和。如果该片的引用序列 ID 为 -1 (未映射)或 -2(多引用),则 MD5 应为 16 字节。
MD5 checksum of the reference bases within the slice boundaries. If this slice has reference sequence id of -1 (unmapped) or -2 (multi-ref) the MD5 should be 16 bytes of \\0. For embedded references, the MD5 can either be all-zeros or the MD5 of the embedded sequence.| MD5 checksum of the reference bases within | | :--- | | the slice boundaries. If this slice has | | reference sequence id of -1 (unmapped) or -2 | | (multi-ref) the MD5 should be 16 bytes of $\backslash 0$. | | For embedded references, the MD5 can either | | be all-zeros or the MD5 of the embedded | | sequence. |
 字节[16]

以 BAM 辅助字段形式编码的一系列标记、类型、值元组。
a series of tag,type,value tuples encoded as per BAM auxiliary fields.| a series of tag,type,value tuples encoded as | | :--- | | per BAM auxiliary fields. |
byte[]  可选标签
Data type Name Value itf8 reference sequence id "reference sequence identifier or -1 for unmapped reads -2 for multiple reference sequences. This value must match that of its enclosing container." itf8 alignment start the alignment start position itf8 alignment span the length of the alignment itf8 number of records the number of records in the slice ltf8 record counter "1-based sequential index of records in the file/stream" itf8 number of blocks the number of blocks in the slice itf8[] embedded reference bases block content id "block content ids of the blocks in the slice block content id for the embedded reference sequence bases or -1 for none" itf8 reference md5 "MD5 checksum of the reference bases within the slice boundaries. If this slice has reference sequence id of -1 (unmapped) or -2 (multi-ref) the MD5 should be 16 bytes of \\0. For embedded references, the MD5 can either be all-zeros or the MD5 of the embedded sequence." byte[16] "a series of tag,type,value tuples encoded as per BAM auxiliary fields." byte[] optional tags | Data type | Name | Value | | :--- | :--- | :--- | | itf8 | reference sequence id | reference sequence identifier or <br> -1 for unmapped reads <br> -2 for multiple reference sequences. <br> This value must match that of its enclosing <br> container. | | itf8 | alignment start | the alignment start position | | itf8 | alignment span | the length of the alignment | | itf8 | number of records | the number of records in the slice | | ltf8 | record counter | 1-based sequential index of records in the <br> file/stream | | itf8 | number of blocks | the number of blocks in the slice | | itf8[] | embedded reference bases block content id | block content ids of the blocks in the slice <br> block content id for the embedded reference <br> sequence bases or -1 for none | | itf8 | reference md5 | MD5 checksum of the reference bases within <br> the slice boundaries. If this slice has <br> reference sequence id of -1 (unmapped) or -2 <br> (multi-ref) the MD5 should be 16 bytes of $\backslash 0$. <br> For embedded references, the MD5 can either <br> be all-zeros or the MD5 of the embedded <br> sequence. | | byte[16] | | a series of tag,type,value tuples encoded as <br> per BAM auxiliary fields. | | byte[] | optional tags | |

只有当切片的映射数据与单个参照(参照序列 ID >= 0 >= 0 >=0>=0 )对齐时,才应在解码过程中使用对齐起始值和对齐跨度值。对于多参考片段或具有未映射数据的片段,建议将这些字段的值填为 0。

如果存储的校验和为全零,则不应验证 MD5sum。在计算 MD5sum 之前,嵌入式参考文献应遵循与外部参考文献相同的大小写和字母规则。如果使用嵌入式参考文献,并不要求其与用于序列比对的参考文献完全匹配。例如,它可能包含没有覆盖的 "N "碱基,也可能对 SNP 变异有不同的碱基调用。因此,在使用嵌入序列时,MD5sum 指的是嵌入序列的校验和,而不应根据任何外部参照文件进行验证。


请注意,当嵌入式参考文献与用于对齐的原始参考文献不同时,可能需要逐字存储 MD 和 NM 标记,以记录嵌入式参考文献和外部参考文献的子串不同。

可选标记的编码方式与 BAM 标记相同。也就是说,一系列二进制编码标签串联在一起,每个标签由一个 2 字节密钥(与 [A-Za-z][A-Za-z0-9]相匹配)和一个 1 字节类型([AfZHcCsSiIB])组成,后跟一串由类型定义格式的字节。


以大写字母开头的标记是保留标记,而小写字母或以 X , Y X , Y X,Y\mathrm{X}, \mathrm{Y} 或 Z 开头的标记则由用户自定义。解码器不理解的任何标记都应跳过,不会产生错误。


目前没有定义标签。

 8.6 核心数据块


核心数据块是由一个或多个 CRAM 记录中的数据组成的比特流(最显著位在前)。请注意,一个字节可能包含多条 CRAM 记录,因为一条最小的 CRAM 记录可能只有几个比特长。核心数据块包含以下字段:
 数据类型  名称  价值
 位[ ]  CRAM 记录 1  第一份 CRAM 记录
dots\ldots dots\ldots dots\ldots
 位[ ]  CRAM 记录 N  第 N 个 CRAM 记录
Data type Name Value bit[ ] CRAM record 1 The first CRAM record dots dots dots bit[ ] CRAM record N The Nth CRAM record| Data type | Name | Value | | :--- | :--- | :--- | | bit[ ] | CRAM record 1 | The first CRAM record | | $\ldots$ | $\ldots$ | $\ldots$ | | bit[ ] | CRAM record N | The Nth CRAM record |

 8.7 外部数据块


核心数据块和外部数据块之间的关系如下图所示:

图 5:核心和外部编码以及核心和外部数据块之间的关系。


图中显示了 CRAM 记录(左侧)如何通过核心或外部编码在核心数据块和一个或多个外部数据块之间分配。所展示的具体编码只是示例,仅供参考。重点在于区分输出始终存储在核心数据块中的核心比特编码和输出始终存储在外部数据块中的外部字节编码。


9 文件箱结束


特殊容器用于标记文件或数据流的结束。版本 3 或更高版本需要使用该容器。其目的是提供一种简便快捷的方法来检测 CRAM 文件或数据流是否已完成。该标记基本上是一个空容器,其 ref seq id 设置为-1(未对齐),对齐起点设置为 4542278。


下面将详细介绍 EOF 容器的全部内容:
 十六进制字节  数据类型  小数值  字段名
 容器头
 000000  整数 15  数据块大小

ff ff ff of
itf8 -1 ref seq id
e0 45 4f 46 itf8 4542278  对齐开始
00 itf8 0  对齐跨度
00 itf8 0  记录数
00 itf8 0  全球记录计数器
00 itf8 0  基地
01 itf8 1  块计数
00  矩阵 0  地标
05 bd d 94 f  整数 1339669765  容器标头 CRC32
 压缩头块
00  字节  0(原始数据)  压缩方法
01  字节  1(压缩头)  块内容类型
00 itf8 0  块内容 id
06 itf8 6  压缩尺寸
06 itf8 6  未压缩尺寸
 压缩头
01 itf8 1
保存映射字节大小
00 itf8 0  保存地图大小
01 itf8 1  编码映射字节大小
00 itf8 0  编码图大小
01 itf8 1  标签编码字节大小
00 itf8 0  标签编码映射大小
ee 63014 b  整数 1258382318  块 CRC32
hex bytes data type decimal value field name Container header Of 000000 integer 15 size of blocks data ff ff ff ff of itf8 -1 ref seq id e0 45 4f 46 itf8 4542278 alignment start 00 itf8 0 alignment span 00 itf8 0 number of records 00 itf8 0 global record counter 00 itf8 0 bases 01 itf8 1 block count 00 array 0 landmarks 05 bd d 94 f integer 1339669765 container header CRC32 Compression header block 00 byte 0 (RAW) compression method 01 byte 1 (COMPRESSION_HEADER) block content type 00 itf8 0 block content id 06 itf8 6 compressed size 06 itf8 6 uncompressed size Compression header 01 itf8 1 preservation map byte size 00 itf8 0 preservation map size 01 itf8 1 encoding map byte size 00 itf8 0 encoding map size 01 itf8 1 tag encoding byte size 00 itf8 0 tag encoding map size ee 63014 b integer 1258382318 block CRC32| hex bytes | data type | decimal value | field name | | :---: | :---: | :---: | :---: | | Container header | | | | | Of 000000 | integer | 15 | size of blocks data | | ff ff ff ff of | itf8 | -1 | ref seq id | | e0 45 4f 46 | itf8 | 4542278 | alignment start | | 00 | itf8 | 0 | alignment span | | 00 | itf8 | 0 | number of records | | 00 | itf8 | 0 | global record counter | | 00 | itf8 | 0 | bases | | 01 | itf8 | 1 | block count | | 00 | array | 0 | landmarks | | 05 bd d 94 f | integer | 1339669765 | container header CRC32 | | Compression header block | | | | | 00 | byte | 0 (RAW) | compression method | | 01 | byte | 1 (COMPRESSION_HEADER) | block content type | | 00 | itf8 | 0 | block content id | | 06 | itf8 | 6 | compressed size | | 06 | itf8 | 6 | uncompressed size | | Compression header | | | | | 01 | itf8 | 1 | preservation map byte size | | 00 | itf8 | 0 | preservation map size | | 01 | itf8 | 1 | encoding map byte size | | 00 | itf8 | 0 | encoding map size | | 01 | itf8 | 1 | tag encoding byte size | | 00 | itf8 | 0 | tag encoding map size | | ee 63014 b | integer | 1258382318 | block CRC32 |

编译到一起时,EOF 标记长 38 个字节,用十六进制表示为Of 000000 ff ff ff ff of e0 454 f 4600000000010005 bd d9 4f 0001000606010001000100 ee 6301 4b

 10 记录结构


CRAM 记录以 SAM 记录为基础,但具有附加功能,可以更有效地存储数据。与 BAM 记录不同,CRAM 记录使用比特和字节存储数据。这样,输出可变长度二进制编码的各种编码技术就可以直接在 CRAM 中使用。另一方面,不需要二进制编码的数据序列可以单独存储在外部块中,并对其单独应用其他压缩技术。


4 4 ^(4){ }^{4} 由于 CRAM 数据系列可能在同一数据块内交错排列,因此了解 CRAM 数据系列的解码顺序至关重要。

总体流程图如下,更详细的说明见后续章节。

 10.1 CRAM 记录


已映射和未映射读数均以下列字段开始。请注意,数据序列类型指的是逻辑数据类型,数据序列名称对应的是数据序列编码映射。
 数据序列类型
Data series type| Data series | | :--- | | type |
 数据系列名称
Data series name| Data series | | :--- | | name |
 现场  说明
int BF  BAM 位标志
参见下面的 BAM 位标志
int CF  CRAM 位标志
参见下面的 CRAM 位标志
- -  位置数据  见第 10.2 节
- -  阅读名称  见第 10.3 节
- -  队友记录  见第 10.4 节
- -  辅助标记  见第 10.5 节
- -  序列
见第 10.6 和 10.7 节
"Data series type" "Data series name" Field Description int BF BAM bit flags see BAM bit flags below int CF CRAM bit flags see CRAM bit flags below - - Positional data See section 10.2 - - Read names See section 10.3 - - Mate records See section 10.4 - - Auxiliary tags See section 10.5 - - Sequences See sections 10.6 and 10.7| Data series <br> type | Data series <br> name | Field | Description | | :--- | :--- | :--- | :--- | | int | BF | BAM bit flags | see BAM bit flags below | | int | CF | CRAM bit flags | see CRAM bit flags below | | - | - | Positional data | See section 10.2 | | - | - | Read names | See section 10.3 | | - | - | Mate records | See section 10.4 | | - | - | Auxiliary tags | See section 10.5 | | - | - | Sequences | See sections 10.6 and 10.7 |


BAM 位标志(BF 数据系列)


以下标志与 SAM 和 BAM 规范中的标志重复,含义相同。但需要注意的是,其中一些标志可以在解码过程中产生,因此在 CRAM 文件中可以省略,并根据位于同一切片内的对端库的两个读数计算位数。
 位标志  评论  说明
0x1

在测序中具有多重段的模板
template having multiple segments in sequencing| template having multiple | | :--- | | segments in sequencing |
0x2

根据校准器正确校准每个片段
each segment properly aligned according to the aligner