这是用户在 2024-9-5 14:07 为 https://app.immersivetranslate.com/pdf-pro/dbaa0e9d-9b69-4c62-8a41-371818dde2f9 保存的双语快照页面,由 沉浸式翻译 提供双语支持。了解如何保存?
2024_09_05_2152cfd992695f73eb33g


序列对齐/映射格式规范


SAM/BAM 格式规范工作组

 2023 年 11 月 16 日

 摘要


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


1 SAM 格式规范


SAM 是 Sequence Alignment/Map 格式的缩写。它是一种 TAB 分隔的文本格式,由标题部分(可选)和排列部分组成。如果存在,标题必须在排列之前。标题行以" "开头,而对齐行则不以" "开头。每个对齐行有 11 个必填字段,包含基本的对齐信息(如映射位置),以及数量可变的可选字段,包含灵活的或对齐器特定的信息。

本规范适用于 1.6 版本的 SAM 和 BAM 格式。每个 SAM 和 BAM 文件可选择通过 @HD VN 标签指定所使用的版本。有关完整的版本历史,请参见附录 B。

SAM 文件内容为 7 位 US-ASCII,但个别指定的某些字段值除外,这些字段值可能包含以 UTF-8 编码的其他 Unicode 字符。或者,SAM 文件以 UTF-8 编码,但只允许在某些字段值中使用非 ASCII 字符,这些字段值在说明中明确指定。

在有区别的地方,SAM 文件内容应使用 POSIX / C 本地语言读写。例如,SAM 中的浮点数值始终使用". "作为小数点字符。

本规范中的正则表达式使用 POSIX / IEEE Std 1003.1 扩展语法编写。

 1.1 示例


假设我们有以下配准结果,配准结果中的小写碱基被剪除。读数 r001/1 和 r001/2 构成一个读数对;r003 是嵌合读数;r004 代表分裂排列。

相应的 SAM 格式为
@HD VN:1.6 SO:coordinate
@SQ SN:ref LN:45
r001 99 ref 7 30 8M2I4M1D3M = 37 39 TTAGATAAAGGATACTG *
r002 0 ref 9 30 3S6M1P1I4M * 0 0 AAAAGATAAGGATA *
r003 0 ref 9 30 5S6M * 0 0 GCCTAAGCTAA * SA:Z:ref,29,-,6H5M,17,0;
r004 0 ref 16 30 6M14N5M * 0 0 ATAGCTTCAGC *
r003 2064 ref 29 17 6H5M * 0 0 TAGGC * SA:Z:ref,9,+,5S6M,30,1;
r001 147 ref 37 30 9M = 7 -39 CAGCGGCAT * NM:i:1


1.2 术语和概念


模板 DNA/RNA 序列,其中一部分在测序机上测序,或由原始序列组装而成。

一个连续的序列或子序列。


从测序机上获取的原始序列。一个读数可能由多个片段组成。对于测序数据,读数按测序顺序排列索引。

线性比对 是指读数与单个参考序列的比对,可能包括插入、删除、跳转和剪切,但不包括方向变化(即一部分比对在正向链上,另一部分比对在反向链上)。线性比对可以用一条 SAM 记录来表示。

嵌合配准 不能表示为线性配准的读数配准。嵌合对齐表示为一组没有大量重叠的线性对齐。通常情况下,嵌合对齐中的一条线性对齐被视为 "代表 "对齐,其他对齐被称为 "补充 "对齐,并用补充对齐标志加以区分。嵌合排列中的所有 SAM 记录都具有相同的 QNAME 以及 标志的相同值(见第 1.4 节)。关于哪个线性排列具有代表性的决定是任意的。

读数配准 是一种线性配准或嵌合配准,是读数配准的完整表示。

多重映射 读数的正确位置可能不明确,例如由于重复。在这种情况下,同一读数可能会有多个读数配准。其中一个排列被认为是主要排列。所有其他对齐方式都在代表它们的 SAM 记录中设置了辅助对齐标志。所有 SAM 记录的 QNAME 相同, 和 0x80 标志值相同。通常情况下,指定的主要排列是最佳排列,但也可以任意决定。


1 基坐标系 序列的第一个基数为 1 的坐标系。在该坐标系中,一个区域由一个封闭区间指定。例如,第 3 个碱基和第 7 个碱基之间的区域为 。SAM、VCF、GFF 和 Wiggle 格式都使用 1 基坐标系。


0 基坐标系 序列的第一个基数为 0 的坐标系。在该坐标系中,一个区域由一个半闭半开的区间指定。例如,第 3 个碱基和第 7 个碱基之间的区域为 。BAM、BCFv2、BED 和 PSL 格式使用基于 0 的坐标系。

Phred 标度 给定概率 的 phred 标度等于 ,四舍五入为最接近的整数。


1.2.1 字符集限制


在 SAM 和 VCF 等相关格式中,参考序列名称、CIGAR 字符串和其他一些字段类型被用作其他字段的值或部分值。为确保这些其他字段的表示法明确无误,这些字段类型不允许使用特定的分隔符。

查询或读取名称可以包含除" "之外的[!-]范围内的任何可打印 ASCII 字符,以便 SAM 对齐行与标题行容易区分。(它们的长度也有限制)。

除反斜线、逗号、引号和括号外,参考序列名称可以包含范围为 [!- ] 的任何可打印 ASCII 字符,即除',"' () [] {} <>'外,不得以' '或' '开头。

因此,它们与以下正则表达式相匹配:


为了清楚起见,我们在本规范的其他地方将这组允许使用的字符写成字符类 [:rname:] 并扩展 POSIX 正则表达式符号,使用 来表示从字符类中省略" "和" "。因此,这个正则表达式可以更清楚地写成 [:rname ] [:rname:]* 。

 1.3 页眉部分


