pav3 3.0.0.dev17__tar.gz → 3.0.0.dev18__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.
- {pav3-3.0.0.dev17/src/pav3.egg-info → pav3-3.0.0.dev18}/PKG-INFO +1 -1
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/__init__.py +1 -1
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/trim.py +2 -2
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/workflow/rules/call.smk +45 -34
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/lgsv/struct.py +10 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/vcf.py +62 -129
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18/src/pav3.egg-info}/PKG-INFO +1 -1
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/LICENSE +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/README.md +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/pyproject.toml +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/setup.cfg +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/__main__.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/__init__.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/features.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/lcmodel/__init__.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/lcmodel/_lcmodel.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/lcmodel/_lcmodel_logistic.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/lcmodel/_lcmodel_null.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/lcmodel/_util.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/lift.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/op.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/records.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/score.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/align/tables.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/anno.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/call/__init__.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/call/expr.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/call/integrate.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/call/intra.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/call/util.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/cli/__init__.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/cli/_cli.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/cli/_common_opt.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/cli/_subcommand_batch.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/cli/_subcommand_call.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/cli/_subcommand_license.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/const.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/default/model.json +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/human_95_80/model.json +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/human_95_80/model_info.tar.gz +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/human_95_80/weights.npz +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/human_98_80/model.json +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/human_98_80/model_info.tar.gz +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/human_98_80/weights.npz +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/prim_90_50/model.json +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/prim_90_50/model_info.tar.gz +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/prim_90_50/weights.npz +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/primdiv_85_50/model.json +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/primdiv_85_50/model_info.tar.gz +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/lcmodel/primdiv_85_50/weights.npz +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/tracks/alignment_track_fields.tsv +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/tracks/variant_track_fields.tsv +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/workflow/Snakefile +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/workflow/profiles/pav_default/config.yaml +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/workflow/rules/align.smk +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/workflow/rules/data.smk +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/workflow/rules/pipeline.smk +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/workflow/rules/tracks.smk +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/dev/__init__.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/dev/imports.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/dev/inter.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/dev/path.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/dev/sm.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/dev/tables.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/fig/__init__.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/fig/const.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/fig/density.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/fig/tracks.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/fig/util.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/inv.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/io.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/kde.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/lgsv/__init__.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/lgsv/call.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/lgsv/chain.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/lgsv/interval.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/lgsv/io.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/lgsv/region_kde.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/lgsv/resources.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/lgsv/variant.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/params.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/pipeline.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/region.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/schema.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/seq.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/util.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/workflow/__init__.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/workflow/__pycache__/__init__.cpython-312.pyc +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/workflow/__pycache__/call.cpython-312.pyc +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/workflow/__pycache__/resource.cpython-312.pyc +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/workflow/call.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/workflow/resource.py +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3.egg-info/SOURCES.txt +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3.egg-info/dependency_links.txt +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3.egg-info/entry_points.txt +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3.egg-info/requires.txt +0 -0
- {pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3.egg-info/top_level.txt +0 -0
|
@@ -83,7 +83,7 @@ TRIM_DESC = {
|
|
|
83
83
|
}
|
|
84
84
|
"""Trim mode description."""
|
|
85
85
|
|
|
86
|
-
DEFAULT_MIN_TRIM_QRY_LEN =
|
|
86
|
+
DEFAULT_MIN_TRIM_QRY_LEN = 1
|
|
87
87
|
"""Default minimum query length. Alignments with fewer query bases are removed."""
|
|
88
88
|
|
|
89
89
|
|
|
@@ -111,7 +111,7 @@ def trim_alignments_qry(
|
|
|
111
111
|
raise ValueError('Query FAI dataframe is None.')
|
|
112
112
|
|
|
113
113
|
if min_trim_qry_len < 1:
|
|
114
|
-
|
|
114
|
+
min_trim_qry_len = 1
|
|
115
115
|
|
|
116
116
|
score_model = get_score_model(score_model)
|
|
117
117
|
|
|
@@ -29,8 +29,6 @@ global temp
|
|
|
29
29
|
# Rules
|
|
30
30
|
#
|
|
31
31
|
|
|
32
|
-
CALL_VCF_VARTYPES = ('insdel', 'inv', 'snv', 'cpx', 'dup')
|
|
33
|
-
|
|
34
32
|
# Generate the VCF
|
|
35
33
|
rule call_vcf:
|
|
36
34
|
input:
|
|
@@ -38,7 +36,7 @@ rule call_vcf:
|
|
|
38
36
|
'results/{asm_name}/call/call_{vartype}.parquet',
|
|
39
37
|
ASM_TABLE, PAV_CONFIG,
|
|
40
38
|
asm_name=wildcards.asm_name,
|
|
41
|
-
vartype=
|
|
39
|
+
vartype=pav3.vcf.VARTYPES,
|
|
42
40
|
),
|
|
43
41
|
callable_ref=lambda wildcards: pav3.pipeline.expand_pattern(
|
|
44
42
|
'results/{asm_name}/call_hap/callable_ref_{hap}.parquet',
|
|
@@ -86,14 +84,14 @@ rule call_vcf:
|
|
|
86
84
|
with pav3.io.TempDirContainer(
|
|
87
85
|
prefix=f'pav_vcf_{wildcards.asm_name}_'
|
|
88
86
|
) as temp_file_container:
|
|
89
|
-
for vartype in
|
|
87
|
+
for vartype in pav3.vcf.VARTYPES:
|
|
90
88
|
|
|
91
89
|
# Read variants
|
|
92
90
|
df = (
|
|
93
91
|
pl.scan_parquet(
|
|
94
92
|
pattern_var.format(
|
|
95
93
|
asm_name=wildcards.asm_name,
|
|
96
|
-
vartype=vartype
|
|
94
|
+
vartype=vartype,
|
|
97
95
|
)
|
|
98
96
|
)
|
|
99
97
|
.with_row_index('_index')
|
|
@@ -103,11 +101,15 @@ rule call_vcf:
|
|
|
103
101
|
df = df.with_columns(pl.lit('SNV').alias('vartype'))
|
|
104
102
|
|
|
105
103
|
# Initialize VCF fields (all but FORMAT and sample columns)
|
|
106
|
-
|
|
107
|
-
df
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
104
|
+
try:
|
|
105
|
+
df = pav3.vcf.init_vcf_fields(
|
|
106
|
+
df,
|
|
107
|
+
ref_fa=ref_fa,
|
|
108
|
+
use_sym=None,
|
|
109
|
+
vartype=vartype,
|
|
110
|
+
)
|
|
111
|
+
except Exception as e:
|
|
112
|
+
raise RuntimeError(f'Failed to initialize VCF fields for {vartype}: {e}') from e
|
|
111
113
|
|
|
112
114
|
# Create a sample column
|
|
113
115
|
df = df.with_columns(
|
|
@@ -117,36 +119,45 @@ rule call_vcf:
|
|
|
117
119
|
)
|
|
118
120
|
|
|
119
121
|
# Append genotypes
|
|
120
|
-
|
|
121
|
-
df
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
122
|
+
try:
|
|
123
|
+
df = (
|
|
124
|
+
df.join(
|
|
125
|
+
pav3.vcf.gt_column(
|
|
126
|
+
df,
|
|
127
|
+
hap_source,
|
|
128
|
+
hap_callable,
|
|
129
|
+
col_name='_vcf_field_gt',
|
|
130
|
+
separator='|',
|
|
131
|
+
),
|
|
132
|
+
on='_index',
|
|
133
|
+
how='left'
|
|
134
|
+
)
|
|
135
|
+
.with_columns(
|
|
136
|
+
pl.col('_vcf_sample_0').list.concat('_vcf_field_gt'),
|
|
137
|
+
pl.col('_vcf_format').list.concat(pl.lit('GT'))
|
|
138
|
+
)
|
|
139
|
+
.drop('_vcf_field_gt')
|
|
135
140
|
)
|
|
136
|
-
|
|
137
|
-
|
|
141
|
+
except Exception as e:
|
|
142
|
+
raise RuntimeError(f'Failed to append genotypes for {vartype}: {e}') from e
|
|
138
143
|
|
|
139
144
|
# Add INFO fields
|
|
140
|
-
|
|
145
|
+
try:
|
|
146
|
+
df = pav3.vcf.standard_info_fields(df)
|
|
147
|
+
except Exception as e:
|
|
148
|
+
raise RuntimeError(f'Failed to add INFO fields for {vartype}: {e}') from e
|
|
141
149
|
|
|
142
150
|
# Finalize VCF fields
|
|
143
|
-
|
|
144
|
-
df
|
|
145
|
-
|
|
146
|
-
|
|
151
|
+
try:
|
|
152
|
+
df = pav3.vcf.reformat_vcf_table(
|
|
153
|
+
df,
|
|
154
|
+
sample_columns={0: wildcards.asm_name}
|
|
155
|
+
)
|
|
147
156
|
|
|
148
|
-
|
|
149
|
-
|
|
157
|
+
# Write VCF
|
|
158
|
+
df.sink_parquet(temp_file_container.next())
|
|
159
|
+
except Exception as e:
|
|
160
|
+
raise RuntimeError(f'Failed to finalize VCF fields for {vartype}: {e}') from e
|
|
150
161
|
|
|
151
162
|
# Write
|
|
152
163
|
header_list = pav3.vcf.get_headers(
|
|
@@ -143,6 +143,9 @@ def get_ref_trace(
|
|
|
143
143
|
on='_index_aligned',
|
|
144
144
|
how='left'
|
|
145
145
|
)
|
|
146
|
+
.with_columns(
|
|
147
|
+
pl.col('is_rev') ^ interval.is_rev
|
|
148
|
+
)
|
|
146
149
|
.group_by('_index_trace')
|
|
147
150
|
.agg(
|
|
148
151
|
(
|
|
@@ -159,6 +162,13 @@ def get_ref_trace(
|
|
|
159
162
|
)
|
|
160
163
|
.drop(['_index_aligned', '_index_trace'])
|
|
161
164
|
|
|
165
|
+
# Adjust anchor-only segments at the edges to include only segments that are a single fwd copy
|
|
166
|
+
.with_columns(
|
|
167
|
+
(pl.col('_all_anchor') & (
|
|
168
|
+
(pl.col('fwd_count') == 1) & (pl.col('rev_count') == 0)
|
|
169
|
+
)).alias('_all_anchor')
|
|
170
|
+
)
|
|
171
|
+
|
|
162
172
|
# Drop anchor-only segments at the edges
|
|
163
173
|
.filter(
|
|
164
174
|
~pl.col('_all_anchor') | (
|
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
"""Transform variant calls from Parquet files to VCF files."""
|
|
2
2
|
|
|
3
|
+
__all__ = [
|
|
4
|
+
'InfoField',
|
|
5
|
+
'FilterField',
|
|
6
|
+
'FormatField',
|
|
7
|
+
'AltField',
|
|
8
|
+
'VCF_VERSION',
|
|
9
|
+
'INFO_FIELDS',
|
|
10
|
+
'FILTER_FIELDS',
|
|
11
|
+
'FORMAT_FIELDS',
|
|
12
|
+
'ALT_FIELDS',
|
|
13
|
+
'VARTYPES',
|
|
14
|
+
'VARTYPE_COMPAT',
|
|
15
|
+
'get_headers',
|
|
16
|
+
'init_vcf_fields',
|
|
17
|
+
'vcf_fields_seq_insdel',
|
|
18
|
+
'vcf_fields_sym',
|
|
19
|
+
'vcf_fields_snv',
|
|
20
|
+
'gt_column',
|
|
21
|
+
'standard_info_fields',
|
|
22
|
+
'reformat_vcf_table',
|
|
23
|
+
'get_hap_source',
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
|
|
3
27
|
from collections.abc import Iterable, Mapping
|
|
4
|
-
from dataclasses import dataclass
|
|
5
28
|
import datetime
|
|
6
29
|
from pathlib import Path
|
|
7
30
|
import threading
|
|
@@ -170,6 +193,18 @@ ALT_FIELDS = [
|
|
|
170
193
|
AltField('CPX', 'Complex variant'),
|
|
171
194
|
]
|
|
172
195
|
|
|
196
|
+
VARTYPES = ('insdel', 'inv', 'snv', 'cpx', 'dup')
|
|
197
|
+
|
|
198
|
+
VARTYPE_COMPAT = {
|
|
199
|
+
'insdel': {'INS', 'DEL'},
|
|
200
|
+
'ins': {'INS'},
|
|
201
|
+
'del': {'DEL'},
|
|
202
|
+
'inv': {'INV'},
|
|
203
|
+
'snv': {'SNV'},
|
|
204
|
+
'cpx': {'CPX'},
|
|
205
|
+
'dup': {'DUP'},
|
|
206
|
+
}
|
|
207
|
+
|
|
173
208
|
|
|
174
209
|
def get_headers(
|
|
175
210
|
ref_filename: Optional[str | Path] = None,
|
|
@@ -221,7 +256,7 @@ def get_headers(
|
|
|
221
256
|
|
|
222
257
|
def init_vcf_fields(
|
|
223
258
|
df: pl.LazyFrame,
|
|
224
|
-
ref_fa: Optional[str] = None,
|
|
259
|
+
ref_fa: Optional[str | Path] = None,
|
|
225
260
|
use_sym: Optional[bool] = None,
|
|
226
261
|
vartype: Optional[str] = None,
|
|
227
262
|
) -> pl.LazyFrame:
|
|
@@ -234,11 +269,30 @@ def init_vcf_fields(
|
|
|
234
269
|
:param ref_fa: Reference FASTA filename. Required for non-SNV variants.
|
|
235
270
|
:param use_sym: Whether to use symbolic alternate records. If None, INS, DEL, and SNV ore not
|
|
236
271
|
symbolic, and all other variant types are.
|
|
272
|
+
:param vartype: Expected variant type or types (i.e. "insdel" allows "INS" and "DEL"). Setting
|
|
273
|
+
this field ensures the variant types is handled consisntently if all variant types
|
|
274
|
+
are not in table `df` or `df` is empty.
|
|
237
275
|
"""
|
|
276
|
+
df_schema = df.collect_schema()
|
|
277
|
+
|
|
238
278
|
vartype_set = set(
|
|
239
279
|
df.select(pl.col('vartype').unique()).collect().to_series()
|
|
240
280
|
)
|
|
241
281
|
|
|
282
|
+
if vartype is not None:
|
|
283
|
+
vartype_compat = VARTYPE_COMPAT.get(vartype, None)
|
|
284
|
+
|
|
285
|
+
if vartype_compat is None:
|
|
286
|
+
raise ValueError(f'Unknown variant type: {vartype}')
|
|
287
|
+
|
|
288
|
+
if no_compat_set := vartype_set - vartype_compat:
|
|
289
|
+
raise ValueError(
|
|
290
|
+
f'Declared variant type "{vartype}" is not compatible with types found '
|
|
291
|
+
f'in the variant table: {", ".join(sorted([str(_).upper() for _ in no_compat_set]))}'
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
vartype_set = vartype_compat
|
|
295
|
+
|
|
242
296
|
if 'SNV' in vartype_set and len(vartype_set) > 1:
|
|
243
297
|
raise ValueError(
|
|
244
298
|
f'Cannot mix SNV variants with other variant types: '
|
|
@@ -335,7 +389,7 @@ def init_vcf_fields(
|
|
|
335
389
|
|
|
336
390
|
def vcf_fields_seq_insdel(
|
|
337
391
|
df: pl.LazyFrame,
|
|
338
|
-
ref_fa: str,
|
|
392
|
+
ref_fa: Path | str,
|
|
339
393
|
) -> pl.LazyFrame:
|
|
340
394
|
"""Set POS, REF, and ALT VCF fields for insertions and deletions (non-symbolic).
|
|
341
395
|
|
|
@@ -464,7 +518,7 @@ def vcf_fields_seq_insdel(
|
|
|
464
518
|
|
|
465
519
|
def vcf_fields_sym(
|
|
466
520
|
df: pl.LazyFrame,
|
|
467
|
-
ref_fa: str,
|
|
521
|
+
ref_fa: Path | str,
|
|
468
522
|
) -> pl.LazyFrame:
|
|
469
523
|
"""Get POS, REF, and ALT fields for symbolic alternate records.
|
|
470
524
|
|
|
@@ -955,17 +1009,17 @@ class _LockingPysam():
|
|
|
955
1009
|
|
|
956
1010
|
Pysam is not thread-safe, and will fail when called through Polars. This class explicitly locks it.
|
|
957
1011
|
"""
|
|
958
|
-
filename:
|
|
1012
|
+
filename: Path
|
|
959
1013
|
|
|
960
1014
|
def __init__(
|
|
961
1015
|
self,
|
|
962
|
-
filename,
|
|
1016
|
+
filename: Path | str,
|
|
963
1017
|
):
|
|
964
1018
|
"""Create a new locking object.
|
|
965
1019
|
|
|
966
1020
|
:param filename: FASTA file name.
|
|
967
1021
|
"""
|
|
968
|
-
self.filename = filename
|
|
1022
|
+
self.filename = Path(filename)
|
|
969
1023
|
self.ref_file = None
|
|
970
1024
|
self.lock = threading.Lock()
|
|
971
1025
|
|
|
@@ -973,7 +1027,7 @@ class _LockingPysam():
|
|
|
973
1027
|
if self.ref_file is not None:
|
|
974
1028
|
raise RuntimeError('Ref file already open')
|
|
975
1029
|
|
|
976
|
-
self.ref_file = pysam.FastaFile(self.filename)
|
|
1030
|
+
self.ref_file = pysam.FastaFile(str(self.filename))
|
|
977
1031
|
|
|
978
1032
|
return self
|
|
979
1033
|
|
|
@@ -995,124 +1049,3 @@ class _LockingPysam():
|
|
|
995
1049
|
|
|
996
1050
|
with self.lock:
|
|
997
1051
|
return self.ref_file.fetch(chrom, start, end)
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
#
|
|
1001
|
-
# Refactor
|
|
1002
|
-
#
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
# def _init_vcf_fields(
|
|
1006
|
-
# df: pl.LazyFrame | pl.DataFrame,
|
|
1007
|
-
# ) -> pl.LazyFrame:
|
|
1008
|
-
# """Initialize VCF fields common across all variant types (does not set REF, ALT, or POS).
|
|
1009
|
-
#
|
|
1010
|
-
# :param df: Variant table.
|
|
1011
|
-
# """
|
|
1012
|
-
#
|
|
1013
|
-
# if isinstance(df, pl.DataFrame):
|
|
1014
|
-
# df = df.lazy()
|
|
1015
|
-
#
|
|
1016
|
-
# return (
|
|
1017
|
-
# df.with_columns(
|
|
1018
|
-
# pl.col('chrom').alias('#CHROM'),
|
|
1019
|
-
# pl.col('id').alias('ID'),
|
|
1020
|
-
# pl.lit('.').alias('QUAL'),
|
|
1021
|
-
# (
|
|
1022
|
-
# pl.when(pl.col('filter').is_not_null())
|
|
1023
|
-
# .then(pl.col('filter').list.join(';'))
|
|
1024
|
-
# .otherwise(pl.lit('PASS'))
|
|
1025
|
-
# ).alias('FILTER'),
|
|
1026
|
-
# pl.lit([]).cast(pl.List(pl.String)).alias('_info'),
|
|
1027
|
-
# pl.lit([]).cast(pl.List(pl.Struct({'fmt': pl.String, 'sample': pl.String}))).alias('_sample')
|
|
1028
|
-
# )
|
|
1029
|
-
# .with_columns(
|
|
1030
|
-
# pl.col('_info').list.concat([
|
|
1031
|
-
# pl.concat_str(pl.lit('ID='), 'id'),
|
|
1032
|
-
# pl.concat_str(pl.lit('QRY_REGION='), pl.col('chrom'), pl.lit(':'), pl.col('qry_pos') + 1, pl.lit('-'), pl.col('qry_end')),
|
|
1033
|
-
# # pl.concat_str(pl.lit('QRY_STRAND='), pl.when(pl.col('is_rev')).then('-').otherwise('+')),
|
|
1034
|
-
# pl.concat_str(pl.lit('ALIGN_INDEX='), pl.col('align_index').cast(pl.List(pl.String)).list.join(','))
|
|
1035
|
-
# ])
|
|
1036
|
-
# )
|
|
1037
|
-
# )
|
|
1038
|
-
|
|
1039
|
-
# def _init_table():
|
|
1040
|
-
# df = (
|
|
1041
|
-
# df.with_columns(
|
|
1042
|
-
# pl.col('chrom').alias('#CHROM'),
|
|
1043
|
-
# # POS
|
|
1044
|
-
# pl.col('id').alias('ID'),
|
|
1045
|
-
# # REF
|
|
1046
|
-
# # ALT
|
|
1047
|
-
# pl.lit('.').alias('QUAL'),
|
|
1048
|
-
# (
|
|
1049
|
-
# pl.when(pl.col('filter').is_not_null())
|
|
1050
|
-
# .then(pl.col('filter').list.join(';'))
|
|
1051
|
-
# .otherwise(pl.lit('PASS'))
|
|
1052
|
-
# ).alias('FILTER'),
|
|
1053
|
-
# # INFO
|
|
1054
|
-
# # FORMAT
|
|
1055
|
-
# # Sample
|
|
1056
|
-
# )
|
|
1057
|
-
# )
|
|
1058
|
-
|
|
1059
|
-
# def _init_table_other(
|
|
1060
|
-
#
|
|
1061
|
-
# ):
|
|
1062
|
-
# df = (
|
|
1063
|
-
# df.with_columns(
|
|
1064
|
-
# (pl.col('vartype').is_in(['INV', 'CPX', 'DUP'])).alias('_is_sym'),
|
|
1065
|
-
# (pl.col('vartype') == 'SNV').alias('_is_snv'),
|
|
1066
|
-
# (pl.col('pos') > 0).alias('_ref_left') # Append reference base to left if True (most variants), move to end if not (variant at position 0)
|
|
1067
|
-
# )
|
|
1068
|
-
# )
|
|
1069
|
-
|
|
1070
|
-
#
|
|
1071
|
-
# def _ref_base(df, ref_fa):
|
|
1072
|
-
# """
|
|
1073
|
-
# Get reference base preceding a variant (SV, indel) or at the point change (SNV).
|
|
1074
|
-
#
|
|
1075
|
-
# :param df: Variant dataframe as BED.
|
|
1076
|
-
# :param ref_fa: Reference file.
|
|
1077
|
-
# """
|
|
1078
|
-
#
|
|
1079
|
-
# # Get the reference base location
|
|
1080
|
-
# with pysam.FastaFile(ref_fa) as ref_file:
|
|
1081
|
-
#
|
|
1082
|
-
# df = (
|
|
1083
|
-
# df.with_columns(
|
|
1084
|
-
# (
|
|
1085
|
-
# pl.when(pl.col('_ref_left'))
|
|
1086
|
-
# .then(pl.col('pos') - 1)
|
|
1087
|
-
# .otherwise(pl.col('end'))
|
|
1088
|
-
# ).alias('_ref_base_loc')
|
|
1089
|
-
# )
|
|
1090
|
-
# .with_columns(
|
|
1091
|
-
# pl.when(pl.col('_is_snv'))
|
|
1092
|
-
# .then(pl.col('_ref_base_loc') + 1)
|
|
1093
|
-
# .otherwise(pl.col('_ref_base_loc'))
|
|
1094
|
-
# ).alias('_ref_base_loc')
|
|
1095
|
-
# .with_columns(
|
|
1096
|
-
# pl.struct(['chrom', '_ref_base_loc'])
|
|
1097
|
-
# .apply(
|
|
1098
|
-
# lambda vals: ref_file.fetch(vals['chrom'], vals['_ref_base_loc'], vals['_ref_base_loc'] + 1)
|
|
1099
|
-
# ).alias('_ref_base')
|
|
1100
|
-
# )
|
|
1101
|
-
# .drop('_ref_base_Loc')
|
|
1102
|
-
# )
|
|
1103
|
-
#
|
|
1104
|
-
# # Open and update records
|
|
1105
|
-
# with pysam.FastaFile(ref_fa) as ref_file:
|
|
1106
|
-
# for index, row in df.iterrows():
|
|
1107
|
-
#
|
|
1108
|
-
# if row['SVTYPE'] in {'INS', 'DEL', 'INSDEL', 'DUP', 'INV'}:
|
|
1109
|
-
# yield ref_file.fetch(row['#CHROM'], row['POS'] + (-1 if row['POS'] > 0 else 0), row['POS']).upper()
|
|
1110
|
-
#
|
|
1111
|
-
# elif row['SVTYPE'] == 'SNV':
|
|
1112
|
-
# if 'REF' in row:
|
|
1113
|
-
# yield row['REF']
|
|
1114
|
-
# else:
|
|
1115
|
-
# yield ref_file.fetch(row['#CHROM'], row['POS'], row['POS'] + 1).upper()
|
|
1116
|
-
#
|
|
1117
|
-
# else:
|
|
1118
|
-
# raise RuntimeError('Unknown variant type: "{}" at index {}'.format(row['VARTYPE'], index))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/data/workflow/profiles/pav_default/config.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/workflow/__pycache__/__init__.cpython-312.pyc
RENAMED
|
File without changes
|
|
File without changes
|
{pav3-3.0.0.dev17 → pav3-3.0.0.dev18}/src/pav3/workflow/__pycache__/resource.cpython-312.pyc
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|