pie-phasing-benchmark 0.11.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. pie_phasing_benchmark-0.11.1/LICENSE +21 -0
  2. pie_phasing_benchmark-0.11.1/PKG-INFO +185 -0
  3. pie_phasing_benchmark-0.11.1/README.md +164 -0
  4. pie_phasing_benchmark-0.11.1/pie/pie/__init__.py +0 -0
  5. pie_phasing_benchmark-0.11.1/pie/pie/module/F1_related.py +39 -0
  6. pie_phasing_benchmark-0.11.1/pie/pie/module/__init__.py +0 -0
  7. pie_phasing_benchmark-0.11.1/pie/pie/module/cal_NGx0.py +14 -0
  8. pie_phasing_benchmark-0.11.1/pie/pie/module/cal_ref.py +62 -0
  9. pie_phasing_benchmark-0.11.1/pie/pie/module/check_filters.py +22 -0
  10. pie_phasing_benchmark-0.11.1/pie/pie/module/cli.py +114 -0
  11. pie_phasing_benchmark-0.11.1/pie/pie/module/evaluation.py +339 -0
  12. pie_phasing_benchmark-0.11.1/pie/pie/module/intersect.py +167 -0
  13. pie_phasing_benchmark-0.11.1/pie/pie/module/lib/__init__.py +0 -0
  14. pie_phasing_benchmark-0.11.1/pie/pie/module/lib/hamming.c +40 -0
  15. pie_phasing_benchmark-0.11.1/pie/pie/module/pie_class.py +83 -0
  16. pie_phasing_benchmark-0.11.1/pie/pie/module/raw_metrics.py +51 -0
  17. pie_phasing_benchmark-0.11.1/pie/pie/module/read_bed.py +37 -0
  18. pie_phasing_benchmark-0.11.1/pie/pie/module/read_vcf.py +76 -0
  19. pie_phasing_benchmark-0.11.1/pie/pie/module/safediv.py +7 -0
  20. pie_phasing_benchmark-0.11.1/pie/pie/module/sort_chrom.py +18 -0
  21. pie_phasing_benchmark-0.11.1/pie/pie/module/write_block.py +19 -0
  22. pie_phasing_benchmark-0.11.1/pie/pie/module/write_evaluation.py +128 -0
  23. pie_phasing_benchmark-0.11.1/pie/pie/module/write_genotype.py +122 -0
  24. pie_phasing_benchmark-0.11.1/pie/pie/module/write_lmdb.py +20 -0
  25. pie_phasing_benchmark-0.11.1/pie/pie/pie.py +143 -0
  26. pie_phasing_benchmark-0.11.1/pie/pie_phasing_benchmark.egg-info/PKG-INFO +185 -0
  27. pie_phasing_benchmark-0.11.1/pie/pie_phasing_benchmark.egg-info/SOURCES.txt +35 -0
  28. pie_phasing_benchmark-0.11.1/pie/pie_phasing_benchmark.egg-info/dependency_links.txt +1 -0
  29. pie_phasing_benchmark-0.11.1/pie/pie_phasing_benchmark.egg-info/entry_points.txt +2 -0
  30. pie_phasing_benchmark-0.11.1/pie/pie_phasing_benchmark.egg-info/requires.txt +14 -0
  31. pie_phasing_benchmark-0.11.1/pie/pie_phasing_benchmark.egg-info/top_level.txt +1 -0
  32. pie_phasing_benchmark-0.11.1/pyproject.toml +3 -0
  33. pie_phasing_benchmark-0.11.1/setup.cfg +4 -0
  34. pie_phasing_benchmark-0.11.1/setup.py +53 -0
  35. pie_phasing_benchmark-0.11.1/tests/test_bed.py +20 -0
  36. pie_phasing_benchmark-0.11.1/tests/test_format.py +51 -0
  37. pie_phasing_benchmark-0.11.1/tests/test_include_genotype.py +20 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Jun Mencius
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,185 @@
1
+ Metadata-Version: 2.1
2
+ Name: pie-phasing-benchmark
3
+ Version: 0.11.1
4
+ Summary: Phasing all-in-one evaluator
5
+ Home-page: https://github.com/JMencius/pie
6
+ Author: Jun Mencius
7
+ Author-email: zjmeng22@m.fudan.edu.cn
8
+ Keywords: pie,haplotype,phasing,benchmark
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: click>=8.1.8
13
+ Requires-Dist: cyvcf2>=0.31.3
14
+ Requires-Dist: sortedcontainers>=2.4.0
15
+ Requires-Dist: pyfastx>=2.2.0
16
+ Requires-Dist: lmdb==1.8.1; python_version < "3.9"
17
+ Requires-Dist: lmdb>=2.0.0; python_version >= "3.9"
18
+ Requires-Dist: numba>=0.58.1
19
+ Provides-Extra: test
20
+ Requires-Dist: pytest; extra == "test"
21
+
22
+ <img src="pie_logo.png" width = "100">
23
+
24
+ # pie
25
+ Phasing all-In-one Evaluator, for haplotype phasing evaluation
26
+
27
+ ## Installation
28
+ Currently, `Pie` does not support online installation, but will be available through `pip` or `conda` upon publication.
29
+
30
+ Installation will finish in a few minutes.
31
+
32
+ ### Use `pip` to conduct local installation
33
+ 1. Create new virtual environment
34
+ ```
35
+ conda create -n pie python=3.8;
36
+ conda activate pie;
37
+ ```
38
+
39
+ 2. Navigate to the base directory, which contains `setup.py`. Use `pip` to install `pie`.
40
+ ```
41
+ pip install .;
42
+ ```
43
+
44
+ ## Usages
45
+ ### Required arguments
46
+ | Parameters | Description | Format or example |
47
+ |:---:|:---:|:---:|
48
+ | `-i or --input` | file for evaluation | .vcf / .vcf.gz |
49
+ | `-c or --compare` | ground truth file | .vcf / .vcf.gz |
50
+ | `-r or --ref` | reference file | .fa / .fasta / .fai |
51
+ | `-o or --output` | Output file prefix | exmaple: ./test/output_name |
52
+
53
+ ### Recommend flag
54
+ Use `--verbose` to monitor the running process and enable detailed logging.
55
+
56
+ ### Full usages
57
+ ```
58
+ Usage: pie [OPTIONS]
59
+
60
+ Options:
61
+ -i, --input TEXT Input vcf/vcf.gz file for evaluation [required]
62
+ -n, --name TEXT User defined sample name, [default: Sample]
63
+ -c, --compare TEXT Ground truth vcf/vcf.gz file for comparison
64
+ [required]
65
+ -r, --ref TEXT Reference file fasta file (.fasta or .fa) or fasta
66
+ index file (.fai) [required]
67
+ -o, --output TEXT Output file prefix, such as -o ./test/output_name
68
+ [required]
69
+ -t, --threads INTEGER Maximum numbers of parallel threads [default: 24]
70
+ -m, --max-len INTEGER Maximum variant distance for pairwise calculation
71
+ [default: 250000]
72
+ -b, --bed TEXT .bed file specifying genomic regions to include
73
+ [default: None]
74
+ --min-sv INTEGER Minimal length threshold of Structral Variant
75
+ [default: 30, ALT length > 30 bp is SV]
76
+ --chrom TEXT Chromosome to evaluate,use comma to join chromosome
77
+ name e.g. --chrom chr1,chr2,chr3
78
+ [default:chr1,chr2,chr3,...,chr22]
79
+ --sexchrom TEXT Sex chromosme,use comma to join chromosome name e.g.
80
+ --sexchrom chrX,chrY [default: chrX,chrY]
81
+ --mincount INTEGER Minimum numbers of phased sites in a phase block
82
+ [default: 2]
83
+ --block Output phasing block start and end positions in a BED
84
+ file
85
+ --no-sex Ignore sex chromosome
86
+ --canonical Canonical mode, only evaluate single mutation SNV
87
+ ignore double heterozygous site
88
+ --only-snv Only evaluate single nucleotide variation
89
+ --only-indel Only evaluate insertion and deletion
90
+ --only-sv Only evaluate structural variant
91
+ --no-snv Ignore single nucleotide variation
92
+ --no-indel Ignore insertion and deletion
93
+ --no-sv Ignore structural variant
94
+ --no-double Ignore double heterozygous site
95
+ --no-sort Do not sort chromosome or regions, directly use the
96
+ input order
97
+ --verbose Enable verbose mode, printing parameters and progress
98
+ to standard output
99
+ --version Show the version and exit.
100
+ --help Show this message and exit.
101
+ ```
102
+
103
+ ## Exmaples
104
+ Suppose `phase.vcf` is the sample VCF file to be evaluated against the ground truth VCF file (`truth.vcf`).
105
+ 1. (Comprehensive) Evaluate all autosome
106
+ ```
107
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa -o ./output/comprehensive
108
+ ```
109
+
110
+ 2. (Chromosome specific) Restrict evaluation to selected chromosome
111
+ ```
112
+ pie --verbose --chrom chr6 -i phase.vcf -c truth.vcf -r ref.fa -o ./output/chr6
113
+ ```
114
+
115
+ 3. (Region specific) Focus only on regions defined in a BED file.
116
+ ```
117
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa --bed mhc.bed -o ./output/mhc
118
+ ```
119
+
120
+ 4. (Filter) Exclude structural variants (SV) from the analysis
121
+ ```
122
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa --no-sv -o ./output/no_sv
123
+ ```
124
+
125
+ 5. (More output) Output raw phasing block start and end positions to a BED file
126
+ ```
127
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa --block -o ./output/more
128
+ ```
129
+
130
+ 6. (Miscellaneous) Evaluate only SNVs on chromosome 6 and output raw block start and end positions to a BED file.
131
+ ```
132
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa --chrom chr6 --only-snv --block -o ./output/misc
133
+ ```
134
+
135
+ ## Test data
136
+ Small query and truth test files are provided in [here](./tests) including three formats:
137
+ | Filename | Format | Description |
138
+ |:---:|:---:|:---:|
139
+ | small_query.vcf | VCF | Uncompressed VCF |
140
+ | small_query.vcf.gz | VCF.GZ | Compressed VCF |
141
+ | small_query.bcf | BCF | Binary VCF |
142
+
143
+ `small_truth.vcf` is provided as the truth.
144
+
145
+ The `VCF` format follows regulations in <https://samtools.github.io/hts-specs/VCFv4.1.pdf>
146
+
147
+
148
+ ## Output file
149
+ | Output suffix | Description | Condition |
150
+ |:---:|:---:|:--:|
151
+ | `.variant.stats.csv` | Genotype evaluation result and phased percentage | Always generated |
152
+ | `.perchrom.csv` | Per chromosome phasing evaluation result | Always generated |
153
+ | `.overall.csv` | Overall sample evaluation result | Always generated |
154
+ | `.blocks.bed` | Raw phasing block start end in `-i` or `--input` file | with `--block` set |
155
+
156
+
157
+ ## Resouce consumption
158
+ `Pie` is expected to completed evaluation within minutes with the default 24 threads on a stardard X86 platfrom.
159
+
160
+ The actual performance may vary depending on factors such as size of `vcf`, I/O speed, memory speed, and CPU capabilities.
161
+
162
+
163
+ ## Acknowledgements
164
+ `Pie` is dependent on the following libraries, we are grateful to all the developers/maintainers:
165
+ - [click](https://github.com/pallets/click): Python command line
166
+ - [cyvcf2](https://github.com/brentp/cyvcf2): VCF/BCF processing
167
+ - [pyfastx](https://github.com/lmdu/pyfastx): Reference FASTA processing
168
+ - [numba](https://github.com/numba/numba): JIT accerleration
169
+ - [sortedcontainers](https://github.com/grantjenks/python-sortedcontainers): Python Sorted Container Types
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+
182
+
183
+
184
+
185
+
@@ -0,0 +1,164 @@
1
+ <img src="pie_logo.png" width = "100">
2
+
3
+ # pie
4
+ Phasing all-In-one Evaluator, for haplotype phasing evaluation
5
+
6
+ ## Installation
7
+ Currently, `Pie` does not support online installation, but will be available through `pip` or `conda` upon publication.
8
+
9
+ Installation will finish in a few minutes.
10
+
11
+ ### Use `pip` to conduct local installation
12
+ 1. Create new virtual environment
13
+ ```
14
+ conda create -n pie python=3.8;
15
+ conda activate pie;
16
+ ```
17
+
18
+ 2. Navigate to the base directory, which contains `setup.py`. Use `pip` to install `pie`.
19
+ ```
20
+ pip install .;
21
+ ```
22
+
23
+ ## Usages
24
+ ### Required arguments
25
+ | Parameters | Description | Format or example |
26
+ |:---:|:---:|:---:|
27
+ | `-i or --input` | file for evaluation | .vcf / .vcf.gz |
28
+ | `-c or --compare` | ground truth file | .vcf / .vcf.gz |
29
+ | `-r or --ref` | reference file | .fa / .fasta / .fai |
30
+ | `-o or --output` | Output file prefix | exmaple: ./test/output_name |
31
+
32
+ ### Recommend flag
33
+ Use `--verbose` to monitor the running process and enable detailed logging.
34
+
35
+ ### Full usages
36
+ ```
37
+ Usage: pie [OPTIONS]
38
+
39
+ Options:
40
+ -i, --input TEXT Input vcf/vcf.gz file for evaluation [required]
41
+ -n, --name TEXT User defined sample name, [default: Sample]
42
+ -c, --compare TEXT Ground truth vcf/vcf.gz file for comparison
43
+ [required]
44
+ -r, --ref TEXT Reference file fasta file (.fasta or .fa) or fasta
45
+ index file (.fai) [required]
46
+ -o, --output TEXT Output file prefix, such as -o ./test/output_name
47
+ [required]
48
+ -t, --threads INTEGER Maximum numbers of parallel threads [default: 24]
49
+ -m, --max-len INTEGER Maximum variant distance for pairwise calculation
50
+ [default: 250000]
51
+ -b, --bed TEXT .bed file specifying genomic regions to include
52
+ [default: None]
53
+ --min-sv INTEGER Minimal length threshold of Structral Variant
54
+ [default: 30, ALT length > 30 bp is SV]
55
+ --chrom TEXT Chromosome to evaluate,use comma to join chromosome
56
+ name e.g. --chrom chr1,chr2,chr3
57
+ [default:chr1,chr2,chr3,...,chr22]
58
+ --sexchrom TEXT Sex chromosme,use comma to join chromosome name e.g.
59
+ --sexchrom chrX,chrY [default: chrX,chrY]
60
+ --mincount INTEGER Minimum numbers of phased sites in a phase block
61
+ [default: 2]
62
+ --block Output phasing block start and end positions in a BED
63
+ file
64
+ --no-sex Ignore sex chromosome
65
+ --canonical Canonical mode, only evaluate single mutation SNV
66
+ ignore double heterozygous site
67
+ --only-snv Only evaluate single nucleotide variation
68
+ --only-indel Only evaluate insertion and deletion
69
+ --only-sv Only evaluate structural variant
70
+ --no-snv Ignore single nucleotide variation
71
+ --no-indel Ignore insertion and deletion
72
+ --no-sv Ignore structural variant
73
+ --no-double Ignore double heterozygous site
74
+ --no-sort Do not sort chromosome or regions, directly use the
75
+ input order
76
+ --verbose Enable verbose mode, printing parameters and progress
77
+ to standard output
78
+ --version Show the version and exit.
79
+ --help Show this message and exit.
80
+ ```
81
+
82
+ ## Exmaples
83
+ Suppose `phase.vcf` is the sample VCF file to be evaluated against the ground truth VCF file (`truth.vcf`).
84
+ 1. (Comprehensive) Evaluate all autosome
85
+ ```
86
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa -o ./output/comprehensive
87
+ ```
88
+
89
+ 2. (Chromosome specific) Restrict evaluation to selected chromosome
90
+ ```
91
+ pie --verbose --chrom chr6 -i phase.vcf -c truth.vcf -r ref.fa -o ./output/chr6
92
+ ```
93
+
94
+ 3. (Region specific) Focus only on regions defined in a BED file.
95
+ ```
96
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa --bed mhc.bed -o ./output/mhc
97
+ ```
98
+
99
+ 4. (Filter) Exclude structural variants (SV) from the analysis
100
+ ```
101
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa --no-sv -o ./output/no_sv
102
+ ```
103
+
104
+ 5. (More output) Output raw phasing block start and end positions to a BED file
105
+ ```
106
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa --block -o ./output/more
107
+ ```
108
+
109
+ 6. (Miscellaneous) Evaluate only SNVs on chromosome 6 and output raw block start and end positions to a BED file.
110
+ ```
111
+ pie --verbose -i phase.vcf -c truth.vcf -r ref.fa --chrom chr6 --only-snv --block -o ./output/misc
112
+ ```
113
+
114
+ ## Test data
115
+ Small query and truth test files are provided in [here](./tests) including three formats:
116
+ | Filename | Format | Description |
117
+ |:---:|:---:|:---:|
118
+ | small_query.vcf | VCF | Uncompressed VCF |
119
+ | small_query.vcf.gz | VCF.GZ | Compressed VCF |
120
+ | small_query.bcf | BCF | Binary VCF |
121
+
122
+ `small_truth.vcf` is provided as the truth.
123
+
124
+ The `VCF` format follows regulations in <https://samtools.github.io/hts-specs/VCFv4.1.pdf>
125
+
126
+
127
+ ## Output file
128
+ | Output suffix | Description | Condition |
129
+ |:---:|:---:|:--:|
130
+ | `.variant.stats.csv` | Genotype evaluation result and phased percentage | Always generated |
131
+ | `.perchrom.csv` | Per chromosome phasing evaluation result | Always generated |
132
+ | `.overall.csv` | Overall sample evaluation result | Always generated |
133
+ | `.blocks.bed` | Raw phasing block start end in `-i` or `--input` file | with `--block` set |
134
+
135
+
136
+ ## Resouce consumption
137
+ `Pie` is expected to completed evaluation within minutes with the default 24 threads on a stardard X86 platfrom.
138
+
139
+ The actual performance may vary depending on factors such as size of `vcf`, I/O speed, memory speed, and CPU capabilities.
140
+
141
+
142
+ ## Acknowledgements
143
+ `Pie` is dependent on the following libraries, we are grateful to all the developers/maintainers:
144
+ - [click](https://github.com/pallets/click): Python command line
145
+ - [cyvcf2](https://github.com/brentp/cyvcf2): VCF/BCF processing
146
+ - [pyfastx](https://github.com/lmdu/pyfastx): Reference FASTA processing
147
+ - [numba](https://github.com/numba/numba): JIT accerleration
148
+ - [sortedcontainers](https://github.com/grantjenks/python-sortedcontainers): Python Sorted Container Types
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
File without changes
@@ -0,0 +1,39 @@
1
+ import math
2
+
3
+
4
+ def cal_precision(TP: int, FP: int) -> float:
5
+ denominator = TP + FP
6
+
7
+ if denominator != 0:
8
+ precision = TP / denominator
9
+ return precision
10
+ else:
11
+ return math.nan
12
+
13
+
14
+ def cal_recall(TP: int, FN: int) -> float:
15
+ denominator = TP + FN
16
+
17
+ if denominator != 0:
18
+ recall = TP / denominator
19
+ return recall
20
+ else:
21
+ return math.nan
22
+
23
+
24
+ def cal_f1(precision: float, recall: float) -> float:
25
+ denominator = precision + recall
26
+ if (denominator != 0) and not(math.isnan(denominator)):
27
+ F1 = (2 * precision * recall) / denominator
28
+ return F1
29
+ else:
30
+ return math.nan
31
+
32
+
33
+ def cal_all(TP: int, FP: int, FN: int) -> tuple:
34
+ precision = cal_precision(TP, FP)
35
+ recall = cal_recall(TP, FN)
36
+ f1 = cal_f1(precision, recall)
37
+
38
+ return (precision, recall, f1)
39
+
@@ -0,0 +1,14 @@
1
+ def cal_NGx0(len_list: list, total_len: int, p: int) -> int:
2
+ total_len = int(total_len)
3
+ target = total_len * p / 100
4
+
5
+ if sum(len_list) < target:
6
+ return None
7
+
8
+ len_list.sort(reverse = True)
9
+
10
+ cummulative = 0
11
+ for i in len_list:
12
+ cummulative += i
13
+ if cummulative >= target:
14
+ return i
@@ -0,0 +1,62 @@
1
+ import pyfastx
2
+ import os
3
+ import sys
4
+ import logging
5
+
6
+
7
+ def get_ref_len(ref: str, chrom: list) -> dict:
8
+ suffix = os.path.splitext(ref)[1]
9
+ if suffix == ".fa" or suffix == ".fasta":
10
+ length_dict = fasta_mode(ref, chrom)
11
+ return length_dict
12
+ elif suffix == ".fai":
13
+ length_dict = fai_mode(ref, chrom)
14
+ return length_dict
15
+ else:
16
+ logging.error("Invalid file suffix of the reference file, must be either .fasta/.fa or .fai")
17
+ raise ValueError("Invalid file suffix of the reference file")
18
+
19
+
20
+
21
+ def fasta_mode(ref: str, chrom: list) -> dict:
22
+ chr_len = dict()
23
+ exist = set()
24
+ for name, seq in pyfastx.Fasta(ref, build_index = False):
25
+ if name in chrom:
26
+ chr_len[name] = len(seq)
27
+ exist.add(name)
28
+
29
+ if len(chr_len) == len(chrom):
30
+ return chr_len
31
+ else:
32
+ for i in chrom:
33
+ if i not in exist:
34
+ logging.warning(f"{i} not in reference file")
35
+ return chr_len
36
+
37
+
38
+
39
+ def fai_mode(ref_fai: str, chrom: list) -> dict:
40
+ chr_len = dict()
41
+ exist = set()
42
+ with open(ref_fai, 'r') as f:
43
+ for line in f:
44
+ m = line.split()
45
+ if len(m) >= 2:
46
+ name = m[0]
47
+ if name in chrom:
48
+ chr_len[name] = int(m[1])
49
+ exist.add(name)
50
+
51
+ if len(chr_len) == len(chrom):
52
+ return chr_len
53
+ else:
54
+ for i in chrom:
55
+ if i not in exist:
56
+ logging.warning(f"{i} not in reference file")
57
+ return chr_len
58
+
59
+
60
+
61
+
62
+
@@ -0,0 +1,22 @@
1
+ import logging
2
+
3
+
4
+ def check_filters(filters: dict) -> bool:
5
+ only_count = ([filters["only_snv"], filters["only_indel"], filters["only_sv"]]).count(True)
6
+ if only_count > 1:
7
+ logging.error("Only one of --only_snv, --only_indel, or --only_sv can be set at a time.")
8
+ return False
9
+
10
+ if filters["only_snv"] and filters["no_snv"]:
11
+ logging.error("Can not set --only_snv and --no_snv simultaneously")
12
+ return False
13
+
14
+ if filters["only_indel"] and filters["no_indel"]:
15
+ logging.error("Can not set --only_indel and --no_indel simultaneously")
16
+ return False
17
+
18
+ if filters["only_sv"] and filters["no_sv"]:
19
+ logging.error("Can not set --only_sv and --no_sv simultaneously")
20
+ return False
21
+
22
+ return True
@@ -0,0 +1,114 @@
1
+ import os
2
+ import sys
3
+ import click
4
+ import math
5
+ from pathlib import Path
6
+ from pie.module.sort_chrom import sort_chrom
7
+ import logging
8
+
9
+ @click.command()
10
+ @click.option("-i", "--input", required = True, type = str, help = "Input vcf/vcf.gz file for evaluation")
11
+ @click.option("-n", "--name", default = "Sample", type = str, help = "User defined sample name, [default: Sample]")
12
+ @click.option("-c", "--compare", required = True, type = str, help = "Ground truth vcf/vcf.gz file for comparison")
13
+ @click.option("-r", "--ref", required = True, type = str, help = "Reference file fasta file (.fasta or .fa) or fasta index file (.fai)")
14
+ @click.option("-o", "--output", required = True, type = str, help = "Output file prefix, such as -o ./test/output_name")
15
+ @click.option("-t", "--threads", default = 24, type = int, help = "Maximum numbers of parallel threads [default: 24]")
16
+ @click.option("-m", "--max-len", default = 250 * 10**3, type = int, help = "Maximum variant distance for pairwise calculation [default: 250000]")
17
+ @click.option("-b", "--bed", default = None, type = str, help = r".bed file specifying genomic regions to include [default: None]")
18
+ @click.option("--min-sv", default = 30, type = int, help = "Minimal length threshold of Structral Variant [default: 30, ALT length > 30 bp is SV]")
19
+ @click.option("--chrom", default = ','.join(["chr" + str(i) for i in range(1, 23)]), type = str, help = "Chromosome to evaluate,use comma to join chromosome name e.g. --chrom chr1,chr2,chr3 [default:chr1,chr2,chr3,...,chr22]")
20
+ @click.option("--sexchrom", default = "chrX,chrY", type = str, help = "Sex chromosme,use comma to join chromosome name e.g. --sexchrom chrX,chrY [default: chrX,chrY]")
21
+ @click.option("--mincount", default = 2, type = int, help = "Minimum numbers of phased sites in a phase block [default: 2]")
22
+ @click.option("--block", is_flag = True, help = r"Output phasing block start and end positions in a BED file")
23
+ @click.option("--no-sex", is_flag = True, help = "Ignore sex chromosome")
24
+ @click.option("--canonical", is_flag = True, help = "Canonical mode, only evaluate single mutation SNV ignore double heterozygous site")
25
+ @click.option("--only-snv", is_flag = True, help = "Only evaluate single nucleotide variation")
26
+ @click.option("--only-indel", is_flag = True, help = "Only evaluate insertion and deletion")
27
+ @click.option("--only-sv", is_flag = True, help = "Only evaluate structural variant")
28
+ @click.option("--no-snv", is_flag = True, help = "Ignore single nucleotide variation")
29
+ @click.option("--no-indel", is_flag = True, help = "Ignore insertion and deletion")
30
+ @click.option("--no-sv", is_flag = True, help = "Ignore structural variant")
31
+ @click.option("--no-double", is_flag = True, help = "Ignore double heterozygous site")
32
+ @click.option("--no-sort", is_flag = True, help = "Do not sort chromosome or regions, directly use the input order")
33
+ @click.option("--lmdb", is_flag = True, hidden = True, help = "Output intermediate hamming result as .lmdb file")
34
+ @click.option("--verbose", is_flag = True, help = "Enable verbose mode, printing parameters and progress to standard output")
35
+ @click.version_option(version="0.11.1", prog_name = r"Phasing all-in-one evaluator (pie), based on Python 3.7+")
36
+ def cli(input, name, compare, ref, output, threads, max_len, bed, min_sv, chrom, sexchrom, mincount, canonical, block, no_sex, only_snv, only_indel, only_sv, no_snv, no_indel, no_sv, no_double, no_sort, lmdb, verbose) -> tuple:
37
+
38
+ # set logging
39
+ logging.basicConfig(level = logging.DEBUG, format = "%(asctime)s - %(levelname)s - %(message)s")
40
+
41
+ # clean parameters
42
+ input = os.path.abspath(input)
43
+ compare = os.path.abspath(compare)
44
+ ref = os.path.abspath(ref)
45
+
46
+ if bed:
47
+ bed = os.path.abspath(bed)
48
+
49
+ if canonical:
50
+ only_snv = True
51
+ no_double = True
52
+
53
+
54
+ # check parameters
55
+ input_vcf = Path(input)
56
+ compare_vcf = Path(compare)
57
+ if not (input_vcf.suffix == ".vcf" or input_vcf.suffix == ".bcf" or (".gz" in input_vcf.suffixes and ".vcf" in input_vcf.suffixes)):
58
+ raise ValueError(r"-i or --input must be .vcf or .vcf.gz file. You provided a file with a different extension")
59
+ if not (compare_vcf.suffix == ".vcf" or compare_vcf.suffix == ".bcf" or (".gz" in compare_vcf.suffixes and ".vcf" in compare_vcf.suffixes)):
60
+ raise ValueError(r"-c or --compare must be .vcf or .vcf.gz file. You provided a file with a different extension")
61
+
62
+ ref_file = Path(ref)
63
+ if not (ref_file.suffix == ".fa" or ref_file.suffix == ".fasta" or ref_file.suffix == ".fai"):
64
+ raise ValueError(r"-r or --ref must be .fa, .fasta, or .fai file. You provided a file with a different extension")
65
+
66
+ if bed:
67
+ bed_file = Path(bed)
68
+ if not (bed_file.suffix == ".bed"):
69
+ raise ValueError(r"--bed must be .bed file. You provided a file with a different extension")
70
+
71
+ output_dir = os.path.dirname(output)
72
+ if not (os.path.exists(output_dir)):
73
+ raise ValueError(f"The output directory {output_dir} does not exist")
74
+ else:
75
+ if not os.path.isdir(output_dir):
76
+ raise ValueError(f"The output directory {output_dir} exists but is not a directory")
77
+
78
+ if threads > os.cpu_count():
79
+ logging.warning(f"-t or --threads set threads exceed the system CPU thread count ({os.cpu_count()})")
80
+
81
+
82
+ # process chromosome area
83
+ chrom = [i.strip() for i in chrom.split(',')]
84
+ if not chrom:
85
+ raise ValueError("-c or --chrom must be in comma joined string e.g. chr1,chr2,ch3")
86
+
87
+ sexchrom = [i.strip() for i in sexchrom.split(',')]
88
+ if not chrom:
89
+ raise ValueError("--sexchrom must be in comma joined string e.g. chr1,chr2,ch3")
90
+
91
+ if no_sex:
92
+ clean_chrom = []
93
+ for i in chrom:
94
+ if i not in sexchrom:
95
+ clean_chrom.append(i)
96
+ chrom = clean_chrom
97
+
98
+ # sort chromosome
99
+ if not no_sort:
100
+ chrom = sort_chrom(chrom)
101
+
102
+ # print parameters in verbose mode
103
+ if verbose:
104
+ ctx = click.get_current_context()
105
+ logging.info("Command parameters:")
106
+ for param in ctx.command.params:
107
+ param_name = param.name
108
+ if param_name != "version":
109
+ param_value = ctx.params[param_name]
110
+ logging.info(f"{param_name}: {param_value}")
111
+
112
+ return (input, name, compare, ref, output, threads, max_len, bed, min_sv, chrom, sexchrom, mincount, canonical, block, no_sex, only_snv, only_indel, only_sv, no_snv, no_indel, no_sv, no_double, no_sort, lmdb, verbose)
113
+
114
+