# 多物种基因家族分析工作流设计 ## 核心概念 ### 物种角色定义 | 角色 | 说明 | 示例 | |:---|:---|:---| | **目标物种** (Target) | 要分析基因家族的物种 | 苦荞 (Ft) | | **参考物种** (Reference) | 用于辅助鉴定的已知物种 | 拟南芥 (Ath)、水稻 (Os)、番茄 (Sl) | ### 文件命名规范 ``` # 目标物种文件(必需) {prefix}.pep.fasta # 目标物种蛋白序列 {prefix}.gff3 # 目标物种注释文件 {prefix}.genome.fasta # 目标物种基因组(可选) # 参考物种文件(可选,可多个) {ref_species}_ref.pep.fasta # 参考物种蛋白(如 Ath_ref.pep.fasta) {ref_species}_ref.gff3 # 参考物种注释(如 Ath_ref.gff3) # 原始数据库文件(自动识别) Athaliana_167_TAIR10.protein_primaryTranscriptOnly.fa.gz # 拟南芥JGI格式 Osativa_323_v7.protein_primaryTranscriptOnly.fa.gz # 水稻JGI格式 ``` ## 工作流程 ### 阶段1: 数据准备 (genome_prepare) **输入**: 原始数据库文件(JGI/Ensembl/NCBI格式) **处理**: 1. 识别目标物种文件(匹配prefix) 2. 识别参考物种文件(其他文件) 3. 分别处理每个物种 4. 生成标准化输出 **输出**: ``` input/{job_id}/ ├── {prefix}.pep.fasta # 目标物种蛋白 ├── {prefix}.gff3 # 目标物种GFF ├── {prefix}.genome.fasta # 目标物种基因组 ├── Ath_ref.pep.fasta # 参考物种1蛋白 ├── Ath_ref.gff3 # 参考物种1 GFF ├── Os_ref.pep.fasta # 参考物种2蛋白 └── ... ``` ### 阶段2: 基因家族鉴定 (identify) **输入**: - 目标物种蛋白: `{prefix}.pep.fasta` - 参考物种蛋白: `*_ref.pep.fasta`(多个) - HMM文件或Pfam ID **处理**: 1. HMM搜索目标物种蛋白组 2. 用参考物种蛋白构建BLAST数据库 3. 双向BLAST验证 4. 整合结果 **输出**: ``` final/{prefix}.final_members.pep.fa # 目标物种基因家族成员 final/{prefix}.identify.manifest.json # 鉴定结果清单 ``` ### 阶段3: 进化分析 (phylogeny) **输入**: - 目标物种基因家族成员 - 参考物种同源基因 **处理**: 1. 多序列比对(目标+参考物种) 2. 构建系统发育树 3. 亚家族分类 **输出**: ``` final/{prefix}.tree.nwk # 系统发育树 final/{prefix}.geneID.subfamily # 亚家族分类 ``` ## 关键改进点 ### 1. 自动区分目标物种和参考物种 ```python class SpeciesClassifier: """自动分类目标物种和参考物种""" def classify(self, files: List[Path], prefix: str) -> Tuple[SpeciesFiles, List[SpeciesFiles]]: """ 返回: (目标物种, 参考物种列表) """ target = None references = [] for file in files: # 检查是否是目标物种 if self.is_target_species(file, prefix): target = self.parse_target_file(file) else: # 参考物种 ref = self.parse_reference_file(file) references.append(ref) return target, references def is_target_species(self, file: Path, prefix: str) -> bool: """判断文件是否属于目标物种""" # 策略1: 文件名匹配prefix if file.name.startswith(prefix.split('.')[0]): return True # 策略2: 用户明确标记 if '.target.' in file.name or '_target.' in file.name: return True # 策略3: 只有一个主要物种文件 return False ``` ### 2. 多参考物种支持 ```python class MultiReferenceBlast: """多参考物种BLAST验证""" def build_combined_db(self, reference_files: List[Path]) -> Path: """合并多个参考物种构建BLAST数据库""" combined_fasta = self.work_dir / "combined_ref.pep.fa" with open(combined_fasta, 'w') as out: for ref_file in reference_files: species_code = self.extract_species_code(ref_file) with open(ref_file) as f: for line in f: if line.startswith('>'): # 添加物种标识到序列ID out.write(f">{species_code}|{line[1:]}") else: out.write(line) return combined_fasta def validate_hits(self, query_hits: List[BlastHit]) -> Dict[str, Any]: """验证hit来自哪个参考物种""" results = {} for hit in query_hits: species = hit.target_id.split('|')[0] if species not in results: results[species] = [] results[species].append(hit) return results ``` ### 3. 智能物种识别 ```python class SpeciesRecognizer: """智能识别文件属于哪个物种""" SPECIES_SIGNATURES = { 'Ath': { 'patterns': ['Athaliana', 'TAIR', 'AT1G', 'AT2G'], 'name': 'Arabidopsis thaliana' }, 'Os': { 'patterns': ['Osativa', 'Os01g', 'Os02g'], 'name': 'Oryza sativa' }, 'Ft': { 'patterns': ['Fagopyrum', 'FtPinG', 'tataricum'], 'name': 'Fagopyrum tataricum' }, 'Sl': { 'patterns': ['Solanum', 'Soly', 'Solyc'], 'name': 'Solanum lycopersicum' }, 'Zm': { 'patterns': ['Zea', 'Zm00001'], 'name': 'Zea mays' } } def recognize_from_content(self, fasta_file: Path) -> str: """从FASTA文件内容识别物种""" with open(fasta_file) as f: # 读取前100个序列ID ids = [] for line in f: if line.startswith('>'): ids.append(line[1:].split()[0]) if len(ids) >= 100: break # 匹配物种特征 for species_code, info in self.SPECIES_SIGNATURES.items(): match_count = sum(1 for id in ids if any(p in id for p in info['patterns'])) if match_count > len(ids) * 0.5: # 超过50%匹配 return species_code return "UNKNOWN" ``` ## 实现建议 ### 方案A: 文件名约定(简单) 用户按约定命名文件: ``` # 目标物种 Ft.pep.fasta # 必需 Ft.gff3 # 可选 # 参考物种 Ath_ref.pep.fasta # 拟南芥参考 Os_ref.pep.fasta # 水稻参考 Sl_ref.pep.fasta # 番茄参考 ``` ### 方案B: 配置文件(灵活) ```yaml # species_config.yaml target: code: "Ft" name: "Fagopyrum tataricum" files: pep: "Ft.pep.fasta" gff: "Ft.gff3" references: - code: "Ath" name: "Arabidopsis thaliana" files: pep: "Athaliana_167_TAIR10.protein_primaryTranscriptOnly.fa.gz" gff: "Athaliana_167_TAIR10.gene_exons.gff3.gz" - code: "Os" name: "Oryza sativa" files: pep: "Osativa_323_v7.protein_primaryTranscriptOnly.fa.gz" - code: "Sl" name: "Solanum lycopersicum" files: pep: "Slycopersicum_...fa.gz" ``` ### 方案C: 自动识别(智能) 系统自动识别: 1. 扫描所有文件 2. 从内容识别物种 3. 用户确认或修正 ## 推荐实现 **短期**(本周):方案A - 文件名约定 - 简单,用户容易理解 - 改动最小 **中期**(本月):方案B - 配置文件 - 更灵活,支持复杂场景 - 可扩展性好 **长期**(未来):方案C - 自动识别+LLM - 完全自动化 - 智能推荐参考物种 ## 立即实施的修改 ### 1. 修改 `genome_prepare` ```python def main(): parser.add_argument("--target-prefix", required=True, help="目标物种前缀") parser.add_argument("--reference-species", nargs='+', help="参考物种代码列表") # 处理逻辑 target_files = find_target_files(input_dir, args.target_prefix) reference_files = find_reference_files(input_dir, exclude=target_files) # 分别处理 process_target(target_files) for ref in reference_files: process_reference(ref) ``` ### 2. 修改 `identify` ```python def run_identify(): # 加载目标物种 target_pep = load_target_protein(prefix) # 加载参考物种 reference_peps = load_reference_proteins(workspace) # HMM搜索目标物种 hmm_results = run_hmmsearch(target_pep) # BLAST验证(使用所有参考物种) combined_db = build_combined_blast_db(reference_peps) blast_results = run_blastp(target_pep, combined_db) # 整合结果 final_members = integrate_results(hmm_results, blast_results) ``` 这样设计是否满足你的需求?需要我立即实施哪个方案?