Skip to content

Commit abf6325

Browse files
committed
Use makegrm setup for gcta/filtergrmwithkeep
1 parent 8a1b82f commit abf6325

19 files changed

Lines changed: 728 additions & 270 deletions

File tree

modules/nf-core/gcta/filtergrmwithkeep/main.nf

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,34 @@ process GCTA_FILTERGRMWITHKEEP {
22
tag "${meta.id}"
33
label 'process_medium'
44
conda "${moduleDir}/environment.yml"
5-
container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
6-
'docker://community.wave.seqera.io/library/gcta:1.94.1--9bc35dc424fcf6e9' :
7-
'community.wave.seqera.io/library/gcta:1.94.1--9bc35dc424fcf6e9' }"
5+
container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container
6+
? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/46/46b0d05f0daa47561d87d2a9cac5e51edc2c78e26f1bbab439c688386241a274/data'
7+
: 'community.wave.seqera.io/library/gcta:1.94.1--9bc35dc424fcf6e9'}"
88

99
input:
10-
tuple val(meta), path(grm_id), path(grm_bin), path(grm_n_bin)
10+
tuple val(meta), path(grm_files)
1111
tuple val(meta2), path(keep_file)
1212

1313
output:
14-
tuple val(meta), path("*_unrel.grm.id"), path("*_unrel.grm.bin"), path("*_unrel.grm.N.bin"), emit: filtered_grm
15-
tuple val("${task.process}"), val("gcta"), eval("gcta --version 2>&1 | grep 'version v' | tr -s ' ' | cut -d' ' -f3 | sed 's/^v//'"), emit: versions_gcta, topic: versions
14+
tuple val(meta), path("*_unrel.grm.*"), emit: filtered_grm
15+
tuple val("${task.process}"), val("gcta"), eval("gcta --version | sed -En 's/^[*] version v([0-9.]*).*/\\1/p'"), emit: versions_gcta, topic: versions
1616

1717
when:
1818
task.ext.when == null || task.ext.when
1919

2020
script:
21-
def args = task.ext.args ?: ''
21+
def extra_args = task.ext.args ?: ''
2222
def prefix = task.ext.prefix ?: "${meta.id}"
2323

2424
"""
25+
2526
gcta \\
2627
--grm ${meta.id} \\
2728
--keep ${keep_file} \\
2829
--make-grm \\
2930
--out ${prefix}_unrel \\
3031
--thread-num ${task.cpus} \\
31-
${args}
32+
${extra_args}
3233
"""
3334

3435
stub:

modules/nf-core/gcta/filtergrmwithkeep/meta.yml

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@ name: "gcta_filtergrmwithkeep"
33
description: Filter a dense GRM to the individuals listed in a keep file
44
keywords:
55
- gcta
6+
- genome-wide complex trait analysis
67
- grm
8+
- genetic relationship matrix
79
- genetics
810
tools:
911
- "gcta":
1012
description: "Genome-wide Complex Trait Analysis (GCTA) estimates genetic relationships, variance components, and association statistics from genome-wide data."
1113
homepage: "https://yanglab.westlake.edu.cn/software/gcta/"
1214
documentation: "https://yanglab.westlake.edu.cn/software/gcta/static/gcta_doc_latest.pdf"
1315
tool_dev_url: "https://yanglab.westlake.edu.cn/software/gcta/"
16+
licence: ["GPL-3.0-only"]
17+
identifier: "biotools:gcta"
1418

1519
input:
1620
- - meta:
@@ -20,20 +24,10 @@ input:
2024
e.g. `[ id:'plink_simulated' ]`
2125
`meta.id` is required and is the dense GRM basename contract used by `gcta --grm`.
2226
Input files must therefore be staged as `<meta.id>.grm.id`, `<meta.id>.grm.bin`, and `<meta.id>.grm.N.bin`.
23-
- grm_id:
27+
- grm_files:
2428
type: file
25-
description: Dense GRM sample identifier file
26-
pattern: "*.grm.id"
27-
ontologies: []
28-
- grm_bin:
29-
type: file
30-
description: Dense GRM binary matrix file
31-
pattern: "*.grm.bin"
32-
ontologies: []
33-
- grm_n_bin:
34-
type: file
35-
description: Dense GRM sample-count matrix file
36-
pattern: "*.grm.N.bin"
29+
description: Dense GRM file bundle
30+
pattern: "*.grm.*"
3731
ontologies: []
3832
- - meta2:
3933
type: map
@@ -55,20 +49,10 @@ output:
5549
Groovy map containing dense GRM metadata
5650
e.g. `[ id:'plink_simulated' ]`
5751
`meta.id` is preserved from the input dense GRM basename contract.
58-
- "*_unrel.grm.id":
59-
type: file
60-
description: Filtered GRM sample identifier file
61-
pattern: "*_unrel.grm.id"
62-
ontologies: []
63-
- "*_unrel.grm.bin":
64-
type: file
65-
description: Filtered GRM binary matrix file
66-
pattern: "*_unrel.grm.bin"
67-
ontologies: []
68-
- "*_unrel.grm.N.bin":
52+
- "*_unrel.grm.*":
6953
type: file
70-
description: Filtered GRM sample-count matrix file
71-
pattern: "*_unrel.grm.N.bin"
54+
description: Filtered GRM file bundle
55+
pattern: "*_unrel.grm.*"
7256
ontologies: []
7357
versions_gcta:
7458
- - "${task.process}":
@@ -77,7 +61,7 @@ output:
7761
- "gcta":
7862
type: string
7963
description: The tool name
80-
- "gcta --version 2>&1 | grep 'version v' | tr -s ' ' | cut -d' ' -f3 | sed 's/^v//'":
64+
- "gcta --version | sed -En 's/^[*] version v([0-9.]*).*/\\1/p'":
8165
type: eval
8266
description: The command used to retrieve the GCTA version
8367

