---
name: cnv-caller-plotter
description: 从全基因组测序数据中检测拷贝数变异，并生成可用于发表的全基因组 CNV 图。支持癌症基因组学和罕见病分析中的 CNV 检出、分段和可视化。
allowed-tools: [Read, Write, Bash, Edit, Grep]
license: MIT
metadata:
  skill-author: AIPOCH
displayName: "CNV 检测可视化"
version: "1.0.1"
slug: cnv-caller-plotter
---

# CNV 检测与绘图工具

从全基因组测序（WGS）数据中检测拷贝数变异（CNV），并为癌症基因组学、罕见病分析和群体遗传学研究生成全基因组可视化图表。提供 CNV 检出、分段分析和可发表级别的可视化。

**核心能力：**
- **从 WGS 检测 CNV**：从已比对的测序数据中识别拷贝数增加和缺失
- **基因组分段**：将基因组划分为区间/窗口以进行拷贝数估计
- **灵活的输入支持**：处理 BAM、VCF 及其他标准基因组学格式
- **可发表级别的图表**：生成 PNG、PDF 或 SVG 格式的全基因组 CNV 概览图
- **标准输出格式**：以 BED 格式导出 CNV 检出结果，便于下游分析

---

## 何时使用

**✅ 适用场景：**
- 分析**癌症基因组**以识别体细胞拷贝数变异（SCNA）
- 研究疑似由拷贝数变异引起的**罕见病**病因
- 进行**群体遗传学**研究，比较不同组间的 CNV 频率
- 为出版物或报告生成**全基因组 CNV 可视化**图表
- 创建**BED 格式的 CNV 检出结果**以与其他分析流程集成
- 对肿瘤和正常样本进行**CNV 比较分析**
- 用测序数据验证**来自 SNP 芯片的 CNV 检出结果**

**❌ 不适用场景：**
- 处理**靶向测序面板**（外显子组/靶向捕获）→ 使用 CNVkit 或 ExomeDepth 等专用工具
- 检测涉及易位或倒位的**结构变异**→ 使用 `structural-variant-caller`
- 分析**单细胞 RNA-seq 数据**→ 使用单细胞专用 CNV 工具（如 inferCNV）
- 检测**小片段插入缺失**（<50bp）→ 使用 `variant-caller` 进行小变异检测
- 出于诊断目的需要**临床级 CNV 检测**→ 使用经过适当质控验证的临床流程
- 处理**低覆盖度数据**（<10x）→ 结果可能不可靠，建议考虑基于 SNP 芯片的方法

**相关技能：**
- **上游 (Upstream)**：`fastqc-report-interpreter`、`alignment-quality-checker`、`variant-caller`
- **下游 (Downstream)**：`circos-plot-generator`、`go-kegg-enrichment`、`heatmap-beautifier`

---

## 与其他技能的集成

**上游技能：**
- `fastqc-report-interpreter`：在 CNV 检出前评估测序质量；低质量数据可能产生不可靠的 CNV
- `alignment-quality-checker`：核查 BAM 文件质量和覆盖均匀性；覆盖不均会导致 CNV 假象
- `variant-caller`：生成 SNV/indel 检出结果，用于癌症样本的 CNV-SNV 联合分析

**下游技能：**
- `circos-plot-generator`：创建整合 CNV 与其他基因组特征的环形基因组图
- `go-kegg-enrichment`：对 CNV 区域内的基因进行通路富集分析
- `heatmap-beautifier`：可视化多个样本间的 CNV 概览

**完整工作流：**
```
Raw WGS Data → fastqc-report-interpreter → alignment-quality-checker → cnv-caller-plotter → circos-plot-generator → Publication Figures
```

---

## 核心功能

### 1. 拷贝数变异检测

通过分析读段深度模式，从 WGS 数据中识别存在拷贝数增加（扩增）或缺失（缺失）的基因组区域。

```python
from scripts.main import CNVCaller

# Initialize CNV caller with bin size
caller = CNVCaller(bin_size=1000)

# Call CNVs from BAM file
cnv_calls = caller.call_cnvs(
    input_file="sample.bam",
    reference="hg38.fa"
)

# Review detected CNVs
for cnv in cnv_calls:
    print(f"{cnv['chrom']}:{cnv['start']}-{cnv['end']}")
    print(f"  Copy Number: {cnv['cn']}")
    if cnv['cn'] > 2:
        print(f"  Type: Amplification (gain)")
    elif cnv['cn'] < 2:
        print(f"  Type: Deletion (loss)")
```

**参数：**

| Parameter | Type | Required | Description | Default |
|-----------|------|----------|-------------|---------|
| `input_file` | str | Yes | 输入 BAM 或 VCF 文件路径 | None |
| `reference` | str | Yes | 参考基因组 FASTA 路径 | None |
| `bin_size` | int | No | 用于分段的基因组区间大小（bp） | 1000 |

**CNV 检出策略：**

