varcode 9.2.1__tar.gz → 9.2.2__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.
- {varcode-9.2.1/varcode.egg-info → varcode-9.2.2}/PKG-INFO +1 -1
- varcode-9.2.2/tests/test_sv_tabular_metadata.py +69 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/csv_helpers.py +12 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/effect_collection.py +7 -2
- {varcode-9.2.1 → varcode-9.2.2}/varcode/structural_variant.py +15 -3
- {varcode-9.2.1 → varcode-9.2.2}/varcode/variant_collection.py +9 -2
- varcode-9.2.2/varcode/version.py +1 -0
- {varcode-9.2.1 → varcode-9.2.2/varcode.egg-info}/PKG-INFO +1 -1
- {varcode-9.2.1 → varcode-9.2.2}/varcode.egg-info/SOURCES.txt +1 -0
- varcode-9.2.1/varcode/version.py +0 -1
- {varcode-9.2.1 → varcode-9.2.2}/LICENSE +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/MANIFEST.in +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/README.md +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/pyproject.toml +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/requirements.txt +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/setup.cfg +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_annotator_divergence_scenarios.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_annotator_parity_adversarial.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_annotators.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_cli_effects.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_cli_genes.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_cli_without_pkg_resources.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_collection_filtering.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_collection_variants_attr_consistency.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_common.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_cosmic_mutations.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_cryptic_exons.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_csv_roundtrip.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_dbnsfp_validation.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_default_structural_helpers.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_effect_annotation_errors.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_effect_candidates.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_effect_classes.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_effect_collection.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_effect_collection_serialization.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_effect_collection_sort_order.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_effect_hypotheses.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_effects_from_mutagenix_variants.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_exacto_fusions.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_exonic_splice_site.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_fast_path.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_frameshift_cterminus_regression.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_frameshift_helpers.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_genome_contig_validation.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_genome_sequence.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_genomic_layout.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_genotype.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_genotype_from_vcf.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_germline_context.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_germline_effects.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_haplotype_effect.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_maf.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_mitochondrial.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_mm10_klf6_frameshift.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_mouse.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_mutant_transcript.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_mutate.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_no_duplicate_variants.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_osteosarc_fusions.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_partial_annotators.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_premature_stop_short_description.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_problematic_variants.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_protein_diff_parity.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_read_phase_resolver.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_real_world_callers.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_reference.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_reference_mismatch_error.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_reference_segments.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_rna_evidence.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_rna_haplotype_sequences.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_rna_read_phasing_source.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_selenocysteine.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_silent_aa_pos.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_silent_hgvs_description.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_splice_graph.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_splice_outcomes.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_splice_site_effects.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_stop_codon_classification_bugs.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_string_helpers.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_structural_variant_annotator.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_structural_variants.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_symbolic_alleles.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_symbolic_sv_padding.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_timings.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_transcript_layout.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_transcript_model.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_transforms_left_align.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_transforms_pair_breakends.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_variant.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_variant_collection.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_vcf.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_vcf_output.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_vcf_parsing.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_vcf_phase_resolver.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/tests/test_vcf_spec_examples.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/__init__.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/annotators/__init__.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/annotators/fast.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/annotators/protein_diff.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/annotators/registry.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/cli/__init__.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/cli/effects_script.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/cli/genes_script.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/cli/logging.conf +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/cli/variant_args.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/cli/version_info.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/common.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/cryptic_exons.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effect_candidates.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effect_hypotheses.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/__init__.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/classify.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/codon_tables.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/common.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/effect_classes.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/effect_helpers.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/effect_ordering.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/effect_prediction.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/effect_prediction_coding.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/effect_prediction_coding_frameshift.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/effect_prediction_coding_in_frame.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/fast_path.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/mutate.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/structural.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/transcript_helpers.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/effects/translate.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/errors.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/exacto.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/genome.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/genome_sequence.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/genomic_layout.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/genotype.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/germline.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/maf.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/mutant_transcript.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/nucleotides.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/phasing.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/realized_effects.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/reference.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/rna_evidence.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/rna_read_phasing.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/splice_graph.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/splice_outcomes.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/string_helpers.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/sv_allele_parser.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/transcript_layout.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/transcript_model.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/transforms/__init__.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/ucsc_reference_names.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/util.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/variant.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/vcf.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/vcf_output.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode/vcf_parsing.py +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode.egg-info/dependency_links.txt +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode.egg-info/entry_points.txt +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode.egg-info/requires.txt +0 -0
- {varcode-9.2.1 → varcode-9.2.2}/varcode.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Structural records must never masquerade as placeholder SNVs (#417)."""
|
|
2
|
+
|
|
3
|
+
import pickle
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from varcode import StructuralVariant, Variant, VariantCollection
|
|
8
|
+
from varcode.csv_helpers import STRUCTURAL_VARIANT_COLUMNS
|
|
9
|
+
from varcode.effects import EffectCollection, Intergenic
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.parametrize("ref", ["A", "C", "G", "T", "N"])
|
|
13
|
+
@pytest.mark.parametrize("kind,alt", [
|
|
14
|
+
("DEL", "<DEL>"), ("DUP", "<DUP>"), ("INV", "<INV>"),
|
|
15
|
+
("CNV", "<CN3>"), ("INS", "<INS:ME:ALU>"),
|
|
16
|
+
("BND", "G[2:200["), ("BND", ".ACGT"), ("INS", "ACGT"),
|
|
17
|
+
])
|
|
18
|
+
def test_actual_alleles_and_no_small_edit_flags(ref, kind, alt):
|
|
19
|
+
sv = StructuralVariant("1", 100, kind, end=200, ref=ref, alt=alt)
|
|
20
|
+
assert sv.start == sv.original_start == 100
|
|
21
|
+
assert sv.ref == sv.original_ref == ref
|
|
22
|
+
assert sv.alt == sv.original_alt == sv.symbolic_alt == alt
|
|
23
|
+
for name in ["is_snv", "is_indel", "is_insertion", "is_deletion",
|
|
24
|
+
"is_transition", "is_transversion"]:
|
|
25
|
+
assert getattr(sv, name) is False
|
|
26
|
+
assert sv.is_structural
|
|
27
|
+
for restored in [StructuralVariant.from_json(sv.to_json()), pickle.loads(pickle.dumps(sv))]:
|
|
28
|
+
assert restored == sv
|
|
29
|
+
assert (restored.ref, restored.alt) == (ref, alt)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def examples():
|
|
33
|
+
snv = Variant("1", 50, "C", "T")
|
|
34
|
+
sv = StructuralVariant("1", 100, "DEL", end=200, ref="T", affected_start=101,
|
|
35
|
+
mate_contig="2", mate_start=300)
|
|
36
|
+
for variant in [snv, sv]:
|
|
37
|
+
variant._gene_names = []
|
|
38
|
+
variant._gene_ids = []
|
|
39
|
+
return snv, sv
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.mark.parametrize("effects", [False, True])
|
|
43
|
+
def test_mixed_tables_retain_structural_coordinates(effects, tmp_path):
|
|
44
|
+
snv, sv = examples()
|
|
45
|
+
collection = (EffectCollection([Intergenic(snv), Intergenic(sv)], sort_key=False)
|
|
46
|
+
if effects else VariantCollection([snv, sv]))
|
|
47
|
+
df = collection.to_dataframe()
|
|
48
|
+
assert list(df.columns) == list(collection._DATAFRAME_COLUMNS + STRUCTURAL_VARIANT_COLUMNS)
|
|
49
|
+
row = df.iloc[1]
|
|
50
|
+
assert (row["ref"], row["alt"], row["sv_type"]) == ("T", "<DEL>", "DEL")
|
|
51
|
+
assert (row["start"], row["end"], row["affected_start"], row["affected_end"]) == (100, 200, 101, 200)
|
|
52
|
+
assert (row["mate_contig"], row["mate_start"]) == ("2", 300)
|
|
53
|
+
if effects:
|
|
54
|
+
assert not row["is_snv"] and not row["is_transition"] and not row["is_transversion"]
|
|
55
|
+
assert df.iloc[0]["is_snv"] and df.iloc[0]["is_transition"]
|
|
56
|
+
path = tmp_path / "mixed.csv"
|
|
57
|
+
collection.to_csv(str(path))
|
|
58
|
+
with pytest.raises(ValueError, match="Structural rows cannot be reconstructed"):
|
|
59
|
+
type(collection).from_csv(str(path))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@pytest.mark.parametrize("effects", [False, True])
|
|
63
|
+
@pytest.mark.parametrize("empty", [False, True])
|
|
64
|
+
def test_point_only_and_empty_schemas_unchanged(effects, empty):
|
|
65
|
+
snv, _ = examples()
|
|
66
|
+
variants = [] if empty else [snv]
|
|
67
|
+
collection = (EffectCollection([Intergenic(v) for v in variants]) if effects
|
|
68
|
+
else VariantCollection(variants))
|
|
69
|
+
assert tuple(collection.to_dataframe().columns) == collection._DATAFRAME_COLUMNS
|
|
@@ -39,6 +39,18 @@ HEADER_PREFIX = "#"
|
|
|
39
39
|
# openvax/varcode#274.
|
|
40
40
|
CONTIG_COLUMN_ALIASES = ("contig", "chr")
|
|
41
41
|
|
|
42
|
+
STRUCTURAL_VARIANT_COLUMNS = (
|
|
43
|
+
"sv_type", "end", "mate_contig", "mate_start", "affected_start", "affected_end",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def reject_structural_csv(df):
|
|
48
|
+
"""CSV summaries do not encode enough state to restore structural effects."""
|
|
49
|
+
if "sv_type" in df and df["sv_type"].fillna("").ne("").any():
|
|
50
|
+
raise ValueError(
|
|
51
|
+
"Structural rows cannot be reconstructed from CSV summaries. "
|
|
52
|
+
"Retain the original VCF/JSON variants and RNA evidence instead.")
|
|
53
|
+
|
|
42
54
|
|
|
43
55
|
def resolve_contig_column(columns):
|
|
44
56
|
"""Return the first of :data:`CONTIG_COLUMN_ALIASES` that appears in
|
|
@@ -17,7 +17,9 @@ from sercol import Collection
|
|
|
17
17
|
|
|
18
18
|
from ..csv_helpers import (
|
|
19
19
|
CONTIG_COLUMN_ALIASES,
|
|
20
|
+
STRUCTURAL_VARIANT_COLUMNS,
|
|
20
21
|
read_metadata_header,
|
|
22
|
+
reject_structural_csv,
|
|
21
23
|
resolve_contig_column,
|
|
22
24
|
warn_on_version_drift,
|
|
23
25
|
write_metadata_header,
|
|
@@ -344,6 +346,8 @@ class EffectCollection(Collection):
|
|
|
344
346
|
|
|
345
347
|
def to_dataframe(self):
|
|
346
348
|
"""Build a dataframe from the effect collection."""
|
|
349
|
+
structural_columns = STRUCTURAL_VARIANT_COLUMNS if any(
|
|
350
|
+
getattr(e.variant, "is_structural", False) for e in self) else ()
|
|
347
351
|
# list of properties to extract from Variant objects if they're
|
|
348
352
|
# not None
|
|
349
353
|
variant_properties = [
|
|
@@ -354,7 +358,7 @@ class EffectCollection(Collection):
|
|
|
354
358
|
"is_snv",
|
|
355
359
|
"is_transversion",
|
|
356
360
|
"is_transition"
|
|
357
|
-
]
|
|
361
|
+
] + list(structural_columns)
|
|
358
362
|
|
|
359
363
|
def row_from_effect(effect):
|
|
360
364
|
row = OrderedDict()
|
|
@@ -375,7 +379,7 @@ class EffectCollection(Collection):
|
|
|
375
379
|
# CSV round-trip doesn't have to special-case len == 0.
|
|
376
380
|
return pd.DataFrame.from_records(
|
|
377
381
|
[row_from_effect(effect) for effect in self],
|
|
378
|
-
columns=self._DATAFRAME_COLUMNS,
|
|
382
|
+
columns=self._DATAFRAME_COLUMNS + structural_columns,
|
|
379
383
|
)
|
|
380
384
|
|
|
381
385
|
def to_csv(self, path, include_header=True):
|
|
@@ -485,6 +489,7 @@ class EffectCollection(Collection):
|
|
|
485
489
|
# dtype is a no-op for whichever column is absent.
|
|
486
490
|
df = pd.read_csv(
|
|
487
491
|
path, comment="#", dtype={"chr": str, "contig": str})
|
|
492
|
+
reject_structural_csv(df)
|
|
488
493
|
contig_col = resolve_contig_column(df.columns)
|
|
489
494
|
if contig_col is None:
|
|
490
495
|
raise ValueError(
|
|
@@ -242,6 +242,15 @@ class StructuralVariant(Variant):
|
|
|
242
242
|
event coordinates include a retained padding base.
|
|
243
243
|
"""
|
|
244
244
|
|
|
245
|
+
# These flags describe literal small edits, not event classes. Consumers
|
|
246
|
+
# must use is_structural/sv_type instead of interpreting symbolic alleles.
|
|
247
|
+
is_snv = False
|
|
248
|
+
is_indel = False
|
|
249
|
+
is_insertion = False
|
|
250
|
+
is_deletion = False
|
|
251
|
+
is_transition = False
|
|
252
|
+
is_transversion = False
|
|
253
|
+
|
|
245
254
|
__slots__ = (
|
|
246
255
|
"sv_type",
|
|
247
256
|
"mate_contig",
|
|
@@ -288,14 +297,14 @@ class StructuralVariant(Variant):
|
|
|
288
297
|
|
|
289
298
|
# Initialize the base Variant with a placeholder ref/alt so the
|
|
290
299
|
# nucleotide-normalization path doesn't reject <DEL>-style
|
|
291
|
-
# symbolic alleles.
|
|
292
|
-
#
|
|
300
|
+
# symbolic alleles. Restore the actual record fields below; placeholder
|
|
301
|
+
# normalization must not leak into public alleles or exports (#417).
|
|
293
302
|
Variant.__init__(
|
|
294
303
|
self,
|
|
295
304
|
contig=contig,
|
|
296
305
|
start=start,
|
|
297
306
|
ref=ref if ref else "N",
|
|
298
|
-
alt="A"
|
|
307
|
+
alt="A",
|
|
299
308
|
genome=genome,
|
|
300
309
|
ensembl=ensembl,
|
|
301
310
|
allow_extended_nucleotides=True,
|
|
@@ -325,6 +334,9 @@ class StructuralVariant(Variant):
|
|
|
325
334
|
# Preserve the original symbolic ALT string so round-tripping
|
|
326
335
|
# and downstream consumers see what the VCF said.
|
|
327
336
|
self._sv_alt = alt if alt is not None else "<%s>" % sv_type
|
|
337
|
+
self.ref = self.original_ref
|
|
338
|
+
self.alt = self.original_alt = self._sv_alt
|
|
339
|
+
self.start = self.original_start = int(start)
|
|
328
340
|
|
|
329
341
|
# Caches, like Variant's overlapping-gene / transcript caches:
|
|
330
342
|
# the junction list derived from the fields above, and results
|
|
@@ -19,7 +19,9 @@ from .effects import EffectCollection
|
|
|
19
19
|
from .common import memoize
|
|
20
20
|
from .csv_helpers import (
|
|
21
21
|
CONTIG_COLUMN_ALIASES,
|
|
22
|
+
STRUCTURAL_VARIANT_COLUMNS,
|
|
22
23
|
read_metadata_header,
|
|
24
|
+
reject_structural_csv,
|
|
23
25
|
resolve_contig_column,
|
|
24
26
|
warn_on_version_drift,
|
|
25
27
|
write_metadata_header,
|
|
@@ -434,8 +436,10 @@ class VariantCollection(Collection):
|
|
|
434
436
|
|
|
435
437
|
def to_dataframe(self):
|
|
436
438
|
"""Build a DataFrame from this variant collection."""
|
|
439
|
+
structural_columns = STRUCTURAL_VARIANT_COLUMNS if any(
|
|
440
|
+
getattr(v, "is_structural", False) for v in self) else ()
|
|
437
441
|
def row_from_variant(variant):
|
|
438
|
-
|
|
442
|
+
row = OrderedDict([
|
|
439
443
|
("chr", variant.contig),
|
|
440
444
|
("start", variant.original_start),
|
|
441
445
|
("ref", variant.original_ref),
|
|
@@ -443,11 +447,13 @@ class VariantCollection(Collection):
|
|
|
443
447
|
("gene_name", ";".join(variant.gene_names)),
|
|
444
448
|
("gene_id", ";".join(variant.gene_ids))
|
|
445
449
|
])
|
|
450
|
+
row.update((name, getattr(variant, name, None)) for name in structural_columns)
|
|
451
|
+
return row
|
|
446
452
|
rows = [row_from_variant(v) for v in self]
|
|
447
453
|
# Always return a DataFrame with the expected columns, even
|
|
448
454
|
# when empty, so downstream code (CSV round-trip, joins) doesn't
|
|
449
455
|
# have to special-case len == 0.
|
|
450
|
-
return pd.DataFrame.from_records(rows, columns=self._DATAFRAME_COLUMNS)
|
|
456
|
+
return pd.DataFrame.from_records(rows, columns=self._DATAFRAME_COLUMNS + structural_columns)
|
|
451
457
|
|
|
452
458
|
def to_csv(self, path, include_header=True):
|
|
453
459
|
"""Write this collection to CSV.
|
|
@@ -541,6 +547,7 @@ class VariantCollection(Collection):
|
|
|
541
547
|
# dtype is a no-op for whichever column is absent.
|
|
542
548
|
df = pd.read_csv(
|
|
543
549
|
path, comment="#", dtype={"chr": str, "contig": str})
|
|
550
|
+
reject_structural_csv(df)
|
|
544
551
|
contig_col = resolve_contig_column(df.columns)
|
|
545
552
|
if contig_col is None:
|
|
546
553
|
raise ValueError(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "9.2.2"
|
|
@@ -68,6 +68,7 @@ tests/test_stop_codon_classification_bugs.py
|
|
|
68
68
|
tests/test_string_helpers.py
|
|
69
69
|
tests/test_structural_variant_annotator.py
|
|
70
70
|
tests/test_structural_variants.py
|
|
71
|
+
tests/test_sv_tabular_metadata.py
|
|
71
72
|
tests/test_symbolic_alleles.py
|
|
72
73
|
tests/test_symbolic_sv_padding.py
|
|
73
74
|
tests/test_timings.py
|
varcode-9.2.1/varcode/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "9.2.1"
|
|
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
|
|
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
|
|
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
|
|
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
|