每个标头行都以字符" "开头,后面跟一个本节定义的双字母标头记录类型代码。在标头中,每行都用 TAB 分隔,除 @CO 行外,每个数据字段都遵循 "TAG:VALUE "格式,其中 TAG 是一个双字符串,定义了 VALUE 的格式和内容。因此,标题行匹配 /^ @(HD|SQ|RG|PG) ( 或 /^ @CO t .*/。在每个(非 @CO)标题行中,字段标记都不能出现超过一次,字段出现的顺序也不重要。

下表描述了可使用的标题记录类型及其预定义标记。用 列出的标记为必填标记;例如,每个 @SQ 标头行都必须有 SN 和 LN 字段。与对齐可选字段(见第 1.5 节)一样,您可以为其他数据字段自由添加新标记。包含小写字母的标记保留给本地使用,不会在本规范的任何未来版本中正式定义。
 标签  说明
@HD

文件级元数据。可选。如果存在,则必须只有一行 @HD 且必须是文件的第一行。
VN*
格式版本。接受格式:/^ .
SO

排列的排序顺序。有效值:未知(默认)、未排序、查询名和坐标。对于坐标排序,主要排序键是 RNAME 字段,顺序由标头中 @SQ 行的顺序决定。次要排序键是 POS 字段。对于排列 具有相同 RNAME 和 POS 的排列,顺序是任意的。所有带有' RNAME 字段中的 "undefined data-dl-uid=7>"遵循与其他值的对齐方式,除此之外,其顺序是任意的。对于 queryname 排序,除了要求在整个文件中应用一致外,对排序没有明确要求。
GO

排列的分组,表示相似的排列记录被分组在一起,但文件不一定整体排序。有效值:无(默认值)、查询(按 QNAME 对排列进行分组)和参考(按 RNAME/POS 对排列进行分组)。
SS

排列的子排序顺序。有效值的形式为 sort-order:sub-sort,其中 sort- order 是存储在 SO 标签中的相同值,sub-sort 是一个以冒号分隔的字符串,用于进一步描述排序顺序,但也包含第 1.3.1 节中的一些预定义术语。例如,如果一种算法依赖于坐标排序,在每个坐标上按查询名称进一步排序,那么标头可以包含 @HD SO:coordinate SS: coordinate:queryname. 如果主要排序不是预定义的主要排序顺序之一、则应使用无排序,而子排序实际上就是主排序。例如,如果按辅助标记 MI 排序,然后按坐标排序,那么标头可以包含 @HD SO:unsorted SS:unsorted:MI: coordinate。 正则表达式:(coordinate। queryname|unsorted) (: [A-Za-z0-9_-]+) +
@SQ
参考序列字典。@SQ 行的顺序定义了排列的排序顺序。
SN*

参考序列名称。所有 @SQ 行中的 SN 标记和所有单个 AN 名称必须不同。该字段的值将在 RNAME 和 RNEXT 字段的比对记录中使用。 正则表达式:[:rname: [:rname:]*
LN*
参考序列长度。范围:
AH

表示该序列是一个备用位点。 该值是该序列作为替代序列的主集合中的位点、格式为'chr:开始-结束"、"chr"(如果已知)或 "*"(如果 未知),其中 ' '是主装配中的序列。必须不存在于主程序集中的序列上。
AN

备选参考序列名称。以逗号分隔的备选序列名称列表,可用于 可在引用该参考序列时使用。 这些替代名称不能在 SAM 文件的其他地方使用;特别是,它们不得出现在对齐记录的 RNAME 中。 或 RNEXT 字段。正则表达式:name (, name)* 其中 name 为 [:rname: ]。[:rname:]*
AS
基因组装配标识符。
DS
说明可使用 UTF-8 编码。
M5
序列的 MD5 校验和。参见第 1.3.2 节
SP  物种
TP
分子拓扑结构。有效值:线性(默认)和圆形。
UR

序列的 URI。该值可以以标准协议之一开头,例如 "http: "或 "ftp:"。如果不以这些协议之一开头,则假定为文件系统路径。
@RG
读取组。允许无序排列多个 @RG 行。
ID*

读取组标识符。每个 @RG 行必须有一个唯一的 ID。ID 值用于对齐记录的 RG 标记。在标头部分的所有读取组中必须是唯一的。在合并 SAM 文件时,读取组 ID 可能会被修改,以便处理碰撞。
BC

识别样本或文库的条形码序列。该值是测序机器在没有错误的情况下读取的预期条形码碱基。如果样本/文库有多个条形码(如模板两端各一个),建议的实现方法是将所有条形码连接起来,用连字符(' - ')分隔。
CN
产生该读数的测序中心名称。
DS
说明可使用 UTF-8 编码。
DT
运行生成日期(ISO8601 日期或日期/时间)。
FO

流序。与每个读数的每个流所用核苷酸相对应的核苷酸碱基阵列。多碱基流以 IUPAC 格式编码,非核苷酸流以 其他各种角色。格式: ACMGRSVTWYHKDBN]+/
KS
与每个读数的关键序列相对应的核苷酸碱基阵列。
LB  图书馆
PG
用于处理读取组的程序。
PI
预测的插入大小中位数,四舍五入为最接近的整数。
PL

用于生成读数的平台/技术。有效值:CAPILLARY、DNBSEQ(MGI/BGI)、ELEMENT、HELICOS、ILLUMINA、IONTORRENT、LS454、ONT(Oxford Nanopore)、PACBIO(Pacific Bio-sciences)、SINGULAR、SOLID 和 ULTIMA。如果技术不在此列表中(尽管 PM 字段可能仍然存在)或未知,则应省略此字段。
PM
平台模型。提供所用平台/技术进一步详情的自由格式文本。
PU
平台单位(如 Illumina 的 flowcell-barcode.lane,或 SOLiD 的 slide)。唯一标识符。
SM
样本。如果正在测序,则使用池名称。
@PG  计划
ID*

程序记录标识符。每个 @PG 行必须有一个唯一的 ID。ID 值将用于其他 @PG 行的对齐 PG 标记和 PP 标记。在合并 SAM 文件时,PG ID 可能会被修改,以便处理碰撞。
PN  计划名称
CL
命令行。可使用 UTF-8 编码。
PP

上一个 @PG-ID.必须与另一个 @PG 标头的 ID 标记相匹配。@PG 记录可以使用 PP 标记进行链式排列,链中的最后一条记录没有 PP 标记。该链定义了应用于排列的程序顺序。在合并 SAM 文件时,可以修改 PP 值,以处理 PG ID 的碰撞。链中的第一条 PG 记录(即 SAM 记录中 PG 标记所指的记录)描述了对 SAM 记录进行操作的最新程序。链中的下一条 PG 记录描述了在 SAM 记录上操作的下一个最新程序。SAM 记录上的 PG ID 并不要求指向链中最新的 PG 记录。它可以指向链中的任何 PG 记录,这意味着 SAM 记录已被该 PG 记录中的程序和通过 PP 标签指向的程序操作过。
DS
说明可使用 UTF-8 编码。
VN  程序版本
@CO

单行文本注释。允许使用无序的多行 @CO。可使用 UTF-8 编码。


1.3.1 已定义的子排序术语


虽然 SS 子排序字段允许执行定义关键字,但有些术语是预定义的,具有特定含义。


词典排序顺序被定义为基于字符的词典排序,其字符顺序由 POSIX C 本地语言定义。例如,"abc"、"abc17"、"abc5"、"abc59 "和 "abcd "按词典顺序排列。


自然排序与词典排序类似,但相邻数字的流被视为嵌入文本字符串中的数字,相互比较时按数字排序,而与周围的非数字字符比较时则按个位数排序。仅在前导零的个数上存在差异(因此在数字上是并列的)的字符串,则按多零在前,少零在后的顺序排列。字符"-"和". "被视为普通字符,因此明显的负值或小数不被视为内嵌数字的一部分。例如,"abc"、"abc+5"、"abc "、"abc.d"、"abc03"、"abc5"、"abc008"、"abc08"、"abc8"、"abc17"、"abc17.+"、"abc17.2"、"abc17.d"、"abc59 "和 "abcd "按自然顺序排列。


umi 是按 UMI 标记进行的词典排序。在比较 UMI 时应使用 MI 标记。如果没有 RX 标记,也可以使用 RX 标记,但不能保证在多个库中都是唯一的。


1.3.2 MD5 计算参考


@SQ 行上的 M5 标签允许通过序列本身的 MD5 摘要对参考序列进行唯一标识。由于摘要是基于序列而非其他,因此有助于解决引用命名的歧义。例如,它可以快速检查不同文件中命名为 "1"、"Chr 1 "和 "chr1 "的参考序列实际上是否相同。

参考序列必须使用 7 位 US-ASCII 字符集。所有有效的引用基都可以用这一字符集表示,而且可以避免确定使用的是哪一个 8 位表示法的问题。填充字符(见第 3.2 节)只能使用 "*"字符表示。

摘要的计算方法如下

  • 除 33 ('!') 至 范围之外的所有字符都会被删除。这将删除所有不可打印字符和空白字符,包括空格和新行。其他所有字符都会保留,即使不是合法的核苷酸代码。

  • 所有小写字母都会转换为大写字母。这一操作等同于对 POSIX 本地语言中的字符调用 toupper()。

  • MD5 摘要的计算方法如 RFC 1321 所述,并以 32 个字符的小写十六进制数表示。

例如,如果引用包含以下字符(包括空格):

ACGT ACGT ACGT
acgt acgt acgt
... 12345 !!!

那么摘要就是字符串 ACGTACGTACGTACGTACGTACGT...12345!!! 结果标签就是 M5: dfabdbb36e239a6da88957841f32b8e4。

在填充的 SAM 文件中,填充基应以 ' 字符的形式插入到参考文献中。以第 3.2 节中的例子为例,参考文献的填充版本为
AGCATGTTAGATAA**GATAGCTGTGCTAGTAGGCAGTCAGCGCCAT

相应的标签为 M5:caad65b937c4bc0b33c08f62a9fb5411。


1.4 对齐部分:必填字段


在 SAM 格式中,每个对齐行通常代表一个数据段的线性对齐。每一行由 11 个或更多用 TAB 分隔的字段组成。前 11 个字段总是存在的,其顺序如下表所示;如果其中任何一个字段所代表的信息不可用,则该字段的值将是一个占位符,即 "0 "或" ",由字段类型决定。下表概述了 SAM 格式中的这些必填字段:
Col  现场  类型 Regexp/Range  简要说明
1 QNAME  字符串  查询模板 NAME
2 FLAG  内部  位操作 FLAG
3 RNAME  字符串
Rname:

参考序列 NAME
4 POS  内部
以 1 为基础的最左侧映射 POSition
5 MAPQ  内部  MAPping 质量
6 CIGAR  字符串 MIDNSHP  雪茄烟串
7 RNEXT  字符串
rname: rname:

配偶/下一个读者的参考名称
8 PNEXT  内部
队友的位置/下一个读数
9 TLEN  内部  观察到的模板长度
10 SEQ  字符串 .  段 SEQuence
11 QUAL  字符串
ASCII 的 Phred 标度基 QUALity +33

对齐行中的所有映射片段都表示在正向基因组链上。对于已映射到反向链的片段,记录的 SEQ 与未映射的原始序列进行反向互补,CIGAR、QUAL 和对链敏感的可选字段被反转,因此记录的序列碱基与所表示的序列碱基一致。

  1. QNAME:查询模板名称。具有相同 QNAME 的读数/段被视为来自同一模板。QNAME '*' 表示信息不可用。在 SAM 文件中,当一个读数的排列是嵌合的或给出了多个映射时,它可能会占用多个排列行。

  2. FLAG:按位排列的 FLAG 组合。 下表解释了每个位:
   说明
1
具有多个测序段的模板
2
根据校准器正确校准每一段
4  未映射区段
8
模板中未映射的下一段
16
SEQ 正在反向互补
32
反向互补模板中下一个片段的 SEQ
64
模板中的第一段
128
模板中的最后一段
256  次级排列
512
未通过过滤,如平台/供应商质量控制
1024  PCR 或光学复本
2048  补充校准

  • 对于 SAM 文件中的每个读取/连续文件,都要求与读取相关的一行且仅有一行满足 "FLAG & '。这一行被称为读取的主要行。

  • 比特 0x100 标志着在某些分析中,当使用的工具意识到该比特时,将不使用对齐方式。当 SAM 中出现多个映射时,它通常用于标记替代映射。

  • 表示相应的对齐行是嵌合对齐的一部分。标记为 0x800 的行称为补充行。

  • 是判断读取是否未映射的唯一可靠依据。如果设置了 ,就不能对 RNAME、POS、CIGAR、MAPQ 以及位 做出任何假设。

  • 位 0x10 表示 SEQ 是否已反向补码和 QUAL 反转。当第 0 x 4 位未设置时,这对应于测序段所映射的链路:第 0 x 10 位未设置表示正向链路,设置表示反向链路。当 0 x 4 位被设置时,表示未映射读数是否以从测序机上下来时的原始方向存储。

  • 反映了所用测序技术中每个模板内固有的读数排序。 如果 都被设置,则读数是线性模板的一部分,但既不是第一个读数,也不是最后一个读数。如果 都未设置,则读数在模板中的索引未知。这种情况可能发生在非线性模板中,或者在数据处理过程中丢失了这一信息。

  • 如果未设置 ,则无法对 进行假设。

  • 表中未列出的位保留供将来使用。当前软件在写入时不应设置这些位,在读取时也应忽略它们。

  1. RNAME:比对的参考序列名称。如果存在 @SQ 标题行,RNAME(如果不是 )必须出现在其中一个 SQ-SN 标记中。无坐标的未映射段有一个 ,在

这个字段。但是,未映射的线段也可能有一个普通坐标,这样就可以在排序后将其放置在所需的位置上。如果 RNAME 为 ,则无法假设 POS 和 CIGAR。


4.POS:第一个 "消耗 "参照基的 CIGAR 运算的以 1 为基准的最左侧映射 POS 位置(见下表)。参考序列中的第一个碱基坐标为 1。对于无坐标的未映射读数,POS 设置为 0。如果 POS 为 0,则不能对 RNAME 和 CIGAR 作任何假设。


5.MAPQ:映射质量。等于 映射位置错误},四舍五入为整数。数值 255 表示没有映射质量。