| Approach | Best For | Sensitivity | Specificity |
|----------|----------|-------------|-------------|
| **读段深度分析** | 大型 CNV（>10kb） | 高 | 中 |
| **双端配对定位** | 中等 CNV（1-10kb） | 中 | 高 |
| **拆分读段分析** | 小型 CNV（<1kb） | 中 | 高 |
| **联合方法** | 综合检测 | 高 | 高 |

**最佳实践：**
- ✅ **使用合适的区间大小**：WGS 使用 1000bp，靶向分析可用更小的区间
- ✅ **确保足够的覆盖度**：可靠的 CNV 检测至少需要 15-20x
- ✅ **匹配参考基因组**：使用与比对时相同的参考基因组（hg19 与 hg38）
- ✅ **检查覆盖均匀性**：GC 偏倚可导致假阳性 CNV

**常见问题及解决方案：**

**问题：重复区域中出现假阳性 CNV**
- 症状：在中心粒、端粒或片段重复区域检出大量 CNV
- 解决方案：过滤与已知问题区域重叠的 CNV；使用可映射性过滤器

**问题：小型 CNV 灵敏度低**
- 症状：即使覆盖度充足，仍漏检 <5kb 的 CNV
- 解决方案：减小区间大小；除深度信号外，同时使用拆分读段或双端配对信号

### 2. 基因组分段与分箱

将基因组划分为窗口/区间以进行拷贝数估计，从而对整个基因组进行系统性分析。

```python
from scripts.main import CNVCaller

# Different bin sizes for different applications
bin_configs = {
    "high_resolution": 100,    # For small CNV detection
    "standard": 1000,          # Default for WGS
    "low_resolution": 10000    # For large-scale alterations
}

for config_name, bin_size in bin_configs.items():
    caller = CNVCaller(bin_size=bin_size)
    print(f"\n{config_name} (bin_size={bin_size}bp):")
    
    # Calculate approximate number of bins for human genome
    genome_size = 3_000_000_000  # 3 Gb
    num_bins = genome_size // bin_size
    print(f"  Estimated bins: ~{num_bins:,}")
    print(f"  Resolution: {bin_size}bp")
```

**区间大小选择指南：**

| Bin Size | Resolution | Use Case | Coverage Required |
|----------|------------|----------|-------------------|
| **100 bp** | 高 | 小型 CNV（<5kb） | >30x |
| **1000 bp** | 标准 | 通用 WGS 分析 | >15x |
| **10000 bp** | 低 | 大型染色体畸变 | >5x |
| **可变** | 自适应 | 混合分辨率 | >20x |

**最佳实践：**
- ✅ **区间大小与预期 CNV 大小匹配**：检测小型 CNV 时使用更小的区间
- ✅ **考虑覆盖深度**：更高的覆盖度可支持更小的区间
- ✅ **排除不可映射区域**：过滤映射率为零或极低的区间
- ✅ **对 GC 含量归一化**：富含 GC 的区域覆盖模式不同

**常见问题及解决方案：**

**问题：区间过小导致分段结果噪声大**
- 症状：拷贝数估计不稳定，方差很高
- 解决方案：增大区间大小；应用平滑算法；用更大的区间作为基线

**问题：区间过大导致遗漏大型 CNV**
- 症状：跨越多个区间的大型缺失/扩增未被检出
- 解决方案：使用统计分段方法（CBS、PSCBS）合并相邻的变异区间

### 3. 全基因组可视化

生成展示所有染色体拷贝数概览的可发表级别图表，便于视觉解读和展示。

```python
from scripts.main import CNVCaller

caller = CNVCaller(bin_size=1000)

# Example CNV calls for plotting
cnv_calls = [
    {"chrom": "chr1", "start": 1000000, "end": 2000000, "cn": 3},   # Gain
    {"chrom": "chr7", "start": 50000000, "end": 55000000, "cn": 1}, # Loss
    {"chrom": "chr17", "start": 35000000, "end": 36000000, "cn": 4} # High-level amplification
]

# Generate plots in different formats
output_dir = "./cnv_results"

for fmt in ["png", "pdf", "svg"]:
    plot_file = caller.plot_genome_wide(
        cnv_calls=cnv_calls,
        output_path=output_dir,
        fmt=fmt
    )
    print(f"Generated: {plot_file}")

# Plot features:
# - Genome-wide view with all chromosomes
# - Copy number on Y-axis (0-6 typical range)
# - Chromosomal position on X-axis
# - Color coding: red=loss, blue=gain, black=neutral
```

**输出格式：**

| Format | Extension | Best For | File Size |
|--------|-----------|----------|-----------|
| **PNG** | .png | 网页、演示、快速查看 | 中 |
| **PDF** | .pdf | 出版物、高质量打印 | 大 |
| **SVG** | .svg | 矢量编辑、可缩放图形 | 小 |

