IO 方法

概述

常规的文件 IO 流(或方法)以 File 类描述文件的基本信息,使用单个字节作为数据写入和读取的最小单位。GBC 以 GTBManager 类描述 GTB 文件的基本信息,使用单个位点 Variant 作为数据写入和读取的最小单位。以下是最常用的 API 列表:

以下是简单的进行 GTB 文件 IO 的示例,它读取 https://pmglab.top/gbc/download/assoc.hg19.gtb 上的变异位点,筛选出坐标范围在 chr1:0-200000 的变异位点,并进行 LiftOver:

// 创建文件对象
GTBManager manager = GTBManager.load("https://pmglab.top/gbc/download/assoc.hg19.gtb");

// 创建 GTB 文件写入器
GTBWriter writer = GTBWriter.Builder.of(new File("./assoc.hg19.gtb"))
        .addField("hg38_CHROM", FieldType.Int)
        .addField("hg38_POS", FieldType.Int)
        .addSubjects(manager.getSubjects())
        .build()
        .writeMeta(manager.getMeta());

// 创建 GTB 读取器
GTBReader reader = new GTBReader(manager);

// 创建过滤器
GTBFilter filter = new GTBFilter().filterByCoordinateRange(Chromosome.get("chr1"), new Interval<>(0, 200000));

// 创建 LiftOver
LiftOver liftOver = LiftOver.load(RefGenomeVersion.hg19, RefGenomeVersion.hg38);

Variant variant;

// 按照过滤器读取位点, 只有满足条件的位点会被读入
while ((variant = reader.read(filter)) != null) {
    // liftover 并写入新坐标
    Entry<Chromosome, Integer> hg38Coordinates = liftOver.convertCoordinate(variant.getChromosome(), variant.getPosition());

    // 写入位点的新属性值
    variant.setProperty("hg38_CHROM", hg38Coordinates.getKey().getChromosomeIndex());
    variant.setProperty("hg38_POS", hg38Coordinates.getValue());

    // 写入位点
    writer.write(variant);
}
reader.close();
writer.close();

GTB 基本格式声明

GTB 的基本格式 GTBFormat 包括压缩级别、每个块最多包含的位点数量、基因型向型 3 个参数。

  • 压缩级别越高,压缩比越高,但压缩速度越慢;
  • 每个块包含的位点数越多,压缩比越高,但会影响访问性能和读写时的内存开销

为保证并行操作大规模基因型数据的可行性,GTB 文件的每个基因型块都不超过 128 MB 大小。

此外,GTBFormat 提供了以下两个常用方法,用于标准化补充列名和受试者名称:

  • checkSubjectName(String subjectName):检查受试者名称。不可见字符(如空格、制表符、换行符等)、反斜杠、等号、冒号、分号、逗号、单引号和双引号都被替换为下划线 _
  • fieldNameChecker(String fieldName):检查字段名称是否合法。字段名称不允许为 CHROM, POS, ALLELE, GENOTYPE。

GTB 元信息

GTB 使用 GTBMeta 管理元信息。主要包含 add(String metaKey, String metaValue)add(ByteCode metaKey, ByteCode metaValue) 方法。作为强制性的规定,GTBMeta 拒绝写入以 $gtbformat. 开头的元信息。

以下是使用 GTBMeta 写入和读取元信息的实例:

GTBMeta meta = new GTBMeta();

// 写入元信息
meta.add("fileformat", "VCFv4.4");
meta.add("contig", "<ID=1,assembly=b37,length=249250621>");
meta.add("contig", "<ID=2,assembly=b37,length=243199373>");
meta.add("FORMAT", "<ID=GT,Number=1,Type=String,Description=\"Genotype\">");

// 读取元信息, 返回结果为所有的键为 contig 的元信息值数组
BaseArray<ByteCode> contigs = meta.get("contig").values();

GTB 写入器

GTB 写入器 GTBWriterGTBPartWriter 使用建造者模式进行初始化,GTBWriter.Builder 是它们的初始化方法。在初始化阶段,使用以下方法配置信息:

  • setFormat(GTBFormat format):设置 GTB 文件格式
  • addSubject(String subjectName):添加受试者
  • addSubjects(String[] subjectNames):添加多个受试者
  • addSubjects(Iterable<String> subjectNames):添加多个受试者
  • addField(String fieldName, FieldType fieldType):添加其他字段
  • addFields(Map<String, FieldType> fields):添加其他字段

有关 FieldType 支持的类型,请参阅:枚举 FieldType。GTBWriter 中添加了其他字段时,需要向 Variant 对象添加相应字段的属性值,否则会引发空指针异常。

完成配置后,使用 .build() 方法实例化 GTB 写入器 GTBWriter,或使用 .build(int nThreads) 实例化 GTB 分部写入器 GTBPartWriter。分部写入器将文件分为指定数量的子部份,每一个部份都独立使用 GTBWriter 进行数据写入,全部写入任务完成后根据分部索引拼接子文件:

-----  ++++++  ~~~~~~     --->      -----++++++~~~~~~   
Part1  Part2   Part3                合并

分部写入器最常用的场景是为每一个染色体分配一个子部份,完成压缩后按照染色体编号进行拼接。

GTBWriter 和 GTBPartWriter 都通过 writeMeta(String metaKey, String metaValue)writeMeta(ByteCode metaKey, ByteCode metaValue)writeMeta(GTBMeta metas) 写入元信息。GTBWriter 通过调用 write(Variant variant)write(Variants variants) 写入变异位点。GTBPartWriter 则需要先指定分部索引,获得相应的 GTBWriter 后执行写入变异位点。完成写入后,请务必调用 close() 方法关闭文件 IO 流。