6.CIGAR:CIGAR 字符串。下表给出了 CIGAR 操作(如果没有,则设置为" "):
 作品 BAM  说明
 消耗查询
 消耗参考资料
M 0
配准匹配(可以是序列匹配或不匹配)
   
I 1
插入参考资料
   没有
D 2
从参考资料中删除
 没有  
N 3
从参考文献中跳过的区域
 没有  
S 4
软剪切(SEQ 中存在剪切序列)
   没有
H 5
硬剪切(剪切序列不存在于 SEQ 中)
 没有  没有
P 6
填充(从填充的引用中静默删除)
   没有
= 7  序列匹配    
X 8  序列错配    

  • "消耗查询 "和 "消耗参考 "分别表示 CIGAR 操作是否会导致比对沿着查询序列和参考序列进行。

  • H 只能作为第一个和/或最后一个操作出现。

  • S 与 CIGAR 字符串两端之间只能进行 H 运算。

  • 对于 mRNA 到基因组的比对,N 运算代表内含子。对于其他类型的比对,N 的解释没有定义。

  • 操作的长度总和应等于 SEQ 的长度。

  1. RNEXT:模板中下一个读数的主排列参考序列名称。对于最后一个读数,下一个读数是模板中的第一个读数。如果存在 @SQ 标头行,RNEXT(如果不是 或 ' ')必须出现在其中一个 SQ-SN 标记中。当信息不可用时,该字段将被设置为 "*";如果 RNEXT 与 RNAME 相同,该字段将被设置为" "。如果不是' ',且模板中的下一次读取有一个主映射(另见 FLAG 中的位 ),则该字段与下一次读取的主行 RNAME 相同。如果 RNEXT 为 ,则不能对 PNEXT 和位 进行假设。

  2. PNEXT:1-based 下一读数在模板中的主排列位置。当信息不可用时设置为 0。该字段等于下一个读数主排列行的 POS。如果 PNEXT 为 0,则不能假设 RNEXT 和位

  3. TLEN:带符号的观察模板长度(Template LENgth)。对于模板中所有读数的主排列都映射到同一参考序列的主读数,TLEN 的绝对值等于模板的映射末端与模板的映射起点之间的距离(即末端-起点+1)。 注意,映射碱基的定义是与 CIGAR 所描述的参考文献对齐的碱基,因此不包括软缺口碱基。TLEN 字段对于模板最左边的片段是正值,对于最右边的片段是负值,中间片段的符号未定义。如果片段覆盖相同的坐标,则可以任意选择最左和最右的片段,但两端必须有不同的符号。如果是单段模板或当

信息不可用(例如,多片段模板的第一个或最后一个片段未映射,或两个片段映射到了不同的参考序列)。


该字段的目的是标明模板另一端已对齐的位置,而无需读取 SAM 文件的其余部分。遗憾的是,对于模板映射的起点和终点的定义还没有达成明确的共识。因此,确切的定义是由执行定义的。


10.SEQ:段 SEQuence。当不存储序列时,该字段可以是 。如果不是 ,序列的长度必须等于 CIGAR 中 操作的长度之和。 表示碱基与参考碱基相同。不能对字母的大小写做任何假设。


11.QUAL(质量):碱基质量加 33 的 ASCII 码(与 Sanger FASTQ 格式中的质量字符串相同)。碱基质量是碱基错误概率的phred-scaled,等于 碱基错误 。如果不存储质量,该字段可以是 。如果不是 ,SEQ 必须不是 ,质量字符串的长度应等于 SEQ 的长度。


1.5 对齐部分:可选字段


所有可选字段都遵循 TAG:TYPE:VALUE 格式,其中 TAG 是两个字符的字符串,与 /[A-Za-z] [A-Za-z0-9]/ 匹配。在每个对齐行内,任何 TAG 都不得出现超过一次,可选字段的出现顺序也不重要。包含小写字母的 TAG 保留给最终用户。在可选字段中,TYPE 是一个区分大小写的字母,它定义了 VALUE 的格式:
 类型  与 VALUE 匹配的 Regexp  说明
A  可打印字符
i  有符号整数
f
单精度浮点数
Z
可打印字符串,包括空格
H
十六进制格式的字节数组
B cCsSiIf  整数或数字数组

对于整数或数字数组(类型为" "),第一个字母表示下面逗号分隔数组中的数字类型。该字母可以是'cCsSiIf'中的一个,分别对应 int8_t(有符号 8 位整数)、uint8_t(无符号 8 位整数)、int16_t、uint16_t、int32_t、uint32_t 和 float。 在导入/导出过程中,如果新类型也与数组兼容,则元素类型可以改变。