**最佳实践：**
- ✅ **发表使用 PDF**：矢量格式在任意缩放下都能保持质量
- ✅ **包含基线（CN=2）**：参考线有助于解读增加/缺失
- ✅ **使用色盲友好配色**：增加与缺失使用可明显区分的颜色
- ✅ **标注关键区域**：标记已知癌基因或感兴趣区域

**常见问题及解决方案：**

**问题：CNV 过多导致图表过于密集**
- 症状：重叠的点使图表难以阅读
- 解决方案：使用分段合并相邻检出结果；调整点大小/透明度

**问题：女性样本未显示 ChrY**
- 症状：女性受试者图表中缺失该染色体
- 解决方案：根据覆盖度动态检测性别；相应调整图表

### 4. BED 格式导出

以标准 BED 格式导出 CNV 检出结果，以便与基因组浏览器及下游分析工具兼容。

```python
from scripts.main import CNVCaller

caller = CNVCaller()

# Example CNV calls
cnv_calls = [
    {"chrom": "chr1", "start": 1000000, "end": 2000000, "cn": 3},
    {"chrom": "chr7", "start": 50000000, "end": 55000000, "cn": 1},
]

# Export to BED format
bed_file = caller.save_bed(cnv_calls, "./output")

# BED format structure:
# chrom  start    end       name      score  strand
# chr1   1000000  2000000   CN=3      .      .
# chr7   50000000 55000000  CN=1      .      .

print(f"BED file saved: {bed_file}")

# Read and display BED content
with open(bed_file, 'r') as f:
    print("\nBED file content:")
    for line in f:
        print(line.strip())
```

**BED 格式规范：**

| Column | Field | Description | Example |
|--------|-------|-------------|---------|
| 1 | chrom | 染色体名称 | chr1, chrX |
| 2 | start | 起始位置（从 0 开始） | 1000000 |
| 3 | end | 结束位置（从 1 开始） | 2000000 |
| 4 | name | CNV 注释 | CN=3 |
| 5 | score | 可选质量分数 | . |
| 6 | strand | 链信息（通常为 .） | . |

**最佳实践：**
- ✅ **使用从 0 开始的坐标**：标准 BED 格式起始位置从 0 开始，结束位置从 1 开始
- ✅ **在名称中包含拷贝数**：使 CNV 状态一目了然
- ✅ **按染色体和位置排序**：许多工具（bedtools、IGV）需要此项
- ✅ **验证格式**：分发前用 `bedtools` 或基因组浏览器进行检查

**常见问题及解决方案：**

**问题：基因组浏览器拒绝加载 BED 文件**
- 症状：IGV 或 UCSC 基因组浏览器加载 BED 时报错
- 解决方案：确保染色体命名正确（chr1 与 1）；对文件排序；检查是使用 tab 还是空格

**问题：坐标系统混淆**
- 症状：在不同工具中 CNV 位置出现 1bp 的偏移
- 解决方案：BED 从 0 开始计数，GFF/VCF 从 1 开始计数；必要时进行转换

### 5. 肿瘤-正常样本对比

将肿瘤样本与配对正常样本的 CNV 概览进行对比，以识别体细胞拷贝数变异（SCNA）。

```python
from scripts.main import CNVCaller

caller = CNVCaller(bin_size=1000)

# Call CNVs in tumor and normal samples
tumor_cnvs = caller.call_cnvs("tumor.bam", "hg38.fa")
normal_cnvs = caller.call_cnvs("normal.bam", "hg38.fa")

# Identify somatic CNVs (present in tumor, not in normal)
def find_somatic_cnvs(tumor_calls, normal_calls):
    """Identify CNVs present in tumor but not normal."""
    somatic_cnvs = []
    
    for t_cnv in tumor_calls:
        is_somatic = True
        
        # Check if similar CNV exists in normal
        for n_cnv in normal_calls:
            if (t_cnv['chrom'] == n_cnv['chrom'] and
                abs(t_cnv['start'] - n_cnv['start']) < 10000 and
                abs(t_cnv['end'] - n_cnv['end']) < 10000 and
                t_cnv['cn'] == n_cnv['cn']):
                is_somatic = False
                break
        
        if is_somatic:
            somatic_cnvs.append(t_cnv)
    
    return somatic_cnvs

somatic_cnvs = find_somatic_cnvs(tumor_cnvs, normal_cnvs)

print(f"Total tumor CNVs: {len(tumor_cnvs)}")
print(f"Somatic CNVs: {len(somatic_cnvs)}")

# Categorize somatic alterations
amplifications = [c for c in somatic_cnvs if c['cn'] > 2]
deletions = [c for c in somatic_cnvs if c['cn'] < 2]

print(f"  Amplifications: {len(amplifications)}")
print(f"  Deletions: {len(deletions)}")
```

**体细胞与生殖细胞变异分类：**

