# longestmrna — 最长转录本提取 | Longest mRNA Extraction

一句话理解：**每个基因挑出一条最有代表性的蛋白序列**——从基因组 FASTA + GFF3 注释出发，为每个基因选出最长的那条 mRNA 转录本，提取它对应的蛋白质序列（以及可选的 CDS 序列），供后续注释、建库、比对使用。

## 功能概述 | Overview

- 从 GFF3 中按 CDS 总长度选出每个基因的最长转录本
- 用 gffread 提取蛋白质序列，seqkit 精确筛选出最长转录本
- 可选同时提取 CDS 核苷酸序列
- 自动生成基因信息表（转录本 ↔ 基因 ↔ 染色体坐标映射）
- 自动对齐 GFF 与基因组序列名，跳过基因组中不存在的 seqid；跳过无 CDS 的非编码基因

## 快速开始 | Quick Start

```bash
biopytools longestmrna -g genome.fasta -f annotation.gff3 -o longest_proteins.fasta
```

最小输入：一个基因组 FASTA + 一个 GFF3 注释文件 + 一个输出 FASTA 路径（输出蛋白质序列）。

## 零基础概念速览 | Concepts in plain words

不熟悉生信术语的话，先花两分钟看这张表：

| 术语 | 通俗理解 |
|------|----------|
| 转录本 (transcript) | 一个基因可能被「剪」成多种不同的 mRNA 版本，每种叫一个转录本 |
| 可变剪接 | 同一个基因因剪接方式不同，产生多条不同的 mRNA，像同一本书出了多个删节版 |
| CDS | 真正翻译成蛋白质的编码区，不含两端非编码区（UTR） |
| 最长转录本 | 编码区加起来最长的那个版本，常用作该基因的「代表序列」 |
| GFF3 | 记录每个基因/转录本/CDS 在基因组上坐标的标准注释格式 |
| 蛋白序列 / CDS 序列 | 前者是氨基酸序列，后者是编码它的核酸序列 |

## 输入 | Input

### 基因组 FASTA（-g, --genome）

标准 FASTA，序列名须与 GFF3 第一列的 seqid 一致（不一致的行会被自动过滤）。

### GFF3 注释（-f, --gff3）

标准 GFF3，需包含 mRNA/transcript 与 CDS 行，才能正确计算每个转录本的编码长度并选出最长者。

```text
chr1    source    gene    1000    5000    .    +    .    ID=gene1
chr1    source    mRNA    1000    5000    .    +    .    ID=gene1.t1;Parent=gene1
chr1    source    CDS     1000    2000    .    +    0    Parent=gene1.t1
chr1    source    mRNA    1100    4800    .    +    .    ID=gene1.t2;Parent=gene1
chr1    source    CDS     1100    2000    .    +    0    Parent=gene1.t2
```

## 参数说明 | Parameters

### 必需参数 | Required

**通俗理解|In plain words:** 三个必填项：基因组、GFF3、输出蛋白文件。缺一不可。

### 可选输出 | Optional outputs

**通俗理解|In plain words:** 这两个是「加菜」。`--gene-info` 指定基因信息表的输出位置（不指定会自动生成在基因组同目录下，名为 `{基因组名}.gene.info.txt`）；`--cds-output` 指定后才会额外提取 CDS 核苷酸序列。**一般只需要蛋白序列时，这两个都不必写。**

## 分析流程 | Pipeline

**通俗理解|In plain words:** 五步：先让注释和基因组「对上号」，再算每个基因里哪个转录本最长，接着写基因信息表，然后提取蛋白序列，最后（可选）提取 CDS。

```text
输入 基因组 FASTA + GFF3
    │
    ▼
步骤0: 对齐 GFF seqid 与基因组序列名（过滤不存在的 seqid）
    │
    ▼
步骤1: 解析 GFF3，按 CDS 总长选出每个基因的最长转录本
    │
    ▼
步骤2: 生成基因信息表（mRNA ↔ 基因 ↔ 坐标映射）
    │
    ▼
步骤3: gffread 提取蛋白序列 + seqkit 筛选最长转录本
    │
    ▼
步骤4: （可选）提取 CDS 核苷酸序列
    │
    ▼
步骤5: 汇总统计
```

## 输出 | Output

```text
longest_proteins.fasta            # 每个基因最长转录本的蛋白质序列（核心）
{基因组名}.gene.info.txt          # 基因信息表（默认与基因组同目录）
{指定路径}.fasta                  # CDS 序列（仅 --cds-output 时）
tmp/                              # 运行期临时文件（结束后清理）
```