预定义标记在单独的《序列对齐/映射可选字段规范》中进行了描述。 有关现有标准标记字段的详细信息和创建新标记的约定,请参阅该文档。以" "、" "或" "开头的标记以及在任一位置包含小写字母的标记保留给本地使用,不会在这些规范的任何未来版本中正式定义。

本节介绍以 SAM 格式表示数据的最佳做法。一般情况下,它们不是必需的,但特定软件包可能需要它们才能正常运行。
  1.  页眉部分

    1 应该有 @HD 行,并指定 SO 标记或 GO 标记(但不能同时指定)。


    2 如果已对读数进行了映射,则应出现 @SQ 行。


    3 当 RG 标记出现在对齐部分的任何位置时,页眉中应出现一个与 ID 标记匹配的 @RG 行。


    4 当 PG 标记出现在对齐部分的任何位置时,页眉中应出现一个与 ID 标记匹配的 @PG 行。

  2. 相邻的 CIGAR 行动应有所不同。

  3. 不应将任何排列分配给制图质量为 255 的排列。
  4.  未映射读数

    1 对于伴侣已被映射的未映射成对末端或伴侣对读数,未映射读数的 RNAME 和 POS 应与其伴侣相同。


    2 如果模板中的所有线段都未映射,则其 RNAME 应设置为'*',POS 应设置为 0。


    3 如果 POS 加上 CIGAR 中 操作的长度总和超过 @SQ 头行(如果存在)LN 字段中指定的长度(SN 等于 RNAME),除非参考序列是环状的(见下文),否则应取消对齐。


    4 未映射读数应以它们从测序机上下来时的方向存储,并相应地取消反向标志位( )的设置。
  5.  多重映射

    1 当一个数据段出现在多行中以表示该数据段的多重映射时,只有其中一条记录的辅助对齐标志位 ( ) 未被设置。RNEXT 和 PNEXT 指向模板中下一次读取的主行。


    2 SEQ 和次级排列的 QUAL 应设置为 ' 以减小文件大小。
  6.  可选标签:

    1 如果模板有 2 个以上分段,则应出现 TC 标记。


    2 应该有 NM 标签。

  7. 循环参考序列

在循环参照序列中跨越坐标 "连接 "的映射(即 @SQ 标头指定 TP : 循环的映射)可表示如下:


1(首选)通常情况下,POS 应介于 1 和 @SQ 标头的 LN 值之间,但 POS 加上 操作的长度总和可能会超过 LN。大于 LN 的坐标将通过减去 LN 来解释,因此 位置上的碱基将被视为映射到 位置上;因此每个(基于 1 的)位置 将被解释为


2 或者,这种排列也可以分成几条记录:一条记录代表以 LN 为终点的片段的初始部分,一条记录代表以 1 为终点的片段的最终部分,其他任何记录则代表横跨整个参考序列之间的其他部分。其中一条记录(可任意选择)被视为主要记录,其余记录的补充标志位 被设置。

8.注释哑读数:这些假读数的 SEQ 设置为 *,FLAG 位 设置为(二级和过滤),并带有 CT 标记。


1 如果希望在 CT 标签中存储自由文本,请使用键值 "注释"(大写 N)来匹配 GFF3。


2 多区段注释(如带有内含子的基因)应在 SAM 中用多行描述(就像多区段读取一样)。如果有明确的生物学方向(如基因),则第一段(FLAG 位 0x40)用于第一节(如基因的 端)。因此,像 complement(join(85052..85354, 85441..85621, 86097..86284)) 这样的 GenBank 条目位置在 SAM 中会有三行,具有共同的 QNAME:
FLAG POS CIGAR  可选字段
 5' 片段 86097 188 M FI:i:1 TC:i:3
 中间片段 85441 181 M FI:i:2 TC:i:3
 3' 片段 85052 303M FI:i:3 TC:i:3

3 如果将 GFF3 转换为 SAM,除了用于 QNAME 的唯一 ID 外,将第 9 列的任何键值存储在 CT 标签中。GFF3 第 1 列(seqid)、第 4 列(start)和第 5 列(end)使用 SAM 列 RNAME、POS 和 CIGAR 编码,以保存长度。GFF3 第 3 列(类型)和第 7 列(链)明确存储在 CT 标记中。其余的 GFF3 第 2 列(源)、第 6 列(分数)和第 8 列(阶段)使用键值 FSource、FScore 和 FPhase 存储在 CT 标签中(大写键值在 GFF3 中受到限制,因此这些名称可避免冲突)。分割位置特征在 GFF3 中用多行描述,在 SAM 中同样成为多区段虚读,并适当填写 RNEXT 和 PNEXT 列。由于 SAM/BAM 中没有对环状基因组原点包裹读数的约定,因此任何包裹原点的 GFF3 特征行都必须在 SAM 中分割成两段。


3 SAM 中的装配序列描述指南


3.1 无衬垫表示法与有衬垫表示法


在描述排列时,我们可以将参考序列视为与其他排列无关的序列。这样的参照序列称为无填充参照。无填充参考序列上的位置称为无填充位置,不受任何排列的影响。当我们使用无加载参照和位置来描述排列时,我们说我们正在使用无加载表示法。

或者,为了描述相同的排列,我们可以修改参考序列,使其包含垫区,为相对于参考序列插入的序列留出空间。填充实际上是一个间隙,通常用星号 表示。包含填充的参照序列称为填充参照。计算 's 的位置称为填充位置。填充的参考序列可能会受到查询排列的影响,而且由于间隙插入,通常比未填充的参考序列要长。一个查询排列的填充位置可能会受到其他查询排列的影响。

无衬垫和有衬垫是相同排列的不同表示。它们可以相互转换,不会丢失任何信息。无填充表示法由于使用固定坐标系比较方便而比较常见,而填充表示法的优点是可以简单地用开始和结束坐标来描述排列,而不需要使用复杂的 CIGAR 字符串。SAM 传统上使用填充表示法进行从头组装。ACE 汇编格式只使用填充表示法。

 3.2 填充式 SAM


SAM 格式通常用于描述与无填充参考序列的比对,但也可以描述与填充参考序列的比对。在后一种情况下,我们说使用的是填充的 。填充的 SAM 也是有效的 SAM,不同之处在于使用的参考序列和位置都是填充的。描述填充表示法的方法可能不止一种。我们建议采用以下方法;另请参阅 Cock 等人在 中的讨论。

在填充的 SAM 中,排列和坐标是相对于填充的参考序列来描述的。在传统的填充表示法(如 ACE 文件格式)中,用 's 记录读数中的填充/间隙,与此不同,我们不会在 SAM 格式的 SEQ 字段中写入 *。 相反,我们使用 CIGAR "D "操作将查询序列中的填充描述为从填充参考中删除。在填充的 SAM 中,不使用插入和填充 CIGAR 操作(' '和' '),因为填充的引用已经考虑了所有的插入。

下面是第 1.1 节中对齐示例的填充 SAM。值得注意的是,ref 的长度是 47 而不是 45。最后三条排列的 POS 都移动了 2。
@HD VN:1.6 SO:coordinate
@SQ SN:ref LN:47
ref 516 ref 1 0 14M2D31M * 0 0 AGCATGTTAGATAAGATAGCTGTGCTAGTAGGCAGTCAGCGCCAT *
r001 99 ref 7 30 14M1D3M = 39 41 TTAGATAAAGGATACTG *
* 768 ref 8 30 1M * 0 0 * * CT:Z:.;Warning;Note=Ref wrong?
r002 0 ref 9 30 3S6M1D5M * 0 0 AAAAGATAAGGATA * PT:Z:1;4;+; homopolymer
r003 0 ref 9 30 5H6M * 0 0 AGCTAA * NM:i:1
r004 0 ref 18 30 6M14N5M * * 0 0 0 ATAGCTTCAGC \
r001 147 ref 39 30 9M = 7 -41 CAGCGGCAT * NM:i:1

这里我们还举例说明了必要时在 SAM 中存储参考序列和参考注释的推荐做法。对于 SAM 中的参考序列,QNAME 应与 RNAME 相同,POS 设为 1,FLAG 设为 516(已过滤且未映射);对于注释,FLAG 应设为 768(已过滤且二级),QNAME 不受限制。用于注释的虚假读数通常会有一个 CT 标签来保存注释信息;参见第 2 节中关于虚假读数的讨论。有关 CT 和 PT 注释标记的全部详情,请参阅单独的《可选字段规范》。