| Category | Tumor CN | Normal CN | Interpretation |
|----------|----------|-----------|----------------|
| **体细胞扩增** | >2 | 2 | 肿瘤特异性增加 |
| **体细胞缺失** | <2 | 2 | 肿瘤特异性缺失 |
| **生殖细胞 CNV** | ≠2 | ≠2 | 遗传性 CNV |
| **LOH** | 1 | 2 | 杂合性缺失 |

**最佳实践：**
- ✅ **尽可能使用配对正常样本**：这对区分体细胞与生殖细胞变异至关重要
- ✅ **考虑肿瘤纯度**：低纯度样本的 CNV 信号会被削弱
- ✅ **验证关键发现**：对重要 CNV 使用正交方法（FISH、qPCR）验证
- ✅ **考虑克隆性**：亚克隆 CNV 可能以较低频率存在

**常见问题及解决方案：**

**问题：正常样本混入肿瘤样本**
- 症状：CNV 信号弱于预期；出现小数拷贝数
- 解决方案：估计肿瘤纯度；使用纯度校正的 CNV 检出方法

**问题：生殖细胞 CNV 被误判为体细胞变异**
- 症状：许多"体细胞"CNV 看起来像常见多态性
- 解决方案：与群体 CNV 数据库（DGV、gnomAD-SV）进行过滤比对

### 6. 质量控制与过滤

应用质量过滤器以去除假象 CNV 检出结果，提高结果可靠性。

```python
from scripts.main import CNVCaller

caller = CNVCaller()

# Example raw CNV calls with QC metrics
cnv_calls = [
    {
        "chrom": "chr1", "start": 1000000, "end": 2000000, "cn": 3,
        "quality_score": 50, "supporting_reads": 150
    },
    {
        "chrom": "chr7", "start": 50000000, "end": 50001000, "cn": 0,
        "quality_score": 10, "supporting_reads": 5  # Likely artifact
    },
]

# Apply quality filters
def filter_cnvs(cnv_list, min_quality=20, min_size=1000, min_support=20):
    """Filter CNVs based on quality metrics."""
    filtered = []
    
    for cnv in cnv_list:
        size = cnv['end'] - cnv['start']
        quality = cnv.get('quality_score', 0)
        support = cnv.get('supporting_reads', 0)
        
        # Apply filters
        if quality < min_quality:
            continue
        if size < min_size:
            continue
        if support < min_support:
            continue
            
        filtered.append(cnv)
    
    return filtered

# Filter with different stringencies
for min_q in [10, 20, 30]:
    filtered = filter_cnvs(cnv_calls, min_quality=min_q)
    print(f"Quality >= {min_q}: {len(filtered)} CNVs retained")

# Additional filters to consider:
# - Exclude segmental duplications
# - Exclude centromeres and telomeres
# - Minimum number of supporting bins
# - Concordance with paired-end or split-read signals
```

**质量指标：**

| Metric | Threshold | Purpose |
|--------|-----------|---------|
| **质量分数** | >20 | CNV 检出结果的整体置信度 |
| **大小** | >1kb | 去除小型假象检出结果 |
| **支持读段数** | >20 | 充足的证据深度 |
| **Log2 比值** | |0.3| | 与二倍体的显著偏差 |
| **可映射性** | >0.8 | 可靠的唯一映射 |

**最佳实践：**
- ✅ **应用大小过滤**：去除 <1kb 的 CNV（通常为假象）
- ✅ **过滤重复区域**：排除已知问题区域
- ✅ **使用多种证据类型**：结合深度、双端配对和拆分读段信号
- ✅ **验证高影响 CNV**：对治疗靶点使用正交方法验证

**常见问题及解决方案：**

**问题：低质量 CNV 检出结果过多**
- 症状：检出数百甚至数千个 CNV
- 解决方案：提高质量阈值；应用群体频率过滤

**问题：真实 CNV 被过滤掉**
- 症状：已知的癌症驱动 CNV 缺失于结果中
- 解决方案：使用基因特异性过滤；手动复核感兴趣区域

---

## 完整工作流示例

**从 WGS 数据到 CNV 可视化：**

```bash
# Step 1: Call CNVs from tumor sample
python scripts/main.py \
  --input tumor_sample.bam \
  --reference hg38.fa \
  --output tumor_cnv/ \
  --bin-size 1000 \
  --plot-format pdf

# Step 2: Call CNVs from matched normal
python scripts/main.py \
  --input normal_sample.bam \
  --reference hg38.fa \
  --output normal_cnv/ \
  --bin-size 1000

# Step 3: Compare and identify somatic CNVs
# (Use Python API for comparison logic)

# Step 4: Generate final plots
python scripts/main.py \
  --input tumor_sample.bam \
  --reference hg38.fa \
  --output final_results/ \
  --plot-format pdf
```

**Python API 用法：**