### 关键文件说明 | Key files

- **蛋白质序列文件**（`-o`）：每个基因一条，FASTA 头为该最长转录本的 ID
- **基因信息表**（`--gene-info` 或自动生成）：表头为 `mRNA_ID / gene_ID / mRNA_start / mRNA_end / gene_start / gene_end / strand / chr`，一行对应一个基因的最长转录本
- **CDS 序列文件**（`--cds-output`）：每个基因最长转录本的编码区核酸序列

## 结果解读 | Interpreting Results

**通俗理解|In plain words:** 跑完看两个数字——「一共处理了多少基因、其中多少是多转录本基因」，以及「平均转录本长度」。输出的蛋白文件里每个基因恰好一条序列。

- 汇总统计会打印：总基因数、多转录本基因数（这些基因有多个版本，工具帮你挑了最长的）、平均转录本长度、实际提取的最长转录本数
- 若打印了「跳过的无 CDS 基因数」，说明这些基因没有编码区（如非编码 RNA 基因），不会出现在蛋白输出里，属正常现象
- 蛋白文件条数应等于「提取的最长转录本数」，与「总基因数」的差额就是被跳过的非编码基因

## 参数选择建议 | Parameter Guidance

- **只要代表蛋白序列**：三个必填参数即可，其余不用管
- **还要建基因到坐标的对照表**：留意自动生成的 `{基因组名}.gene.info.txt` 位置，或用 `--gene-info` 指定到指定目录
- **还要编码区核酸序列**：加 `--cds-output`
- **GFF 里有非编码基因**：无需处理，程序自动跳过并给出计数

<!-- BEGIN PARAMS:auto -->

## 参数速查 | Parameter reference

> 本表由 `scripts/gen_docs_params.py` 从 CLI 定义自动生成,勿手改|Auto-generated from CLI definitions; do not edit by hand

### 命令行参数 | CLI options

| 参数 | 默认值 | 类型 | 说明 |
|------|--------|------|------|
| `--genome, -g` | 必填 | Path | 输入基因组FASTA文件｜Input genome FASTA file |
| `--gff3, -f` | 必填 | Path | 输入GFF3注释文件｜Input GFF3 annotation file |
| `--output, -o` | 必填 | Path | 输出FASTA文件｜Output FASTA file |
| `--gene-info` | — | Path | 基因信息输出文件｜Gene info output file |
| `--cds-output` | — | Path | CDS核苷酸序列输出文件｜CDS nucleotide sequence output file |

### 模块直调参数 | Direct invocation options

| 参数 | 默认值 | 类型 | 说明 |
|------|--------|------|------|
| `-g, --genome` | 必填 |  | 输入基因组FASTA文件｜Input genome FASTA file |
| `-f, --gff3` | 必填 |  | 输入GFF3注释文件｜Input GFF3 annotation file |
| `-o, --output` | 必填 |  | 输出FASTA文件｜Output FASTA file |
| `--gene-info` | — |  | 基因信息输出文件｜Gene info output file (auto-generated by default) |
| `--cds-output` | — |  | CDS核苷酸序列输出文件｜CDS nucleotide sequence output file |

<!-- END PARAMS:auto -->

## 依赖 | Dependencies

- gffread（默认裸名 `gffread`，可由 `GFFREAD_PATH` 或 `~/.config/biopytools/config.yml` 覆盖）
- seqkit（默认裸名 `seqkit`，可由 `SEQKIT_PATH` 覆盖）

两者都通过 conda 环境自动检测调用。

## 常见问题 | FAQ

**Q1：输出的蛋白条数比基因数少，正常吗？**
正常。无 CDS 的非编码基因会被跳过（不进入基因信息表和蛋白输出），程序会打印跳过的数量。

**Q2：GFF 里有些 seqid 在基因组 FASTA 里没有，会报错吗？**
不会。步骤 0 会自动对齐序列名，跳过基因组中不存在的 seqid，保证最长转录本、基因信息、序列输出三者一致。

**Q3：怎么判断「最长」？**
按 CDS（编码区）总长度计算，而不是转录本全长。这样不受 UTR 长度干扰，选出的才是真正编码最长的版本。

**Q4：换输出路径重跑会怎样？**
本工具无断点续传，重跑会重新提取并覆盖输出文件。临时文件重定向到输出目录下的 `tmp/`，结束后清理，不会污染系统 `/tmp`。