4 BAM 格式规范


4.1 BGZF 压缩格式


BGZF 是在标准 gzip 文件格式基础上实现的块压缩。 BGZF 的目标是提供良好的压缩效果,同时允许对 BAM 文件进行高效的随机访问,以便进行索引查询。BGZF 格式是 "与 gunzip 兼容 "的,也就是说,兼容 gunzip 的实用程序可以解压 BGZF 压缩文件。

BGZF 文件是一系列连接的 BGZF 块,压缩前后每个块的大小均不超过 64 Kb。每个 BGZF 块本身都是一个符合规范的 gzip 压缩包,其中包含一个 RFC1952 所述格式的 "额外字段"。gzip 文件格式允许包含特定于应用程序的额外字段,这些字段会被符合规范的解压缩执行程序忽略。gzip 规范还允许连接 gzip 文件。解压缩串联 gzip 文件的结果是解压缩数据的串联。

每个 BGZF 块都包含一个标准的 gzip 文件头,并带有以下符合标准的扩展名:

  1. 标头中的 F.EXTRA 位被设置,表示存在额外字段。

  2. BGZF 使用的额外字段使用两个子字段 ID 值 66 和 67(ASCII "BC")。

  3. BGZF 额外字段有效载荷(gzip 规范中的字段 LEN)的长度为 2(两个字节的有效载荷)。

  4. BGZF 额外字段的有效载荷是一个 16 位无符号整数,采用 little endian 格式。该整数表示包含的 BGZF 块的大小减一。

在磁盘上,一个完整的 BGZF 文件是一系列块,如下表所示。(根据 RFC1952 的要求,所有整数都是小字尾)。
 现场  说明  类型  价值

压缩块列表(直至文件末尾)
ID1 gzip IDentifier 1 uint8_t 31
ID2 gzip IDentifier2 uint8_t 139
CM  gzip 压缩方法 uint8_t 8
FLG gzip FLaGs uint8_t 4
MTIME  gzip 修改时间 uint32_t
XFL gzip eXtra FLags uint8_t
OS  gzip 操作系统 uint8_t
XLEN  gzip 额外长度 uint16_t