```python
from scripts.main import CNVCaller
from pathlib import Path

def analyze_cancer_genome(
    tumor_bam: str,
    normal_bam: str,
    reference: str,
    output_dir: str
) -> dict:
    """
    Complete cancer genome CNV analysis workflow.
    """
    caller = CNVCaller(bin_size=1000)
    
    # Create output directory
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    
    # Call CNVs in both samples
    print("Calling CNVs in tumor sample...")
    tumor_cnvs = caller.call_cnvs(tumor_bam, reference)
    
    print("Calling CNVs in normal sample...")
    normal_cnvs = caller.call_cnvs(normal_bam, reference)
    
    # Identify somatic alterations
    somatic_cnvs = identify_somatic(tumor_cnvs, normal_cnvs)
    
    # Generate outputs
    tumor_bed = caller.save_bed(tumor_cnvs, output_dir)
    somatic_bed = caller.save_bed(somatic_cnvs, f"{output_dir}/somatic")
    plot_file = caller.plot_genome_wide(tumor_cnvs, output_dir, "pdf")
    
    # Calculate statistics
    stats = {
        "total_tumor_cnvs": len(tumor_cnvs),
        "somatic_cnvs": len(somatic_cnvs),
        "amplifications": len([c for c in somatic_cnvs if c['cn'] > 2]),
        "deletions": len([c for c in somatic_cnvs if c['cn'] < 2]),
        "output_files": {
            "tumor_bed": tumor_bed,
            "somatic_bed": somatic_bed,
            "genome_plot": plot_file
        }
    }
    
    return stats

# Execute workflow
results = analyze_cancer_genome(
    tumor_bam="tumor.bam",
    normal_bam="normal.bam",
    reference="hg38.fa",
    output_dir="./cnv_analysis"
)

print(f"\nAnalysis complete!")
print(f"Total tumor CNVs: {results['total_tumor_cnvs']}")
print(f"Somatic CNVs: {results['somatic_cnvs']}")
print(f"  Amplifications: {results['amplifications']}")
print(f"  Deletions: {results['deletions']}")
```

**预期输出文件：**

```
cnv_analysis/
├── cnv_calls.bed              # All CNV calls in BED format
├── somatic/
│   └── cnv_calls.bed         # Somatic CNVs only
├── cnv_plot.pdf              # Genome-wide visualization
└── analysis_summary.json     # Statistics and metadata
```

---

## 常见模式

### 模式 1：癌症基因组分析（肿瘤-正常配对）

**场景**：与配对正常组织相比，识别癌症样本中的体细胞拷贝数变异。

```json
{
  "analysis_type": "cancer_genome",
  "samples": {
    "tumor": "tumor_wgs.bam",
    "normal": "blood_normal.bam"
  },
  "reference": "hg38.fa",
  "parameters": {
    "bin_size": 1000,
    "min_cnv_size": 10000,
    "plot_format": "pdf"
  },
  "expected_outputs": [
    "Somatic CNV calls (BED format)",
    "Genome-wide CNV profile plot",
    "CNV statistics and summary"
  ]
}
```

**工作流：**
1. 处理肿瘤和正常样本的 BAM 文件
2. 分别对每个样本进行 CNV 检出
3. 对比以识别体细胞变异
4. 用群体数据库过滤生殖细胞多态性
5. 对 CNV 区域内的癌基因进行注释
6. 生成可发表级别的可视化图表
7. 用正交方法验证关键驱动变异

**输出示例：**
```
Somatic CNV Summary:
  Total alterations: 47
  Amplifications: 12 (including MYC, EGFR)
  Deletions: 35 (including TP53, PTEN)
  
High-impact alterations:
  chr8:128000000-129000000 CN=8 (MYC amplification)
  chr17:7000000-8000000 CN=0 (TP53 deletion)
```

### 模式 2：罕见病 CNV 检测

**场景**：检测疑似基因组病患者的致病性 CNV。

```json
{
  "analysis_type": "rare_disease",
  "sample": "patient.bam",
  "reference": "hg38.fa",
  "parameters": {
    "bin_size": 500,
    "min_cnv_size": 1000,
    "max_frequency": 0.01
  },
  "annotation": [
    "OMIM genes",
    "ClinVar pathogenic variants",
    "Decipher syndromes"
  ]
}
```

**工作流：**
1. 使用高灵敏度设置进行 CNV 检出
2. 用常见群体 CNV（DGV、gnomAD）进行过滤
3. 优先关注罕见 CNV（频率 <1%）
4. 用疾病相关基因进行注释
5. 评估遗传模式（如有亲代数据）
6. 与表型/HPO 术语进行交叉参考
7. 生成含优先发现的临床报告

**输出示例：**
```
Rare CNV Findings:
  chr22:19000000-21000000 CN=1 (22q11.2 deletion syndrome)
    Size: 2.0 Mb
    Genes: TBX1, COMT, etc.
    Frequency: <0.1% in population
    Phenotype match: Cardiac, thymic, facial anomalies
    Classification: Pathogenic
```

### 模式 3：群体 CNV 分析

**场景**：比较多个样本间的 CNV 概览，以识别复发性变异。