@@ -89,11 +73,11 @@ topics:
8973
- gcta:
9074
type: string
9175
description: The tool name
92-
- gcta --version 2>&1 | grep 'version v' | tr -s ' ' | cut -d' ' -f3 | sed 's/^v//':
76+
- "gcta --version | sed -En 's/^[*] version v([0-9.]*).*/\\1/p'":
9377
type: eval
9478
description: The command used to retrieve the GCTA version
9579

9680
authors:
97-
- "@andongni"
81+
- "@lyh970817"
9882
maintainers:
99-
- "@andongni"
83+
- "@lyh970817"

modules/nf-core/gcta/filtergrmwithkeep/tests/main.nf.test

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,29 @@ nextflow_process {
88
tag "modules_nfcore"
99
tag "gcta"
1010
tag "gcta/filtergrmwithkeep"
11-
tag "gcta/makegrmpart"
11+
tag "gcta/makegrm"
1212
tag "gcta/removerelatedsubjects"
1313

1414
setup {
15-
run("GCTA_MAKEGRMPART", alias: "GCTA_MAKEGRMPART_DENSE") {
16-
script "../../makegrmpart/main.nf"
15+
run("GCTA_MAKEGRM", alias: "GCTA_MAKEGRM_DENSE") {
16+
script "../../makegrm/main.nf"
1717
process {
1818
"""
19-
file('plink_simulated.mbfile').text = 'plink_simulated\\n'
19+
file('plink_simulated.mpfile').text = 'plink_simulated plink_simulated.pgen plink_simulated.psam plink_simulated.pvar\\n'
2020

2121
input[0] = [
22-
[ id:'plink_simulated_dense', part_gcta_job:1, nparts_gcta:1 ],
23-
file('plink_simulated.mbfile'),
22+
[ id:'plink_simulated_dense' ],
23+
file('plink_simulated.mpfile'),
2424
[
25-
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.bed', checkIfExists: true)
25+
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.pgen', checkIfExists: true)
2626
],
2727
[
28-
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.bim', checkIfExists: true)
28+
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.pvar', checkIfExists: true)
2929
],
3030
[
31-
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.fam', checkIfExists: true)
31+
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.psam', checkIfExists: true)
3232
]
3333
]
34-
input[1] = [[ id:'all_variants' ], []]
3534
"""
3635
}
3736
}
@@ -40,10 +39,8 @@ nextflow_process {
4039
script "../../removerelatedsubjects/main.nf"
4140
process {
4241
"""
43-
dense_grm = GCTA_MAKEGRMPART_DENSE.out.grm_files.map { meta, grm_id, grm_bin, grm_n_bin ->
44-
def prefix = meta.id + '.part_' + meta.nparts_gcta + '_' + meta.part_gcta_job
45-
[[ id:prefix ], grm_id, grm_bin, grm_n_bin]
46-
}
42+
dense_grm = GCTA_MAKEGRM_DENSE.out.grm_files
43+
.map { meta, grm_files -> [[ id:meta.id ], grm_files] }
4744

4845
input[0] = dense_grm
4946
"""
@@ -57,12 +54,7 @@ nextflow_process {
5754
when {
5855
process {
5956
"""
60-
dense_grm = GCTA_MAKEGRMPART_DENSE.out.grm_files.map { meta, grm_id, grm_bin, grm_n_bin ->
61-
def prefix = meta.id + '.part_' + meta.nparts_gcta + '_' + meta.part_gcta_job
62-
[[ id:prefix ], grm_id, grm_bin, grm_n_bin]
63-
}
64-
65-
input[0] = dense_grm
57+
input[0] = GCTA_MAKEGRM_DENSE.out.grm_files.map { meta, grm_files -> [[ id:meta.id ], grm_files] }
6658
input[1] = GCTA_REMOVERELATEDSUBJECTS_KEEP.out.keep_file
6759
"""
6860
}
@@ -72,17 +64,20 @@ nextflow_process {
7264
assertAll(
7365
{ assert process.success },
7466
{ assert process.out.filtered_grm.size() == 1 },
75-
{ assert process.out.filtered_grm.get(0).get(0).id == "plink_simulated_dense.part_1_1" },
67+
{ assert process.out.filtered_grm.get(0).get(0).id == "plink_simulated_dense" },
7668
{
7769
assert snapshot(
7870
process.out.filtered_grm
7971
).match("filtered_grm")
8072
},
8173
{
8274
def row = process.out.filtered_grm.get(0)
83-
assert file(row.get(1)).exists()
84-
assert file(row.get(2)).exists()
85-
assert file(row.get(3)).exists()
75+
assert row.get(1).every { file(it).exists() }
76+
assert row.get(1).collect { file(it).name }.sort() == [
77+
"plink_simulated_dense_unrel.grm.N.bin",
78+
"plink_simulated_dense_unrel.grm.bin",
79+
"plink_simulated_dense_unrel.grm.id"
80+
]
8681
},
8782
{ assert snapshot(process.out.findAll { key, val -> key.startsWith('versions') }).match("versions") }
8883
)
@@ -95,13 +90,8 @@ nextflow_process {
9590
when {
9691
process {
9792
"""
98-
dense_grm = GCTA_MAKEGRMPART_DENSE.out.grm_files.map { meta, grm_id, grm_bin, grm_n_bin ->
99-
def prefix = meta.id + '.part_' + meta.nparts_gcta + '_' + meta.part_gcta_job
100-
[[ id:prefix ], grm_id, grm_bin, grm_n_bin]
101-
}
102-
103-
input[0] = dense_grm.map { meta, grm_id, grm_bin, grm_n_bin ->
104-
[[ id:'contract_dense_mismatch' ], grm_id, grm_bin, grm_n_bin]
93+
input[0] = GCTA_MAKEGRM_DENSE.out.grm_files.map { meta, grm_files ->
94+
[[ id:'contract_dense_mismatch' ], grm_files]
10595
}
10696
input[1] = GCTA_REMOVERELATEDSUBJECTS_KEEP.out.keep_file
10797
"""
@@ -123,12 +113,7 @@ nextflow_process {
123113
when {
124114
process {
125115
"""
126-
dense_grm = GCTA_MAKEGRMPART_DENSE.out.grm_files.map { meta, grm_id, grm_bin, grm_n_bin ->
127-
def prefix = meta.id + '.part_' + meta.nparts_gcta + '_' + meta.part_gcta_job
128-
[[ id:prefix ], grm_id, grm_bin, grm_n_bin]
129-
}
130-
131-
input[0] = dense_grm
116+
input[0] = GCTA_MAKEGRM_DENSE.out.grm_files.map { meta, grm_files -> [[ id:meta.id ], grm_files] }
132117
input[1] = GCTA_REMOVERELATEDSUBJECTS_KEEP.out.keep_file
133118
"""
134119
}
@@ -138,17 +123,20 @@ nextflow_process {
138123
assertAll(
139124
{ assert process.success },
140125
{ assert process.out.filtered_grm.size() == 1 },
141-
{ assert process.out.filtered_grm.get(0).get(0).id == "plink_simulated_dense.part_1_1" },
126+
{ assert process.out.filtered_grm.get(0).get(0).id == "plink_simulated_dense" },
142127
{
143128
assert snapshot(
144129
process.out.filtered_grm
145130
).match("stub_filtered_grm")
146131
},
147132
{
148133
def row = process.out.filtered_grm.get(0)
149-
assert file(row.get(1)).exists()
150-
assert file(row.get(2)).exists()
151-
assert file(row.get(3)).exists()
134+
assert row.get(1).every { file(it).exists() }
135+
assert row.get(1).collect { file(it).name }.sort() == [
136+
"plink_simulated_dense_unrel.grm.N.bin",
137+
"plink_simulated_dense_unrel.grm.bin",
138+
"plink_simulated_dense_unrel.grm.id"
139+
]
152140
},
153141
{ assert snapshot(process.out.findAll { key, val -> key.startsWith('versions') }).match("stub_versions") }
154142
)

modules/nf-core/gcta/filtergrmwithkeep/tests/main.nf.test.snap

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,42 @@
2222
[
2323
[
2424
{
25-
"id": "plink_simulated_dense.part_1_1"
25+
"id": "plink_simulated_dense"
2626
},
27-
"plink_simulated_dense.part_1_1_unrel.grm.id:md5,d41d8cd98f00b204e9800998ecf8427e",
28-
"plink_simulated_dense.part_1_1_unrel.grm.bin:md5,d41d8cd98f00b204e9800998ecf8427e",
29-
"plink_simulated_dense.part_1_1_unrel.grm.N.bin:md5,d41d8cd98f00b204e9800998ecf8427e"
27+
[
28+
"plink_simulated_dense_unrel.grm.N.bin:md5,d41d8cd98f00b204e9800998ecf8427e",
29+
"plink_simulated_dense_unrel.grm.bin:md5,d41d8cd98f00b204e9800998ecf8427e",
30+
"plink_simulated_dense_unrel.grm.id:md5,d41d8cd98f00b204e9800998ecf8427e"
31+
]
3032
]
3133
]
3234
],
3335
"meta": {
3436
"nf-test": "0.9.3",
3537
"nextflow": "25.10.4"
3638
},
37-
"timestamp": "2026-03-21T20:39:51.93996848"
39+
"timestamp": "2026-05-15T23:16:45.31350454"
3840
},
3941
"filtered_grm": {
4042
"content": [
4143
[
4244
[
4345
{
44-
"id": "plink_simulated_dense.part_1_1"
46+
"id": "plink_simulated_dense"
4547
},
46-
"plink_simulated_dense.part_1_1_unrel.grm.id:md5,ca8c0bded6951fdd3bf0dddc97b6df6b",
47-
"plink_simulated_dense.part_1_1_unrel.grm.bin:md5,b1f124463eecbae86840a6651eec372d",
48-
"plink_simulated_dense.part_1_1_unrel.grm.N.bin:md5,06b73ea8bae8f1e5f5d4de33dbd2c75e"
48+
[
49+
"plink_simulated_dense_unrel.grm.N.bin:md5,06b73ea8bae8f1e5f5d4de33dbd2c75e",
50+
"plink_simulated_dense_unrel.grm.bin:md5,b1f124463eecbae86840a6651eec372d",
51+
"plink_simulated_dense_unrel.grm.id:md5,ca8c0bded6951fdd3bf0dddc97b6df6b"
52+
]
4953
]
5054
]
5155
],
5256
"meta": {
5357
"nf-test": "0.9.3",
5458
"nextflow": "25.10.4"
5559
},
56-
"timestamp": "2026-03-21T20:39:33.630308116"
60+
"timestamp": "2026-05-15T23:14:49.332143185"
5761
},
5862
"stub_versions": {
5963
"content": [
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json
3+
channels:
4+
- conda-forge
5+
- bioconda
6+
dependencies:
7+
- bioconda::gcta=1.94.1
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
process GCTA_MAKEGRM {
2+
tag "${meta.id}"
3+
label 'process_medium'
4+
conda "${moduleDir}/environment.yml"
5+
container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container
6+
? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/46/46b0d05f0daa47561d87d2a9cac5e51edc2c78e26f1bbab439c688386241a274/data'
7+
: 'community.wave.seqera.io/library/gcta:1.94.1--9bc35dc424fcf6e9'}"
8+
9+
input:
10+
tuple val(meta), path(mfile), path(bed_pgen), path(bim_pvar), path(fam_psam)
11+
12+
output:
13+
tuple val(meta), path("*.grm.*"), emit: grm_files
14+
tuple val("${task.process}"), val("gcta"), eval("gcta --version | sed -En 's/^[*] version v([0-9.]*).*/\\1/p'"), emit: versions_gcta, topic: versions
15+
16+
when:
17+
task.ext.when == null || task.ext.when
18+
19+
script:
20+
def extra_args = task.ext.args ?: ''
21+
def prefix = task.ext.prefix ?: "${meta.id}"
22+
def genotype_files = bed_pgen instanceof List ? bed_pgen : [bed_pgen]
23+
def genotype_extension = genotype_files[0].name.tokenize('.').last()
24+
def multi_file_flag = genotype_extension == 'pgen' ? '--mpfile' : '--mbfile'
25+
26+
"""
27+
28+
gcta \\
29+
${multi_file_flag} ${mfile} \\
30+
--make-grm \\
31+
--thread-num ${task.cpus} \\
32+
--out ${prefix} ${extra_args}
33+
"""
34+
35+
stub:
36+
def prefix = task.ext.prefix ?: "${meta.id}"
37+
"""
38+
touch ${prefix}.grm.id
39+
touch ${prefix}.grm.bin
40+
touch ${prefix}.grm.N.bin
41+
"""
42+
}

0 commit comments

Comments
 (0)