forked from admin/PlantAI-rag-new
feat(bioflow): wgs/pop/gwas 26 阶段参数契约(与 rnaseq 同款机制)
- stage_image_map 加 26 个 wgs/pop/gwas 阶段 cli_contract:
--workspace/--job-id/--prefix 公共三元组 + 上游 manifest 注入
(prev_manifest:<stage> 解析为 workspace/final/{prefix}.{stage}.manifest.json)
+ param:<name> 用户参数 + tool:<name> 镜像内工具
- kernel _contract_args 扩展 prev_manifest/tool 两种 source
- catalog 补 wgs/pop/gwas 参数 schema(确认表单收集参考基因组/样本清单/
表型文件/主成分等)
- 339 用例全绿;已部署 176
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -76,132 +76,784 @@
|
|||||||
"wgs_qc": {
|
"wgs_qc": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_qc",
|
"module": "cli.run_wgs_qc",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--wgs-samples",
|
||||||
|
"param:wgs_samples"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_index": {
|
"wgs_index": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_index",
|
"module": "cli.run_wgs_index",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--reference-fasta",
|
||||||
|
"param:reference_fasta"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_align": {
|
"wgs_align": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_align",
|
"module": "cli.run_wgs_align",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--qc-manifest",
|
||||||
|
"prev_manifest:wgs_qc"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--index-manifest",
|
||||||
|
"prev_manifest:wgs_index"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_markdup": {
|
"wgs_markdup": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_markdup",
|
"module": "cli.run_wgs_markdup",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--align-manifest",
|
||||||
|
"prev_manifest:wgs_align"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--gatk",
|
||||||
|
"tool:gatk"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--samtools",
|
||||||
|
"tool:samtools"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--max-jobs",
|
||||||
|
"param:max_jobs"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--remove-duplicates",
|
||||||
|
"param:remove_duplicates"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_bam_qc": {
|
"wgs_bam_qc": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_bam_qc",
|
"module": "cli.run_wgs_bam_qc",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--markdup-manifest",
|
||||||
|
"prev_manifest:wgs_markdup"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--index-manifest",
|
||||||
|
"prev_manifest:wgs_index"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--samtools",
|
||||||
|
"tool:samtools"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--threads",
|
||||||
|
"param:threads"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--max-jobs",
|
||||||
|
"param:max_jobs"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_haplotype_calling": {
|
"wgs_haplotype_calling": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_haplotype_calling",
|
"module": "cli.run_wgs_haplotype_calling",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--markdup-manifest",
|
||||||
|
"prev_manifest:wgs_markdup"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--bam-qc-manifest",
|
||||||
|
"prev_manifest:wgs_bam_qc"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--index-manifest",
|
||||||
|
"prev_manifest:wgs_index"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--gatk",
|
||||||
|
"tool:gatk"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--native-pair-hmm-threads",
|
||||||
|
"param:native_pair_hmm_threads"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--max-jobs",
|
||||||
|
"param:max_jobs"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_gvcf_combine": {
|
"wgs_gvcf_combine": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_gvcf_combine",
|
"module": "cli.run_wgs_gvcf_combine",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--haplotype-manifest",
|
||||||
|
"prev_manifest:wgs_haplotype_calling"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--index-manifest",
|
||||||
|
"prev_manifest:wgs_index"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_joint_genotyping": {
|
"wgs_joint_genotyping": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_joint_genotyping",
|
"module": "cli.run_wgs_joint_genotyping",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--combine-manifest",
|
||||||
|
"prev_manifest:wgs_gvcf_combine"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--index-manifest",
|
||||||
|
"prev_manifest:wgs_index"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_variant_select": {
|
"wgs_variant_select": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_variant_select",
|
"module": "cli.run_wgs_variant_select",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--joint-manifest",
|
||||||
|
"prev_manifest:wgs_joint_genotyping"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_variant_filter": {
|
"wgs_variant_filter": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_variant_filter",
|
"module": "cli.run_wgs_variant_filter",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--select-manifest",
|
||||||
|
"prev_manifest:wgs_variant_select"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_impute": {
|
"wgs_impute": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_impute",
|
"module": "cli.run_wgs_impute",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--filter-manifest",
|
||||||
|
"prev_manifest:wgs_variant_filter"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--beagle-jar",
|
||||||
|
"param:beagle_jar"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"wgs_maf_missing_filter": {
|
"wgs_maf_missing_filter": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_wgs_maf_missing_filter",
|
"module": "cli.run_wgs_maf_missing_filter",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--impute-manifest",
|
||||||
|
"prev_manifest:wgs_impute"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"pop_pca": {
|
"pop_pca": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_pop_pca",
|
"module": "cli.run_pop_pca",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"pop_phylogeny": {
|
"pop_phylogeny": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_pop_phylogeny",
|
"module": "cli.run_pop_phylogeny",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"pop_structure": {
|
"pop_structure": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_pop_structure",
|
"module": "cli.run_pop_structure",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"pop_ld_decay": {
|
"pop_ld_decay": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_pop_ld_decay",
|
"module": "cli.run_pop_ld_decay",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"pop_snp_density": {
|
"pop_snp_density": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_pop_snp_density",
|
"module": "cli.run_pop_snp_density",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"gwas_fmt": {
|
"gwas_fmt": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_gwas_tassel",
|
"module": "cli.run_gwas_tassel",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"gwas_kinship": {
|
"gwas_kinship": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_gwas_kinship",
|
"module": "cli.run_gwas_kinship",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"gwas_trait": {
|
"gwas_trait": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_gwas_trait",
|
"module": "cli.run_gwas_trait",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--phenotype",
|
||||||
|
"param:phenotype"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--sample-column",
|
||||||
|
"param:sample_column"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--trait-column",
|
||||||
|
"param:trait_column"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--trait-name",
|
||||||
|
"param:trait_name"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"gwas_cov": {
|
"gwas_cov": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_gwas_covariate",
|
"module": "cli.run_gwas_covariate",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--q",
|
||||||
|
"param:q"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--fam",
|
||||||
|
"param:fam"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--k",
|
||||||
|
"param:k"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"gwas_mlm": {
|
"gwas_mlm": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_gwas_tassel_mlm",
|
"module": "cli.run_gwas_tassel_mlm",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--kinship",
|
||||||
|
"param:kinship"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--trait",
|
||||||
|
"param:trait"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--covariate",
|
||||||
|
"param:covariate"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--genotype-scope-id",
|
||||||
|
"param:genotype_scope_id"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"gwas_plot": {
|
"gwas_plot": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_gwas_plot",
|
"module": "cli.run_gwas_plot",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--mlm-pvalues",
|
||||||
|
"param:mlm_pvalues"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--cmlm-pvalues",
|
||||||
|
"param:cmlm_pvalues"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--genotype-scope-id",
|
||||||
|
"param:genotype_scope_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--phenotype-scope-id",
|
||||||
|
"param:phenotype_scope_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--covariate-scope-id",
|
||||||
|
"param:covariate_scope_id"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"gwas_emmax": {
|
"gwas_emmax": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_gwas_emmax",
|
"module": "cli.run_gwas_emmax",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--trait",
|
||||||
|
"param:trait"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf-manifest",
|
||||||
|
"param:vcf_manifest"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--trait-manifest",
|
||||||
|
"param:trait_manifest"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--genotype-scope-id",
|
||||||
|
"param:genotype_scope_id"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"gwas_emplot": {
|
"gwas_emplot": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_gwas_emmax_plot",
|
"module": "cli.run_gwas_emmax_plot",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--emmax-pvalues",
|
||||||
|
"param:emmax_pvalues"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--emmax-manifest",
|
||||||
|
"param:emmax_manifest"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--genotype-scope-id",
|
||||||
|
"param:genotype_scope_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--phenotype-scope-id",
|
||||||
|
"param:phenotype_scope_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--source-model-scope-id",
|
||||||
|
"param:source_model_scope_id"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"gwas_glm": {
|
"gwas_glm": {
|
||||||
"image": "bioflow-wgs",
|
"image": "bioflow-wgs",
|
||||||
"module": "cli.run_gwas_tassel_glm",
|
"module": "cli.run_gwas_tassel_glm",
|
||||||
"executable": true
|
"executable": true,
|
||||||
|
"cli_contract": [
|
||||||
|
[
|
||||||
|
"--workspace",
|
||||||
|
"workspace"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--job-id",
|
||||||
|
"job_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--prefix",
|
||||||
|
"prefix"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf",
|
||||||
|
"param:vcf"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--trait",
|
||||||
|
"param:trait"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--covariate",
|
||||||
|
"param:covariate"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--vcf-manifest",
|
||||||
|
"param:vcf_manifest"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--trait-manifest",
|
||||||
|
"param:trait_manifest"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--covariate-manifest",
|
||||||
|
"param:covariate_manifest"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--genotype-scope-id",
|
||||||
|
"param:genotype_scope_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--phenotype-scope-id",
|
||||||
|
"param:phenotype_scope_id"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"--covariate-scope-id",
|
||||||
|
"param:covariate_scope_id"
|
||||||
|
]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"genome_prepare": {
|
"genome_prepare": {
|
||||||
"image": "bioflow-gf",
|
"image": "bioflow-gf",
|
||||||
|
|||||||
@@ -395,6 +395,46 @@ _RNASEQ_REPORT_PARAMS = [
|
|||||||
"help": "分析前缀"},
|
"help": "分析前缀"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# wgs/pop/gwas 参数 schema(契约 param: 键 → 确认表单字段)
|
||||||
|
_CPU4 = {"name": "cpu", "type": "choice", "choices": ["4", "8", "16", "32"],
|
||||||
|
"default": "4", "source": "runtime", "help": "容器 CPU 数"}
|
||||||
|
|
||||||
|
|
||||||
|
def _u(name: str, help_: str) -> dict[str, str]:
|
||||||
|
return {"name": name, "type": "string", "default": "", "source": "user", "help": help_}
|
||||||
|
|
||||||
|
|
||||||
|
_WGS_COMMON = [_u("prefix", "分析前缀"), _CPU4]
|
||||||
|
_WGS_QC_PARAMS = [*_WGS_COMMON, _u("wgs_samples", "WGS 样本清单(逗号分隔或路径)")]
|
||||||
|
_WGS_INDEX_PARAMS = [*_WGS_COMMON, _u("reference_fasta", "参考基因组 FASTA 路径(容器内可访问)")]
|
||||||
|
_WGS_ALIGN_PARAMS = [*_WGS_COMMON]
|
||||||
|
_WGS_MARKDUP_PARAMS = [*_WGS_COMMON,
|
||||||
|
{"name": "max_jobs", "type": "string", "default": "8", "source": "user",
|
||||||
|
"help": "并行任务上限"},
|
||||||
|
{"name": "remove_duplicates", "type": "choice", "choices": ["true"],
|
||||||
|
"default": "true", "source": "user", "help": "去重复(固定 true)"}]
|
||||||
|
_WGS_BAM_QC_PARAMS = [*_WGS_COMMON,
|
||||||
|
{"name": "threads", "type": "string", "default": "8", "source": "user",
|
||||||
|
"help": "线程数"},
|
||||||
|
{"name": "max_jobs", "type": "string", "default": "8", "source": "user",
|
||||||
|
"help": "并行任务上限"}]
|
||||||
|
_WGS_HAPLOTYPE_PARAMS = [*_WGS_COMMON,
|
||||||
|
{"name": "native_pair_hmm_threads", "type": "string", "default": "4",
|
||||||
|
"source": "user", "help": "GATK PairHMM 线程"},
|
||||||
|
{"name": "max_jobs", "type": "string", "default": "8", "source": "user",
|
||||||
|
"help": "并行任务上限"}]
|
||||||
|
_WGS_IMPUTE_PARAMS = [*_WGS_COMMON, _u("beagle_jar", "Beagle JAR 路径(容器内可访问)")]
|
||||||
|
_POP_COMMON = [*_WGS_COMMON, _u("vcf", "VCF 文件路径(容器内可访问)")]
|
||||||
|
_GWAS_TRAIT_PARAMS = [*_WGS_COMMON,
|
||||||
|
_u("phenotype", "表型数据文件路径"),
|
||||||
|
_u("sample_column", "样本列名"),
|
||||||
|
_u("trait_column", "性状列名"),
|
||||||
|
_u("trait_name", "性状名")]
|
||||||
|
_GWAS_COV_PARAMS = [*_WGS_COMMON,
|
||||||
|
_u("q", "Q 矩阵路径"),
|
||||||
|
_u("fam", "FAM 文件路径"),
|
||||||
|
_u("k", "主成分数 K")]
|
||||||
|
|
||||||
# 通用输入/输出描述(契约文档摘要;契约文件为权威,这里给目录层最小描述)
|
# 通用输入/输出描述(契约文档摘要;契约文件为权威,这里给目录层最小描述)
|
||||||
_IDENTIFY_INPUTS = [
|
_IDENTIFY_INPUTS = [
|
||||||
{"name": "protein_fasta", "type": "fasta", "required": True,
|
{"name": "protein_fasta", "type": "fasta", "required": True,
|
||||||
@@ -468,6 +508,32 @@ _STAGE_PARAM_SCHEMAS: dict[str, tuple[list[dict[str, Any]], list[dict[str, Any]]
|
|||||||
{"name": "prefix", "type": "string", "default": "", "source": "contract", "help": "分析前缀"},
|
{"name": "prefix", "type": "string", "default": "", "source": "contract", "help": "分析前缀"},
|
||||||
], _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
], _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
"rnaseq_qc": (_RNASEQ_QC_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
"rnaseq_qc": (_RNASEQ_QC_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_qc": (_WGS_QC_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_index": (_WGS_INDEX_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_align": (_WGS_ALIGN_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_markdup": (_WGS_MARKDUP_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_bam_qc": (_WGS_BAM_QC_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_haplotype_calling": (_WGS_HAPLOTYPE_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_gvcf_combine": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_joint_genotyping": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_variant_select": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_variant_filter": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_impute": (_WGS_IMPUTE_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"wgs_maf_missing_filter": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"pop_pca": (_POP_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"pop_phylogeny": (_POP_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"pop_structure": (_POP_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"pop_ld_decay": (_POP_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"pop_snp_density": (_POP_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"gwas_fmt": (_POP_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"gwas_kinship": (_POP_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"gwas_trait": (_GWAS_TRAIT_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"gwas_cov": (_GWAS_COV_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"gwas_mlm": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"gwas_plot": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"gwas_emmax": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"gwas_emplot": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
"gwas_glm": (_WGS_COMMON, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
"rnaseq_align": (_RNASEQ_ALIGN_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
"rnaseq_align": (_RNASEQ_ALIGN_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
"rnaseq_quant": (_RNASEQ_QUANT_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
"rnaseq_quant": (_RNASEQ_QUANT_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
"rnaseq_sample_qc": (_RNASEQ_SAMPLE_QC_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
"rnaseq_sample_qc": (_RNASEQ_SAMPLE_QC_PARAMS, _DOWNSTREAM_INPUTS, _DOWNSTREAM_OUTPUTS),
|
||||||
|
|||||||
@@ -200,8 +200,11 @@ class Kernel:
|
|||||||
故 -o 必须指向 workspace/final,manifest 也落此处与 runner 检索对齐)
|
故 -o 必须指向 workspace/final,manifest 也落此处与 runner 检索对齐)
|
||||||
- samples_yaml:/job/input/samples.yaml(宿主侧不存在则跳过该 flag,
|
- samples_yaml:/job/input/samples.yaml(宿主侧不存在则跳过该 flag,
|
||||||
交由 CLI 报缺失,错误信息比服务端更可读)
|
交由 CLI 报缺失,错误信息比服务端更可读)
|
||||||
|
- prev_manifest:<stage>:上游阶段 manifest 路径
|
||||||
|
/job/workspace/final/{prefix}.{stage}.manifest.json(缺失跳过)
|
||||||
- prefix/job_id:从 params 取值,缺失跳过
|
- prefix/job_id:从 params 取值,缺失跳过
|
||||||
- param:<name>:从 params[name] 取值,缺失跳过(用户经确认表单提供)
|
- param:<name>:从 params[name] 取值,缺失跳过(用户经确认表单提供)
|
||||||
|
- tool:<name>:容器内工具命令(镜像 PATH 内裸命令,如 gatk/samtools)
|
||||||
"""
|
"""
|
||||||
args: list[str] = []
|
args: list[str] = []
|
||||||
for flag, source in contract:
|
for flag, source in contract:
|
||||||
@@ -211,6 +214,15 @@ class Kernel:
|
|||||||
args += [flag, self.cfg.container_workspace_dir]
|
args += [flag, self.cfg.container_workspace_dir]
|
||||||
elif source == "output_final":
|
elif source == "output_final":
|
||||||
args += [flag, f"{self.cfg.container_workspace_dir}/final"]
|
args += [flag, f"{self.cfg.container_workspace_dir}/final"]
|
||||||
|
elif str(source).startswith("prev_manifest:"):
|
||||||
|
stage_name = str(source).split(":", 1)[1]
|
||||||
|
value = str(params.get("prefix") or "").strip()
|
||||||
|
if value:
|
||||||
|
args += [flag,
|
||||||
|
f"{self.cfg.container_workspace_dir}/final/{value}.{stage_name}.manifest.json"]
|
||||||
|
elif str(source).startswith("tool:"):
|
||||||
|
name = str(source).split(":", 1)[1]
|
||||||
|
args += [flag, name]
|
||||||
elif source == "samples_yaml":
|
elif source == "samples_yaml":
|
||||||
if (Path(job_input_dir) / "samples.yaml").is_file():
|
if (Path(job_input_dir) / "samples.yaml").is_file():
|
||||||
args += [flag, f"{self.cfg.container_input_dir}/samples.yaml"]
|
args += [flag, f"{self.cfg.container_input_dir}/samples.yaml"]
|
||||||
|
|||||||
@@ -127,6 +127,50 @@ def test_build_command_cli_contract(tmp_path):
|
|||||||
assert "--input-dir" in cmd4 and "--workspace" in cmd4
|
assert "--input-dir" in cmd4 and "--workspace" in cmd4
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_command_wgs_contract(tmp_path):
|
||||||
|
"""wgs 系契约:--workspace/--job-id/--prefix + prev_manifest 路径注入。"""
|
||||||
|
from app.services.bioflow.kernel import Kernel, KernelConfig, ImageMap
|
||||||
|
cfg = KernelConfig(host_uid=1234, data_root=str(tmp_path / "data"))
|
||||||
|
img = ImageMap(
|
||||||
|
images={"wgs": {"docker_tag": "bioflow-wgs"}},
|
||||||
|
stages={
|
||||||
|
"wgs_qc": {"image": "wgs", "module": "cli.run_wgs_qc",
|
||||||
|
"cli_contract": [["--workspace", "workspace"],
|
||||||
|
["--job-id", "job_id"],
|
||||||
|
["--prefix", "prefix"],
|
||||||
|
["--wgs-samples", "param:wgs_samples"]]},
|
||||||
|
"wgs_align": {"image": "wgs", "module": "cli.run_wgs_align",
|
||||||
|
"cli_contract": [["--workspace", "workspace"],
|
||||||
|
["--job-id", "job_id"],
|
||||||
|
["--prefix", "prefix"],
|
||||||
|
["--qc-manifest", "prev_manifest:wgs_qc"],
|
||||||
|
["--index-manifest", "prev_manifest:wgs_index"],
|
||||||
|
["--gatk", "tool:gatk"]]},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
k = Kernel(img, cfg)
|
||||||
|
# wgs_qc:公共三元组 + param 注入
|
||||||
|
cmd = k.build_command("wgs_qc", tmp_path / "in", tmp_path / "ws",
|
||||||
|
params={"job_id": "j1", "prefix": "rice",
|
||||||
|
"wgs_samples": "s1,s2"})
|
||||||
|
assert "--workspace" in cmd and "/job/workspace" in cmd
|
||||||
|
assert "--job-id" in cmd and "j1" in cmd
|
||||||
|
assert "--prefix" in cmd and "rice" in cmd
|
||||||
|
assert "--wgs-samples" in cmd and "s1,s2" in cmd
|
||||||
|
assert "--input-dir" not in cmd
|
||||||
|
# wgs_align:prev_manifest 注入(prefix 有值时)
|
||||||
|
cmd2 = k.build_command("wgs_align", tmp_path / "in", tmp_path / "ws",
|
||||||
|
params={"job_id": "j1", "prefix": "rice"})
|
||||||
|
assert "--qc-manifest" in cmd2
|
||||||
|
assert "/job/workspace/final/rice.wgs_qc.manifest.json" in cmd2
|
||||||
|
assert "/job/workspace/final/rice.wgs_index.manifest.json" in cmd2
|
||||||
|
assert "--gatk" in cmd2 and "gatk" in cmd2 # tool:<name> 注入裸命令
|
||||||
|
# prefix 缺失时 prev_manifest 跳过
|
||||||
|
cmd3 = k.build_command("wgs_align", tmp_path / "in", tmp_path / "ws",
|
||||||
|
params={"job_id": "j1"})
|
||||||
|
assert "--qc-manifest" not in cmd3
|
||||||
|
|
||||||
|
|
||||||
def test_build_command_params(kernel, tmp_path):
|
def test_build_command_params(kernel, tmp_path):
|
||||||
cmd = kernel.build_command("identify", tmp_path / "in", tmp_path / "ws",
|
cmd = kernel.build_command("identify", tmp_path / "in", tmp_path / "ws",
|
||||||
{"prefix": "Ft.SPL", "required_pfams": "PF03110",
|
{"prefix": "Ft.SPL", "required_pfams": "PF03110",
|
||||||
|
|||||||
Reference in New Issue
Block a user