```json
{
  "analysis_type": "population",
  "samples": [
    "sample1.bam", "sample2.bam", "sample3.bam",
    ...
  ],
  "cohorts": {
    "cases": 50,
    "controls": 50
  },
  "parameters": {
    "bin_size": 1000,
    "plot_format": "png"
  },
  "analysis": [
    "Recurrent CNV detection",
    "Burden analysis",
    "Association testing"
  ]
}
```

**工作流：**
1. 在所有样本上使用一致的参数进行 CNV 检出
2. 合并并统一各样本的 CNV 检出结果
3. 识别复发性 CNV 区域
4. 进行负荷分析（总 CNV 负荷）
5. 检验与表型/状态的关联
6. 进行多重检验校正
7. 可视化整个队列的 CNV 图谱

**输出示例：**
```
Population CNV Analysis:
  Samples analyzed: 100
  Total CNVs detected: 2,847
  
Recurrent alterations:
  chr1:1000000-2000000: 23% frequency
  chr16:15000000-16000000: 18% frequency
  
Case vs Control association:
  Significant enrichment: 3 CNV regions
  Most significant: chr8:128000000-129000000 (p=0.001)
```

### 模式 4：细胞系表征

**场景**：为研究或质量控制表征癌细胞系的 CNV 概览。

```json
{
  "analysis_type": "cell_line",
  "sample": "mcf7_cell_line.bam",
  "reference": "hg38.fa",
  "parameters": {
    "bin_size": 1000,
    "plot_format": "pdf"
  },
  "comparison": {
    "reference_profile": "mcf7_ccle_cnvs.bed",
    "expected_alterations": ["chr8_MYC_amp", "chr20_ZNF217_amp"]
  }
}
```

**工作流：**
1. 从 WGS 生成高质量 CNV 概览
2. 与参考概览（CCLE、COSMIC）进行比较
3. 验证预期的癌症驱动变异
4. 识别亚克隆群体
5. 评估基因组稳定性指标
6. 生成用于细胞系鉴定的质控报告
7. 记录以确保可重复性

**输出示例：**
```
Cell Line: MCF-7
Identity confirmed: Yes (99.2% match to reference)

Expected alterations detected:
  chr8:128000000-129000000: CN=8 (MYC) ✓
  chr20:50000000-52000000: CN=6 (ZNF217) ✓

Additional alterations:
  chr17:35000000-37000000: CN=3 (ERBB2) ✓
  
Ploidy: 2.8 (aneuploid)
Genome instability score: High
```

---

## 质量核查清单

**分析前检查：**
- [ ] **关键**：核实输入 BAM 文件已正确比对并建立索引
- [ ] 确认参考基因组版本与比对时一致（hg19 与 hg38）
- [ ] 检查测序覆盖度是否充足（WGS >15x，高分辨率分析 >30x）
- [ ] 评估覆盖均匀性（均匀性低会导致 CNV 假象）
- [ ] 复核 FASTQC 报告中的质量问题
- [ ] 确保癌症分析有配对正常样本可用
- [ ] 核实样本身份（检查性染色体是否与元数据一致）
- [ ] 确认无样本互换或污染

**分析过程中：**
- [ ] 根据预期 CNV 大小和覆盖度选择合适的区间大小
- [ ] 必要时进行 GC 含量归一化
- [ ] 分析多个样本时检查批次效应
- [ ] 监测重复区域中的高假阳性率
- [ ] 用已知性别验证性染色体检出结果
- [ ] 将线粒体 CNV 作为质控指标评估
- [ ] 复核覆盖图以发现技术假象
- [ ] 若有 SNP 芯片数据，检查一致性

**分析后验证：**
- [ ] **关键**：过滤已知问题区域（中心粒、端粒）中的 CNV
- [ ] 使用群体数据库（DGV、gnomAD）去除常见生殖细胞 CNV
- [ ] 在已知基因中验证癌症驱动变异
- [ ] 检查破坏单个外显子的 CNV 检出结果（通常为假象）
- [ ] 复核超大型 CNV（>50Mb）是否为技术假象
- [ ] 评估 CNV 负荷相对于群体常态的水平
- [ ] 核实 BED 文件格式是否合规
- [ ] 生成并复核全基因组图表

**用于临床或发表前：**
- [ ] **关键**：请经验丰富的分析师复核结果
- [ ] 用正交方法（FISH、qPCR、MLPA）验证致病性 CNV
- [ ] 与临床数据库（ClinVar、OMIM、Decipher）交叉参考
- [ ] 记录所应用的所有参数和过滤条件
- [ ] 用不同参数重新运行以评估可重复性
- [ ] 检查多样本分析中的批次效应
- [ ] 用最新基因组构建版本确认 CNV 坐标
- [ ] 归档原始数据和分析脚本以确保可重复性

---

## 常见陷阱