额外子字段(总大小 XLEN

附加 RFC1952 额外子字段(如果存在
SI1  子字段标识符1 uint8_t 66
S12  子字段标识符2 uint8_t 67
SLEN  子字段长度 uint16_t 2
BSIZE
总块大小减 1
uint16_t

附加 RFC1952 额外子字段(如果存在
CDATA
通过 zlib::deflate() 压缩的数据
uint8_t [BSIZE-XLEN-19]
CRC32 CRC-32 uint32_t
ISIZE
输入 SIZE(未压缩数据的长度)
uint32_t

接下来介绍的随机访问方法将每个 BGZF 块的未压缩内容限制为最多 字节的数据。因此,虽然 ISIZE 按照 gzip 格式存储为 uint32_t,但在 BGZF 中,它被限制在 的范围内。BSIZE 可以表示 [1,65536] 范围内的 BGZF 数据块大小,不过由于压缩的原因,BSIZE 通常会比 ISIZE 小。

 4.1.1 随机访问


BGZF 文件通过 BAM 文件索引支持随机存取。为此,BAM 文件索引使用 BGZF 文件中的虚拟文件偏移量。每个虚拟文件偏移量都是一个无符号的 64 位整数,定义为:coffset<<16|uoffset,其中 coffset 是 BGZF 文件中到 BGZF 块开头的无符号字节偏移量,uoffset 是该 BGZF 块所代表的未压缩数据流的无符号字节偏移量。可以比较虚拟文件偏移量,但不允许在虚拟文件偏移量之间做减法,也不允许在虚拟偏移量和整数之间做加法。

 4.1.2 文件结束标记


应在 BGZF 文件末尾写入文件末尾 (EOF) 拖车或标记块,以便轻松检测到意外的文件截断。EOF 标记块是一个特定的空 BGZF 块,使用默认的 zlib 压缩级别设置编码,由以下 28 个十六进制字节组成:
1f 8b 08 04 00 00 00 00 00 ff 06 00 42 43 02 00 1b 00 03 00 00 00 00 00 00 00 00 00

在 BGZF 文件末尾出现 EOF 标记表明,紧随其后的物理 EOF 就是编写该文件的程序所希望的文件末尾。空的 BGZF 块在其他方面并不特殊;特别是,EOF 标记块的存在本身并不表示文件的结束。

在打开可随机存取的 BGZF 文件后,如果没有最后的 EOF 标记,就会很快触发警告或错误。 在以顺序流方式读取 BGZF 文件时,理想情况下应在到达流的末尾时执行 EOF 检查。检查文件中的最后一个 BGZF 块是否解压为空,或检查文件的最后 28 个字节是否正好是上述字节,这两种检查方法都已足够;在不同的情况下,每种方法都可能更方便。

 4.2 BAM 格式


BAM 采用 BGZF 格式压缩。BAM 中的所有多字节数字都是小字节,与机器的字节序无关。下表对格式进行了正式描述,括号中的值是在没有相应信息时的默认值;下划线的大写单词表示 SAM 格式中的字段。
 现场  说明  类型  价值
 魔法  BAM 魔法字符串  BAM 1
I_text
页眉文本的长度,包括任何 NUL 填充
uint32_t
 文本
SAM 中的纯标头文本;不一定以 NUL 结尾
 字符 [I_text]
n_ref  # 参考序列 uint32_t

参考信息列表 ( f )
I_name
引用名称的长度加 1(包括 NUL)
uint32_t  有限
 名字
参考序列名称;以 NUL 结尾
 字符 [I_name]
l_ref
参考序列的长度
uint32_t

排列列表(直至文件末尾)
block_size
对齐记录的总长度,不包括该字段
uint32_t  有限
refID

参考序列 ID, refID ref;-1表示没有映射位置的读数
int32_t
 姿势
0 -基于最左坐标
int32_t
I_read_name
下面的 read_name 长度 ( length(QNAME )
uint8_t
 地图q  制图质量 (=MAPQ) uint8_t
 箱柜
BAI 指数仓,见第 4.2.1 节
uint16_t
n_cigar_op
CIGAR 中的操作数,见第 4.2.2 节
uint16_t
 国旗  比特标志 uint16_t
I_seq  SEQ 长度 uint32_t  有限
next_refID
下一个分段的 Ref-ID next_refID n_ref
int32_t
 下一个位置
0 -基于下一段的最左位置
int32_t
tlen
模板长度 ( TLEN)
int32_t
 读取名称
读取以 NUL 结尾的名称(QNAME,带尾部 '
 char [l_read_name] 字符
 雪茄
CIGAR: op_len<<4|op.MIDNSHP ' ' 012345678 '
 uint32_t [n_cigar_op] (数字)
 序列

4 位编码读取:' ACMGRSVTWYHKDBN' .参见第 4.2.3 节
uint8_t [(I_seq+1)/2]
 资格
虹彩比例基础质量。参见第 4.2.3 节
char [I_seq]

辅助数据列表(直至对齐程序块结束)
 标签  双字符标签 char [2]
val_type
值类型:AcCsSiIfZHB,见第 4.2.4 节
 烧焦
 价值  标签值  (按 Val_type)

大多数描述为 uint32_t 的长度和计数字段的范围都有额外的限制:I_text 由于实现限制;n_ref 因为 refID 和 next_refID 是带符号的;I_ref 因为 tlen 是带符号的;标有 "limited "的字段受可用内存和所表示数据的实际大小的限制,远远早于 Java 的带符号 32 位整数最大数组大小的限制。


4.2.1 BIN 字段计算


BIN 使用第 5.3 节中的 reg2bin() 函数计算。对于映射读数,使用 POS-1(即基于 0 的左侧位置),并使用 CIGAR 字符串中的排列长度来计算排列终点。对于未映射读数(例如只有一部分被映射的成对末端读数,见第 2 节)和 CIGAR 字符串完全不包含参考碱基的读数,配准长度被视为 1。请注意,POS 为 0(在 BAM 中为-1)的未映射读数使用 reg2bin ,计算结果为 4680。

 4.2.2 N_CIGAR_OP 字段


在 16 位的情况下,n_cigar_op 最多可以在 BAM 文件中保存 65535 次 CIGAR 操作。对于有更多 CIGAR 操作的排列,BAM 会将真正的 CIGAR(编码方式与 BAM 中的 cigar 字段相同)存储在类型为' '的 CG 可选标记中,并将 CIGAR 设置为' S '作为占位符、其中' '等于 seq,' '是比对中的参考序列长度,'S'和'N'分别是软剪辑和参考剪辑 CIGAR 操作符--即'S'和'N'。e.,即 n_cigar_op 和 cigar 。如果存在 CG 标记,并且第一次 CIGAR 操作剪切了整个读数,那么 BAM 解析库将使用 CG 标记中存储的真实 CIGAR 更新 n_cigar_op 和 cigar,并删除现在多余的 CG 标记。


4.2.3 SEQ 和 QUAL 编码


序列以 4 位值编码,相邻碱基从最高的 4 位开始打包到同一字节。当 I_seq 为奇数时,最后一个字节的最下面 4 位是未定义的,但我们建议将其写为 0。不区分大小写的碱基编码"=ACMGRSVTWYHKDBN "分别映射为 ,所有其他字符映射为 "N"(值 15)。

省略序列在 SAM 中表示为" ",l_seq 表示 0,seq 和 qual 表示零长度。


基本特质以 [0,93] 范围内的字节形式存储,不需要将 +33 转换为可打印的 ASCII 编码。当基本质量被省略但序列未被省略时,qual 将以 0xFF 字节填充(长度为 I_seq)。


4.2.4 辅助数据编码


可选对齐字段紧跟在 qual 字段之后存储,并包含在 block_size 中。每个字段用一个双字符标记表示,后面跟一个类型字符,然后是其值,值的长度由字段类型决定。

单字符 "A "字段的总长度为 4 个字节,值以单字节表示:
A  烧焦

在 SAM 中,所有单整数(即非数组)类型都存储为 "i",而在 BAM 中,任何 "cCsSiI "都可以与相应大小的二进制整数值一起使用,二进制整数值根据字段值的大小选择。 同样,浮点" "字段也用 IEEE 二进制 32 值表示。因此,BAM 数字字段的总长度为 4、5 或 7 字节:
c i 8
 (即 int8_t)
C u 8
 (即 uint8_t)
s int16_t
S uint16_t
i int32_t
I uint32_t
f  浮动

字符串字段和十六进制格式的字节数组表示为以 NUL 结尾的文本字符串:
Z  烧掉  烧焦  烧焦 NUL

一个" "数组字段的表示以一个与上述数字字段类型类似的子类型字符和一个计数(uint32_t,但受内存和 block_size 的限制)开始,计数表示数组中元素的个数。随后是数组元素,根据子类型编码为二进制整数或 IEEE 浮点数:

 5 BAM 索引


索引的目的是在不浏览整个排列的情况下,快速检索与指定区域重叠的排列。在索引之前,BAM 必须按参考 ID 排序,然后按最左坐标排序。

本节介绍坐标排序 BAM 索引的分选方案及其在历史悠久的 BAI 格式中的应用。其他地方记录的 CSI 格式使用类似的分选方案,也可用于 BAM 索引。

 5.1 算法


5.1.1 基本分选指数


在该方案中,每个分选区代表一个连续的基因组区域,该区域要么完全包含在另一个分选区中,要么与另一个分选区不重叠;每个排列与一个分选区相关联,该分选区代表包含整个排列的最小区域。分选方案本质上是 R 树的一种表现形式。一个不同的 bin 唯一对应于 R 树中一个不同的内部节点。如果 A 所代表的区域包含在 B 中,那么 Bin A 就是 Bin B 的子节点。

为了找到与指定区域重叠的排列,我们需要获取与该区域重叠的分区,然后测试分区中的每条排列以检查重叠情况。为了快速找到与指定bin相关的排列,我们可以在索引中保留所有具有该bin的排列块的起始文件偏移量。由于排列是按照最左侧的坐标排序的,具有相同分区的排列往往会在磁盘上集中在一起,因此通常一个分区只与几个分块相关联。遍历具有相同分区的所有排列通常需要几次寻道调用。给定一组与指定区域重叠的 bin,我们可以按照最左侧坐标的顺序访问排列,当一个排列不在所需区域内时,就停止搜索其余排列。这种策略平均可以节省一半的寻道调用次数。

在 BAI 格式中,每个分区可以跨 。分区 0 跨 512 Mbp 区域,分区 ,分区 跨 16 kbp 区域。这意味着这种索引格式不支持长度超过 的参考染色体序列。

CSI 格式扩大了分区的大小,并支持与 SAM 和 BAM 相同长度的参考序列。


5.1.2 缩小小块


在两个相邻分区的边界附近,我们可能会看到许多小块,其中一些分区较短,而其他分区较大。为了减少寻道调用次数,我们可以将两个具有相同分区的小块连接起来,如果它们彼此靠近的话。经过这个过程后,连接后的数据块将包含不同分区的排列。我们需要在索引中保留每个分块末尾的文件偏移量,以识别其边界。


5.1.3 与线性指数相结合


对于超过 64 Mbp 的排列,我们总是需要寻找 0 仓中的某些块,而使用线性索引可以避免这种情况。在线性索引中,对于参考文献上的每个 16384bp 的平铺窗口,我们记录与该窗口重叠的排列的最小文件偏移。给定一个区域 [rbeg,rend],我们只需要访问其末端文件偏移大于包含 rbeg 的 16 kbp 窗口文件偏移的块。

利用分选和线性索引,我们只需一次寻道调用就能检索到大部分区域的排列结果。


5.1.4 概念范例


假设我们的基因组短于 144kbp。我们可以设计一个由三类分仓组成的分仓方案:0 仓跨度为 ,1、2 和 3 仓跨度为 48 kbp,4 至 12 仓各跨度为 16 kbp:
 0(0-144kbp)
 1(0-48kbp)  2(48-96kbp)  3(96-144kbp)
10 11 12

一条从 65 kbp 开始到 67 kbp 结束的排列将进入第 8 仓,这是包含该排列的最小仓。同样,一条从 51 kbp 开始到 70 kbp 结束的排列将进入 bin 2,而 之间的排列将进入 bin 0。假设我们要查找与 区域重叠的所有排列。我们首先计算出 0、2 和 8 号分区与该区域重叠,然后遍历这些分区中的排列,找到所需的排列。如果仅使用分区索引,我们需要访问位于 的排列,因为它属于 0 号分区。但如果使用线性索引,我们就知道这样的排列在 64 kbp 之前就停止了,不可能与指定区域重叠。因此可以节省一次寻道调用。


5.2 BAM 文件的 BAI 索引格式

 现场  说明  类型  价值
 魔法  魔法字符串 char [4]  BAI (1
n_ref  # 参考序列 uint32_t

索引列表
n_bin
# 个不同的分选箱(用于分选索引)
uint32_t

不同箱列表
 箱柜  独特的垃圾桶 uint32_t
n_chunk  # 块 uint32_t  有限

数据块列表 ( chunk)
 分块
(虚拟)文件偏移量,即块的起始位置
uint64_t
 块结束
(虚拟)数据块末尾的文件偏移量
uint64_t
n_intv
# 16kbp 间隔(用于线性索引)
uint32_t

区间列表 ( )
ioffset
(虚拟)区间内第一次对齐的文件偏移量
uint64_t
 n_no_coor(可选)
未定位的未映射读数(RNAME *)的数量
uint64_t

索引文件可以选择性地包含附加元数据,提供每个参考序列的映射和放置的未映射读段的数量汇总,以及任何未放置的未映射读段的数量汇总。 这些元数据存储在每个参考序列的可选额外元数据伪文本框中,以及文件末尾的可选尾部 n_noo_coor 字段中。

伪仓在参考文献的不同仓列表中显示为 37450 号仓(超出正常范围),其布局与真实仓及其分块相匹配:
 箱柜  魔法箱编号 uint32_t 37450
n_chunk  # 块 uint32_t 2
 参考基准
(虚拟)文件偏移量,读取该引用的起始位置
uint64_t
ref_end
(虚拟)文件偏移量,即该引用的读数末尾的偏移量
uint64_t
n_mapped
该参考文献的映射读段数
uint64_t
n_unmapped
该参考文献的未映射读段数量
uint64_t

ref_beg/ref_end 字段用于定位参考序列上的第一个和最后一个读数,无论这些读数是映射的还是未映射的。因此,它们分别等于最小 chunk_beg 和最大 chunk_end。


5.3 计算仓号和重叠仓的 C 源代码


以下函数用于计算 BAI 式分选方案(6 级,最小分选尺寸为 )的分选区编号和重叠。请参阅 CSI 规范,了解这些函数针对任意深度和大小的分选方案所设计的通用函数。

在调用这些函数时,如果使用的是代表未定位未映射读取的区域,例如 reg2bin ,就会涉及 ( -1 ) 等操作,这些操作在某些编程语言中是未定义的,或者是实现定义的。在实现这些操作时,必须将其视为使用常见的二元补码语义:reg2bin 和 reg2bins 返回
/* calculate bin given an alignment covering [beg,end) (zero-based, half-closed-half-open) */
int reg2bin(int beg, int end)
{
    --end;
    if (beg>>14 == end>>14) return ((1<<15)-1)/7 + (beg>>14);
    if (beg>>17 == end>>17) return ((1<<12)-1)/7 + (beg>>17);
    if (beg>>20 == end>>20) return ((1<<9)-1)/7 + (beg>>20);
    if (beg>>23 == end>>23) return ((1<<6)-1)/7 + (beg>>23);
    if (beg>>26 == end>>26) return ((1<<3)-1)/7 + (beg>>26);
    return 0;
}
/* calculate the list of bins that may overlap with region [beg,end) (zero-based) */
#define MAX_BIN (((1<<18)-1)/7)
int reg2bins(int beg, int end, uint16_t list[MAX_BIN])
{
    int i = 0, k;
    --end;
    list [i++] = 0;
    for (k = 1 + (beg>>26); k <= 1 + (end>>26); ++k) list[i++] = k;
    for (k = 9 + (beg>>23); k <= 9 + (end>>23); ++k) list[i++] = k;
    for (k = 73 + (beg>>20); k <= 73 + (end>>20); ++k) list[i++] = k;
    for (k = 585 + (beg>>17); k <= 585 + (end>>17); ++k) list[i++] = k;
    for (k = 4681 + (beg>>14); k <= 4681 + (end>>14); ++k) list[i++] = k;
    return i;
}


附录 A 区域解析符号


如果名称本身不包含": "字符,那么像名称[:begin [-end]]这样的区域符号(省略括号外的部分表示请求整个参考序列)的解析就会很简单,但事实并非如此。(在 SAM 格式本身中并没有包含可选" "的这种符号,但各种工具都使用这种符号,方便用户指定感兴趣的区域)。

在解析这种符号时,通常已经知道了有效的参考序列名称集--例如,因为已经遇到过相关的 @SQ 标头。工具可以使用该集合明确地确定哪些冒号可以分隔已知有效的参考序列名称。

字符串 str 的伪代码解析如下


考虑 str 中最右边的" "字符(如果有)。


如果 的形式为 "前缀:NUM "或 "前缀:NUM-NUM


或用 "前缀:后缀 "来表示某个可信的区间后缀

 

如果前缀和 str 都在已知集合中,则...错误:表示不明确


否则,如果前缀在已知集合中,则返回 (前缀, NUM... NUM)


else 如果 在已知集合中,则返回 (str,整个序列)


否则...错误:未知参考序列名称


否则......要么 str 中不包含冒号,要么后缀不可能是数字


如果 在已知集合中,则返回 (str,整个序列)


否则...错误:参考序列名称未知或区间语法无效


导致 "错误:表示含糊 "的检查非常重要,因为它可以防止对实际含糊的输入进行混乱的解释。通常情况下,有效的参考序列名称集合不会包含作为集合中其他名称前缀的名称,因此在非恶意数据中通常不会出现这种错误。

除了这种算法或作为其替代,工具还可以使用额外的分隔符来制作明确可解析的符号。我们推荐在参考序列名称周围使用大括号--{name}[:begin [-end]]。- 我们推荐在引用序列名称--{name} [:begin[-end]]--周围使用大括号,因为这样便于记忆、易于键入、明确无误,而且大多数 shell 不会展开。


附录 B SAM 版本历史


其中列出了每个标记的 SAM 版本的日期,以及该版本生效期间所做的更改。导致版本号变化的主要更改以粗体显示。

对标准预定义标记的添加和更改在单独的《序列对齐/映射可选字段规范》中列出。


1.6:2017 年 11 月 28 日至今


  • 在 @RG PL 标题标记值列表中添加 SINGULAR。(2023年5月)

  • 说明 @RG PI 值是整数。(2023年5月)

  • 在 @RG PL 标头标记值列表中添加 ELEMENT 和 ULTIMA。(2022年8月)

  • 说明标题字段标记在每一行中必须是不同的,而且标题字段和对齐方式可选字段的排序并不重要。(2021 年 6 月)

  • 明确二级排列时 TLEN 的含义。(2021 年 5 月)

  • 更改了 CIGAR 字符串不消耗参考碱基的排列记录的 Bin 计算:与未映射记录一样,它们被视为长度为 1(而不是 0)。(2021年1月)

  • 更正索引伪区间的描述,之前的描述称 ref_beg/ref_end(后被命名为 unmapped_beg/unmapped_end)只包括放置的未映射读数。(2020年7月)

  • 在 @RG PL 标头标记值列表中添加 DNBSEQ。(2020年4月)

  • 添加 @SQ TP 循环/线性拓扑头标签。(2019年5月)

  • 限制了参考序列名称(@SQ SN、RNAME 等)中允许使用的标点符号。@SQ SN 和 @SQ AN 中允许使用的字符集现在完全相同,这扩大了之前的 AN 字符集。(2019年1月)


    我们建议验证引用序列名称的实现使用第 1.2.1 节中的规则;对于声明 @HD VN 的文件应更加宽松;并且仅根据这些规则验证 AN,而不是之前限制性更强的 AN 规则。

  • 添加 @HD SS 排序详细信息标题标签。(2018年10月)

  • B 数组可选字段可能没有条目 - 这在 BAM 中已经可以表示,澄清了 SAM 中也允许使用空数组。(2018年7月)

  • 添加 @SQ DS 标题标记。(2018年7月)

  • 添加 @RG BC 标题标签。(2018年4月)

  • 允许在一些标题标记中使用 UTF-8。(2018年3月)

  • 增加对操作数超过 65,535 次的 CIGAR 字符串的支持。(2017年11月)


1.5:2013 年 5 月 23 日至 2017 年 11 月


  • 添加 @SQ AN 标头标签,只允许使用字母数字和 "*+.@_ - -'字符。(2017年7月)

  • 添加 @SQ AH 标题标记。(2017年3月)

  • 辅助标记迁移至 SAMtags 文档。(2016年9月)

  • Z 和 H 辅助标记允许长度为零。(2016年6月)

  • QNAME 限制为 254 字节(原为 255)。(2015年8月)

  • 将 0x200 标志位概括为过滤掉的位。(2015年8月)

  • 添加 @HD GO,以便进行团体订购。(2015年3月)

  • 在 @RG PL 和 @RG PM 标题标记中添加 ONT。(2015年3月)

  • 在未映射读数上增加反向 FLAG 的含义。(2015年3月)

  • 记录 idxstats .bai 元素。(2014 年 11 月)

  • 增加 CSI 指数。(2014年9月)

  • 添加 @PG DS 标头字段。(2013 年 12 月)

  • 记录 BAM EOF 字节值。(2013 年 12 月)

  • 对齐类型词汇表。(2013 年 5 月)

  • 请注意,PNEXT/RNEXT 指向的是下一次读取,而不是分段。(2013年5月)

  • 添加 SUPPLEMENTARY 标志位。(2013 年 5 月)


1.4: 2011 年 4 月 21 日至 2013 年 5 月


  • 添加序列注释(CT/PT 标记)使用指南。(2012年3月)

  • 将最大引用长度从 增加到 。(2011年9月)

  • 澄清 @SQ M5 标题标记的生成。(2011年9月)

  • 描述填充排列。(2011年9月)

  • 添加 @RG FO、KS 标头字段。(2011 年 4 月)

  • 澄清 PG 记录的连锁。(2011 年 4 月)

  • 添加 B 阵列辅助标记类型。(2011年4月)

  • 允许在 SEQ 和 MD 辅助标记中使用 IUPAC。(2011年4月)

  • 允许 QNAME "*"。(2011年4月)


1.3:2010 年 7 月至 2011 年 4 月


  • 添加 RG PG 标头字段。(2010 年 11 月)

  • 添加 BAM 说明和索引部分。(2010 年 11 月)

  • 添加"="和" "CIGAR 操作。(2010 年 7 月)

  • 删除 FLAG 字母。(2010 年 7 月)

  • SM 标头字段以前是 @RG 的必选字段,现在是可选字段。(2010 年 7 月)


    1.0: 2009 年至 2010 年 7 月
 初版。


  1. 因此,SAM 文件尤其不能以字节序号(BOM)开头,文本行只能以 ASCII 行结束符字符分隔。除了本地平台的文本文件行结束约定外,为实现与其他平台的互操作性,实施可能希望支持 LF 和 CR LF。

  2. FLAG 列中的值与位标志对应如下: :第一个/下一个是反向补充正确对齐/多个区段;0:未设置标志,因此是映射的单个区段; x810:补充/反向补充; :最后一个(一对区段中的第二个)/反向补充/正确对齐/多个区段。

  3. 嵌合比对主要是由结构变异、基因融合、错误组装、RNA-seq 或实验方案引起的。在读数较长的情况下,嵌合对齐更为常见。对于嵌合对齐来说,构成对齐的线性对齐基本上是不重叠的;每条线性对齐都可能具有很高的映射质量,在 SNP/INDEL 调用中具有参考价值。相比之下,多重配对主要由重复序列引起。由于读数较长,多重映射的频率较低。如果一个读数有多个映射,那么所有这些映射几乎都是相互重叠的;除了单个最佳映射外,所有其他映射的映射质量都是 ,而且大多数 SNP/INDEL 调用器都会忽略这些映射。


    字符包括" "和" "," "和" "出现在 HLA 等位基因名称中。附录 A 介绍了即使名称本身可能包含冒号,也能明确解析名称[:begin-end]区域符号的方法。


    最佳做法是在设计和试验新数据字段标记时,或仅在本地感兴趣的字段中使用小写标记。对于具有普遍意义的新标记,请提出 hts-specs 问题或发送电子邮件至 samtools-devel@lists.sourceforge.net 以在规范中添加等效的大写标记。这样就可以避免相同的大写标记被用于不同的含义。

  4. 众所周知,广泛使用的软件库对 queryname 排序顺序的定义各不相同,这意味着在对不同来源的多个文件进行操作时应小心谨慎。工具可能希望使用子排序字段来明确区分自然排序和词典排序。参见第 1.3.1 节。


    排序顺序的重复可以进行有限的验证。例如,@HD SO:queryname SS:coordinate:TLEN 表示数据已被非 SS 感知工具重新排序(按查询名称),SS 字段应被忽略。


    参见 https://www.ncbi.nlm.nih.gov/grc/help/definitions 以了解备用位点和主要装配的说明。


    例如,在给定"@SQ SN:MT AN: chrMT,M, chrM LN:16569 TP:circular "的情况下,工具可以确保用户对 "MT"、"chrMT"、"M "或 "chrM "中任何一个的请求都能成功,并指向相同的序列。


    前面脚注的例子将 MT 识别为环状染色体。TP字段经常被省略,这意味着线性。

  5. 参考序列名称可以包含任何可打印的 ASCII 字符(某些标点符号除外),并且不能以 "*"或"="开头。有关 [:rname:] 符号的详细信息和解释,请参见第 1.2.1 节。

  6. 位标志的操作方法在维基百科(参见 "位字段")和其他地方有所介绍。


    例如,在 Illumina 成对端测序中,第一个 ( ) 对应 R1 "正向 "读数,最后一个 ( 0 x 80 ) 对应 R2 "反向 "读数。(尽管用的是术语,但这与片段映射时的方向无关:映射后,任一片段的反向标志位 ( ) 都可能被设置。)

  7. 因此,长度为 50 的基 100 上沿正向排列的区段和长度为 50 的基 200 上沿反向排列的区段表明模板覆盖基 100 至 249,长度为 150。

  8. 本规范的最早版本使用 (原始方向,TLEN#1;读数的虚线部分表示软剪切碱基),而后来的版本使用最左到最右的映射碱基(TLEN#2)。注意:这两个定义在大多数排列中都是一致的,但在重叠的情况下有所不同,即第一个片段的排列超出了最后一个片段的起始位置。
     明确的方案
     模棱两可的方案

    在 SAM 中,整数可选字段的位数没有明确限制。不过,BAM 可以表示 范围内的值,因此实际上这也是 SAM 的" "的实际取值范围。


    例如,六字符十六进制字符串 "1 AE 301 "表示字节数组 [0x1a、0xe3、0x1]。


    显式键入简化了格式解析,并有助于在将 SAM 转换为 BAM 时减小文件大小。


    请参阅 https://github.com/samtools/hts-specs 中的 SAMtags.pdf。

  9. 这种表示法对索引和随机存取的影响还有待实施探索。
  10. Peter J. A. Cock, James K. Bonfield, Bastien Chevreux, and Heng Li, SAM/BAM format v1.5 extensions for de novo assemblies, bioRxiv 020024; doi:10.1101/020024.

  11. 在 SEQ 字段中将焊盘/间隙写成 's 可能更方便,但这会引起向后兼容性问题。


    请参阅 SAMtags.pdf 中的注释和填充。

  12. L. Peter Deutsch,GZIP 文件格式规范 4.3 版,RFC 1952。


    值得注意的是,Java GZIPInputStream 类中存在一个已知错误,即该类无法成功解压缩连接的 gzip 压缩包。可以使用内置的 Java util.zip 包创建和处理 BGZF 文件,但由于该错误,在 BGZF 文件上天真地使用 GZIPInputStream 将无法工作。

  13. 空,即压缩长度为零的数据块后形成的空。


    支持在追加模式下重新打开 BAM 文件的实现可以通过写入文件头和对齐记录、关闭文件(添加 EOF 标记)来生成文件;然后重新打开文件进行追加、写入更多对齐记录并关闭文件(添加 EOF 标记)。生成的 BAM 文件将包含一个嵌入的不重要的 EOF 标记块,在读取时应被有效忽略。


    在开始读取文件时生成诊断信息非常有用,这样交互式用户就可以放弃对可能损坏的文件进行冗长的分析。当然,这只有在有关流支持随机存取的情况下才有可能。

  14. 如第 1.4 节所述,保留的 FLAG 位应写为 0,并在当前软件读取时忽略。


    为了向后兼容,不存在的 QNAME(在 SAM 中表示为" ")将存储为 C 字符串 "*\0"。

  15. 每个整数值的符号性和大小由实现选择,但通常是最小的即可。


    出于历史原因,BAM 将" "字段值表示为文本十六进制数字,而不是二进制数据。现代应用程序可能更喜欢使用 "B、C "数组字段,而不是" "字段。

  16. 请参见 CSIv1.pdf,网址为https://github.com/samtools/hts-specs。这是一个单独的规范,因为除了 BAM 之外,CSI 还用于索引其他坐标排序文件格式。


    W. James Kent 等人,《加州大学洛杉矶分校的人类基因组浏览器》,《基因组研究》,2002 年 12 期:996-1006;doi:10.1101/ gr.229102;PMID:12045153。特别参见《数据库》,第 1003 页。

  17. 单个仓中的块数实际上受到可用内存的限制,在任何情况下,通常最多为数千个。


    "放置的未映射读数 "是指根据 FLAG 未映射的读数,但其 RNAME 和 POS 字段已被填入,从而 "放置 "在参考序列上(见第 2 节)。相反,未定位未映射读数的 RNAME 和 POS 字段为 "*"和 "0"。

  18. 见 SAMtags.pdf 附录 A,网址:https://github.com/samtools/hts-specs