GTB 管理器

GTB 管理器对象 GTBManager 用于维护同个文件路径指向的 GTB 文件信息。它通过缓存结构设计,使得多次请求同个文件的管理器时仅扫描一次文件的索引信息,后续所有的请求都返回同一个管理器对象。加载一个 GTB 文件的管理器,请使用 GTBManager.load(Object fileObject)

GTBManager 包含如下常用的方法:

  • getFieldNum():获取当前数据表包含的列数(添加的字段数)
  • getVariantNum():获取位点数
  • getSubjectNum():获取样本数
  • containField(String fieldName):是否包含指定的列字段
  • containSubject(String subject):是否包含指定的样本名
  • getFields():获取补充的其他字段及其类型
  • getSubjects():获取样本序列
  • getFieldType(String fieldName):获取指定字段的类型
  • indexOfSubject(String subject):获取指定样本的索引
  • subjectOfIndex(int index):获取指定索引对应的样本名
  • getMeta():获取元信息管理器
  • isOrdered():检查文件是否坐标有序

GTB 过滤器

GTB 过滤器 GTBFilter 对象用于读取 GTB 变异位点时快速进行过滤。它包含以下常用方法,这些方法建立了变异位点对象 Variant 和基因型序列 Genotypes 的筛选条件:

  • filterByAC(Interval<Integer> range):按照等位基因频数过滤
  • filterByAN(Interval<Integer> range):按照等位基因总数过滤
  • filterByAF(Interval<Float> range):按照等位基因频率过滤
  • filterByAlleleNum(Interval<Float> range):按照可变等位基因数过滤位点
  • filterByChromosome(Chromosome chromosome):按照染色体进行过滤(只读取指定的染色体)
  • filterByChromosomes(Chromosome... chromosomes):按照多个染色体进行过滤(只读取指定的染色体)
  • filterByChromosomes(Iterable<Chromosome> chromosomes):按照多个染色体进行过滤(只读取指定的染色体)
  • filterByCoordinate(Chromosome chromosome, int position):添加染色体-坐标过滤器(只读取指定的坐标)
  • filterByCoordinates(Chromosome chromosome, Iterable<Integer>poses):添加染色体-坐标过滤器(只读取指定的坐标)。当指定的染色体的筛选坐标为 null 时,表示读取该染色体的所有位点
  • filterByCoordinates(Map<Chromosome, Iterable<Integer>> poses):添加多个染色体-坐标过滤器(只读取指定的坐标)
  • filterByCoordinateRange(Chromosome chromosome, Interval<Integer> ranges):添加染色体-坐标范围过滤器(只读取指定的坐标)
  • filterByCoordinateRanges(Map<Chromosome, Interval<Integer>> poses):添加多个染色体-坐标范围过滤器(只读取指定的坐标)。当指定的染色体的筛选坐标范围为 null 时,表示读取该染色体的所有位点
  • filterByVariantIndex(Interval<Long> indexRangeOfVariant):添加变异位点指针范围过滤器

此外,对于复杂的条件判断,可以使用以下方法进行:

  • filterByVariant(Function<Variant, Boolean> function):位点过滤器

GTBFilter 支持通过链式调用的方式添加过滤器,如下所示添加多个复杂过滤器方法:

LiftOver liftOver = LiftOver.load(RefGenomeVersion.hg19, RefGenomeVersion.hg38);
GTBFilter filter = new GTBFilter()
        .filterByAC(new Interval<>(0, 100))
        .filterByAF(new Interval<>(0.1f, 0.9f))
        .filterByChromosome(Chromosome.get("chr1"))
        .filterByVariant(variant -> liftOver.convertCoordinate(variant) != null);

GTB 读取器

GTB 读取器 GTBReader 用于创建一个按行读取变异位点的读取器实例,包含以下构造器方法:

  • GTBReader(Object manager):默认构造器方法,加载所有的基因和补充字段
  • GTBReader(Object manager, boolean loadGenotype):构造器方法,可选是否加载基因型
  • GTBReader(Object manager, boolean loadGenotype, boolean loadField):构造器方法,可选是否加载基因型、补充字段
  • GTBReader(Object manager, boolean loadGenotype, Iterable<String> fields):构造器方法,可选是否加载基因型,以及筛选加载的补充字段。fieldsnull 时表示加载所有的补充字段

请注意,单个 GTBReader 是线程不安全的,如果需要并行读取文件,请创建多个 GTBReader 实例。

实例化的 GTBReader 主要包含以下方法:

  • read():读取并返回一个变异位点对象,到达文件尾部时返回 null
  • reads():读取连续地、坐标相同的多个变异位点,并返回一个多位点对象,当 GTB 文件无序时,它无法返回正确的结果
  • read(GTBFilter filter):读取一个满足过滤条件的位点,当不存在这样的位点时返回 null,并且文件指针移动到末尾
  • tell():获取文件的位点指针(即位点索引)
  • seek(long variantIndex):移动文件位点指针到指定位置
  • seek(GTBFilter filter):移动文件位点指针到满足过滤器条件的位置,当不存在这样的位点时返回 false,文件指针保持不变
  • limit(Interval<Long> ranges):设置当前读取器的读取范围
  • remaining():获取当前读取器剩余可读的记录条目数
  • part(int nParts):将 GTBReader 从当前指针位置到文件末尾均等地分为 nPart

对于读取的位点,通过 Variant.getProperty(IGenotypes.class) 获得基因型序列。有关基因型序列的操作方法详见 IGenotypes

Copyright ©张柳彬 all right reserved文档修订时间: 2023-04-18 20:16:55

results matching ""

    No results matching ""