**输入数据问题：**
- ❌ **使用低覆盖度数据** → 产生大量假阳性的噪声 CNV 检出结果
  - ✅ 可靠的 WGS CNV 检出至少需要 15-20x 覆盖度
  
- ❌ **参考基因组不匹配** → CNV 坐标检出错误
  - ✅ 核实 BAM 使用的参考基因组与 CNV 检出工具一致（hg19 与 hg38）
  
- ❌ **肿瘤样本未使用配对正常样本** → 无法区分体细胞与生殖细胞变异
  - ✅ 尽可能使用配对正常样本；否则使用群体对照
  
- ❌ **覆盖均匀性差** → GC 偏倚导致假 CNV
  - ✅ 检查覆盖图；应用 GC 校正算法

**分析参数问题：**
- ❌ **区间大小过大** → 漏检小型 CNV（<10kb）
  - ✅ 高分辨率分析使用 100-500bp 区间；标准 WGS 使用 1000bp
  
- ❌ **区间大小过小** → 低覆盖区域噪声过大
  - ✅ 在分辨率与覆盖度之间权衡；若可用则使用自适应分箱
  
- ❌ **质量过滤不充分** → 假阳性 CNV 过多
  - ✅ 应用最低质量分数；按大小和读段支持数过滤
  
- ❌ **未过滤常见 CNV** → 将常见多态性报告为致病性变异
  - ✅ 与 DGV、gnomAD 等群体数据库进行过滤比对

**解读问题：**
- ❌ **忽略肿瘤纯度** → 误判亚克隆 CNV
  - ✅ 估计肿瘤纯度；相应调整 CNV 检出阈值
  
- ❌ **未验证关键发现** → 报告假阳性驱动变异
  - ✅ 用正交方法验证与癌症相关的 CNV
  
- ❌ **过度解读小型 CNV** → 单外显子缺失通常为假象
  - ✅ 除非有多种证据类型支持，否则聚焦于较大 CNV（>10kb）
  
- ❌ **忽略亲代数据** → 无法确定罕见病中的遗传模式
  - ✅ 纳入亲代样本以区分新生变异与遗传变异

**输出与报告问题：**
- ❌ **坐标系统不明确** → 0-based 与 1-based 混淆
  - ✅ 清楚记录所用坐标系统；BED 为 0-based，VCF 为 1-based
  
- ❌ **缺失质量指标** → 无法评估 CNV 检出结果的置信度
  - ✅ 包含质量分数、支持读段数和 log2 比值
  
- ❌ **未归档原始数据** → 结果无法重现
  - ✅ 保存 BAM 文件、参数设置和分析脚本
  
- ❌ **文档不充分** → 他人无法解读结果
  - ✅ 记录所用的所有过滤器、阈值和数据库

---

## 故障排查

**问题：未检测到 CNV**
- 症状：CNV 检出集为空或几乎为空
- 原因：
  - 覆盖度过低（<10x）
  - 区间大小对小型 CNV 过大
  - 质量阈值过于严格
  - 样本实际为二倍体，本身无 CNV
- 解决方案：
  - 从 BAM 文件核实覆盖深度
  - 减小区间大小以提高分辨率
  - 暂时放宽质量过滤
  - 检查全基因组覆盖均匀性

**问题：CNV 检出结果过多（数百或数千个）**
- 症状：CNV 检出数量过多，许多为小型或低质量
- 原因：
  - 覆盖度低或噪声高
  - 区间大小过小
  - 未应用质量过滤
  - 样本来自高度多态的群体
- 解决方案：
  - 应用最低质量分数过滤（Q>20）
  - 按最小大小过滤（>1kb）
  - 去除片段重复区域中的检出结果
  - 与群体 CNV 数据库进行过滤比对

**问题：重复区域中出现假阳性**
- 症状：CNV 集中于中心粒、端粒或 SD 区域
- 原因：
  - 重复区域可映射性低
  - 比对问题导致覆盖不均
  - 参考基因组存在缺口
- 解决方案：
  - 过滤与已知问题区域重叠的 CNV
  - 使用可映射性过滤器（要求可映射性 >0.8）
  - 从分析中排除中心粒和端粒
  - 仅使用高可映射性读段

**问题：肿瘤样本中 CNV 信号过弱**
- 症状：已知癌症变异未检出或信号微弱
- 原因：
  - 肿瘤纯度低（<20%）
  - 正常细胞污染
  - 亚克隆变异频率较低
- 解决方案：
  - 从 VAF 分布估计肿瘤纯度
  - 使用纯度校正的 CNV 检出方法
  - 降低检测阈值
  - 考虑用单细胞测序进行亚克隆分析

**问题：性染色体拷贝数异常**
- 症状：XX 样本 X 染色体显示 CN=1，或 XY 显示 CN=2
- 原因：
  - 性染色体非整倍体（如 Klinefelter、Turner 综合征）
  - 样本性别标注错误
  - 假常染色体区域误判
- 解决方案：
  - 从覆盖度比值（X/Y）核实样本性别
  - 检查临床记录中已知的性染色体异常
  - 从分析中排除假常染色体区域
  - 分别分析常染色体和性染色体

**问题：多样本分析中出现批次效应**
- 症状：CNV 模式与测序批次相关而非与生物学相关
- 原因：
  - 使用不同的测序平台或试剂
  - 批次间覆盖度差异
  - 比对参数不同
- 解决方案：
  - 在各批次间对覆盖度归一化
  - 所有样本使用相同的比对和处理流程
  - 在关联检验中将批次作为协变量纳入
  - 应用批次校正算法

**问题：无法安装或运行该工具**
- 症状：导入错误、依赖缺失、执行失败
- 原因：
  - 缺少 Python 包（pysam、numpy、matplotlib）
  - Python 版本不兼容
  - 缺少参考基因组索引文件
- 解决方案：
  - 安装所需包：`pip install pysam numpy matplotlib pandas`
  - 使用 Python 3.8 或更高版本
  - 创建参考基因组索引：`samtools faidx reference.fa`
  - 检查 BAM 文件索引是否存在：`sample.bam.bai`

---

## 参考资料

可在 `references/` 目录中获取：

- （该技能目前没有可用的参考文件）

**外部资源：**
- Database of Genomic Variants (DGV)：http://dgv.tcag.ca
- gnomAD Structural Variants：https://gnomad.broadinstitute.org
- ClinVar：https://www.ncbi.nlm.nih.gov/clinvar
- DECIPHER：https://www.deciphergenomics.org
- COSMIC：https://cancer.sanger.ac.uk

---

## 脚本

位于 `scripts/` 目录：

- `main.py` - 主 CNV 检出与绘图引擎

---

## CNV 检测方法比较

| Method | Input | Sensitivity | Resolution | Best For |
|--------|-------|-------------|------------|----------|
| **读段深度（本工具）** | BAM | 中 | 1-10 kb | 大型 CNV、WGS |
| **双端配对定位** | BAM | 中 | 100bp-10kb | 缺失、插入 |
| **拆分读段分析** | BAM | 高 | 1bp-1kb | 断点检测 |
| **SNP 芯片** | CEL/IDAT | 高 | 5-25kb | 经济高效的筛查 |
| **光学图谱** | Bionano | 高 | 500bp+ | 超大型结构变异 |

## 参数

| Parameter | Type | Default | Required | Description |
|-----------|------|---------|----------|-------------|
| `--input`, `-i` | string | - | Yes | 输入 BAM/VCF 文件 |
| `--reference`, `-r` | string | - | Yes | 参考基因组 FASTA |
| `--output`, `-o` | string | ./cnv_output | No | 输出目录 |
| `--bin-size` | int | 1000 | No | 分析用区间大小 |
| `--plot-format` | string | png | No | 图表格式（png、pdf、svg） |

## 用法

### 基本用法

```bash
# Call CNVs from BAM file
python scripts/main.py --input sample.bam --reference hg38.fa

# Custom output directory and bin size
python scripts/main.py --input sample.bam --reference hg38.fa --output ./results --bin-size 500

# Generate PDF plots
python scripts/main.py --input sample.bam --reference hg38.fa --plot-format pdf
```

## 风险评估

| Risk Indicator | Assessment | Level |
|----------------|------------|-------|
| 代码执行 | 本地执行 Python 脚本 | 低 |
| 网络访问 | 无外部 API 调用 | 低 |
| 文件系统访问 | 读取 BAM/VCF，写入结果 | 低 |
| 数据暴露 | 处理基因组数据 | 中 |
| PHI 风险 | 可能处理患者遗传数据 | 高 |

## 安全检查清单

- [x] 无硬编码凭证或 API 密钥
- [x] 无未授权的文件系统访问
- [x] 对文件路径进行输入验证
- [x] 输出目录受限
- [x] 错误消息已清理
- [x] **关键**：处理患者数据需符合 HIPAA 合规要求

## 前置条件

```bash
# Python 3.7+
# No additional packages required (uses standard library)
```

## 评估标准

### 成功指标
- [x] 成功处理 BAM/VCF 文件
- [x] 检测拷贝数变异
- [x] 生成可视化图表
- [x] 以 BED 格式输出结果

### 测试用例
1. **基本检出**：BAM 输入 → 带坐标的 CNV 检出结果
2. **图表生成**：CNV 检出结果 → 全基因组图表
3. **自定义区间大小**：不同区间大小 → 相应的分辨率

## 生命周期状态

- **当前阶段**：活跃
- **下次复核日期**：2026-03-09
- **已知问题**：CNV 检出逻辑为占位实现
- **规划中的改进**：
  - 实现实际的 CNV 检出算法
  - 增加肿瘤/正常样本对比功能
  - 增强可视化选项

---

**Last Updated**: 2026-02-09  
**Skill ID**: 162  
**Version**: 2.0 (K-Dense Standard)
