varcode 9.2.3__tar.gz → 9.2.4__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 (160) hide show
  1. {varcode-9.2.3/varcode.egg-info → varcode-9.2.4}/PKG-INFO +1 -1
  2. varcode-9.2.4/tests/test_bnd_retained_segments.py +111 -0
  3. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/structural.py +15 -9
  4. {varcode-9.2.3 → varcode-9.2.4}/varcode/mutant_transcript.py +4 -1
  5. {varcode-9.2.3 → varcode-9.2.4}/varcode/sv_allele_parser.py +11 -0
  6. varcode-9.2.4/varcode/version.py +1 -0
  7. {varcode-9.2.3 → varcode-9.2.4/varcode.egg-info}/PKG-INFO +1 -1
  8. {varcode-9.2.3 → varcode-9.2.4}/varcode.egg-info/SOURCES.txt +1 -0
  9. varcode-9.2.3/varcode/version.py +0 -1
  10. {varcode-9.2.3 → varcode-9.2.4}/LICENSE +0 -0
  11. {varcode-9.2.3 → varcode-9.2.4}/MANIFEST.in +0 -0
  12. {varcode-9.2.3 → varcode-9.2.4}/README.md +0 -0
  13. {varcode-9.2.3 → varcode-9.2.4}/pyproject.toml +0 -0
  14. {varcode-9.2.3 → varcode-9.2.4}/requirements.txt +0 -0
  15. {varcode-9.2.3 → varcode-9.2.4}/setup.cfg +0 -0
  16. {varcode-9.2.3 → varcode-9.2.4}/tests/test_annotator_divergence_scenarios.py +0 -0
  17. {varcode-9.2.3 → varcode-9.2.4}/tests/test_annotator_parity_adversarial.py +0 -0
  18. {varcode-9.2.3 → varcode-9.2.4}/tests/test_annotators.py +0 -0
  19. {varcode-9.2.3 → varcode-9.2.4}/tests/test_cli_effects.py +0 -0
  20. {varcode-9.2.3 → varcode-9.2.4}/tests/test_cli_genes.py +0 -0
  21. {varcode-9.2.3 → varcode-9.2.4}/tests/test_cli_without_pkg_resources.py +0 -0
  22. {varcode-9.2.3 → varcode-9.2.4}/tests/test_collection_filtering.py +0 -0
  23. {varcode-9.2.3 → varcode-9.2.4}/tests/test_collection_variants_attr_consistency.py +0 -0
  24. {varcode-9.2.3 → varcode-9.2.4}/tests/test_common.py +0 -0
  25. {varcode-9.2.3 → varcode-9.2.4}/tests/test_cosmic_mutations.py +0 -0
  26. {varcode-9.2.3 → varcode-9.2.4}/tests/test_cryptic_exons.py +0 -0
  27. {varcode-9.2.3 → varcode-9.2.4}/tests/test_csv_roundtrip.py +0 -0
  28. {varcode-9.2.3 → varcode-9.2.4}/tests/test_dbnsfp_validation.py +0 -0
  29. {varcode-9.2.3 → varcode-9.2.4}/tests/test_default_structural_helpers.py +0 -0
  30. {varcode-9.2.3 → varcode-9.2.4}/tests/test_effect_annotation_errors.py +0 -0
  31. {varcode-9.2.3 → varcode-9.2.4}/tests/test_effect_candidates.py +0 -0
  32. {varcode-9.2.3 → varcode-9.2.4}/tests/test_effect_classes.py +0 -0
  33. {varcode-9.2.3 → varcode-9.2.4}/tests/test_effect_collection.py +0 -0
  34. {varcode-9.2.3 → varcode-9.2.4}/tests/test_effect_collection_serialization.py +0 -0
  35. {varcode-9.2.3 → varcode-9.2.4}/tests/test_effect_collection_sort_order.py +0 -0
  36. {varcode-9.2.3 → varcode-9.2.4}/tests/test_effect_hypotheses.py +0 -0
  37. {varcode-9.2.3 → varcode-9.2.4}/tests/test_effects_from_mutagenix_variants.py +0 -0
  38. {varcode-9.2.3 → varcode-9.2.4}/tests/test_exacto_fusions.py +0 -0
  39. {varcode-9.2.3 → varcode-9.2.4}/tests/test_exonic_splice_site.py +0 -0
  40. {varcode-9.2.3 → varcode-9.2.4}/tests/test_fast_path.py +0 -0
  41. {varcode-9.2.3 → varcode-9.2.4}/tests/test_frameshift_cterminus_regression.py +0 -0
  42. {varcode-9.2.3 → varcode-9.2.4}/tests/test_frameshift_helpers.py +0 -0
  43. {varcode-9.2.3 → varcode-9.2.4}/tests/test_genome_contig_validation.py +0 -0
  44. {varcode-9.2.3 → varcode-9.2.4}/tests/test_genome_sequence.py +0 -0
  45. {varcode-9.2.3 → varcode-9.2.4}/tests/test_genomic_layout.py +0 -0
  46. {varcode-9.2.3 → varcode-9.2.4}/tests/test_genotype.py +0 -0
  47. {varcode-9.2.3 → varcode-9.2.4}/tests/test_genotype_from_vcf.py +0 -0
  48. {varcode-9.2.3 → varcode-9.2.4}/tests/test_germline_context.py +0 -0
  49. {varcode-9.2.3 → varcode-9.2.4}/tests/test_germline_effects.py +0 -0
  50. {varcode-9.2.3 → varcode-9.2.4}/tests/test_haplotype_effect.py +0 -0
  51. {varcode-9.2.3 → varcode-9.2.4}/tests/test_maf.py +0 -0
  52. {varcode-9.2.3 → varcode-9.2.4}/tests/test_mitochondrial.py +0 -0
  53. {varcode-9.2.3 → varcode-9.2.4}/tests/test_mm10_klf6_frameshift.py +0 -0
  54. {varcode-9.2.3 → varcode-9.2.4}/tests/test_mouse.py +0 -0
  55. {varcode-9.2.3 → varcode-9.2.4}/tests/test_mutant_transcript.py +0 -0
  56. {varcode-9.2.3 → varcode-9.2.4}/tests/test_mutate.py +0 -0
  57. {varcode-9.2.3 → varcode-9.2.4}/tests/test_no_duplicate_variants.py +0 -0
  58. {varcode-9.2.3 → varcode-9.2.4}/tests/test_nonlocal_sv_transcripts.py +0 -0
  59. {varcode-9.2.3 → varcode-9.2.4}/tests/test_osteosarc_fusions.py +0 -0
  60. {varcode-9.2.3 → varcode-9.2.4}/tests/test_partial_annotators.py +0 -0
  61. {varcode-9.2.3 → varcode-9.2.4}/tests/test_premature_stop_short_description.py +0 -0
  62. {varcode-9.2.3 → varcode-9.2.4}/tests/test_problematic_variants.py +0 -0
  63. {varcode-9.2.3 → varcode-9.2.4}/tests/test_protein_diff_parity.py +0 -0
  64. {varcode-9.2.3 → varcode-9.2.4}/tests/test_read_phase_resolver.py +0 -0
  65. {varcode-9.2.3 → varcode-9.2.4}/tests/test_real_world_callers.py +0 -0
  66. {varcode-9.2.3 → varcode-9.2.4}/tests/test_reference.py +0 -0
  67. {varcode-9.2.3 → varcode-9.2.4}/tests/test_reference_mismatch_error.py +0 -0
  68. {varcode-9.2.3 → varcode-9.2.4}/tests/test_reference_segments.py +0 -0
  69. {varcode-9.2.3 → varcode-9.2.4}/tests/test_rna_evidence.py +0 -0
  70. {varcode-9.2.3 → varcode-9.2.4}/tests/test_rna_haplotype_sequences.py +0 -0
  71. {varcode-9.2.3 → varcode-9.2.4}/tests/test_rna_read_phasing_source.py +0 -0
  72. {varcode-9.2.3 → varcode-9.2.4}/tests/test_selenocysteine.py +0 -0
  73. {varcode-9.2.3 → varcode-9.2.4}/tests/test_silent_aa_pos.py +0 -0
  74. {varcode-9.2.3 → varcode-9.2.4}/tests/test_silent_hgvs_description.py +0 -0
  75. {varcode-9.2.3 → varcode-9.2.4}/tests/test_splice_graph.py +0 -0
  76. {varcode-9.2.3 → varcode-9.2.4}/tests/test_splice_outcomes.py +0 -0
  77. {varcode-9.2.3 → varcode-9.2.4}/tests/test_splice_site_effects.py +0 -0
  78. {varcode-9.2.3 → varcode-9.2.4}/tests/test_stop_codon_classification_bugs.py +0 -0
  79. {varcode-9.2.3 → varcode-9.2.4}/tests/test_string_helpers.py +0 -0
  80. {varcode-9.2.3 → varcode-9.2.4}/tests/test_structural_variant_annotator.py +0 -0
  81. {varcode-9.2.3 → varcode-9.2.4}/tests/test_structural_variants.py +0 -0
  82. {varcode-9.2.3 → varcode-9.2.4}/tests/test_sv_tabular_metadata.py +0 -0
  83. {varcode-9.2.3 → varcode-9.2.4}/tests/test_symbolic_alleles.py +0 -0
  84. {varcode-9.2.3 → varcode-9.2.4}/tests/test_symbolic_sv_padding.py +0 -0
  85. {varcode-9.2.3 → varcode-9.2.4}/tests/test_timings.py +0 -0
  86. {varcode-9.2.3 → varcode-9.2.4}/tests/test_transcript_layout.py +0 -0
  87. {varcode-9.2.3 → varcode-9.2.4}/tests/test_transcript_model.py +0 -0
  88. {varcode-9.2.3 → varcode-9.2.4}/tests/test_transforms_left_align.py +0 -0
  89. {varcode-9.2.3 → varcode-9.2.4}/tests/test_transforms_pair_breakends.py +0 -0
  90. {varcode-9.2.3 → varcode-9.2.4}/tests/test_variant.py +0 -0
  91. {varcode-9.2.3 → varcode-9.2.4}/tests/test_variant_collection.py +0 -0
  92. {varcode-9.2.3 → varcode-9.2.4}/tests/test_vcf.py +0 -0
  93. {varcode-9.2.3 → varcode-9.2.4}/tests/test_vcf_output.py +0 -0
  94. {varcode-9.2.3 → varcode-9.2.4}/tests/test_vcf_parsing.py +0 -0
  95. {varcode-9.2.3 → varcode-9.2.4}/tests/test_vcf_phase_resolver.py +0 -0
  96. {varcode-9.2.3 → varcode-9.2.4}/tests/test_vcf_spec_examples.py +0 -0
  97. {varcode-9.2.3 → varcode-9.2.4}/varcode/__init__.py +0 -0
  98. {varcode-9.2.3 → varcode-9.2.4}/varcode/annotators/__init__.py +0 -0
  99. {varcode-9.2.3 → varcode-9.2.4}/varcode/annotators/fast.py +0 -0
  100. {varcode-9.2.3 → varcode-9.2.4}/varcode/annotators/protein_diff.py +0 -0
  101. {varcode-9.2.3 → varcode-9.2.4}/varcode/annotators/registry.py +0 -0
  102. {varcode-9.2.3 → varcode-9.2.4}/varcode/cli/__init__.py +0 -0
  103. {varcode-9.2.3 → varcode-9.2.4}/varcode/cli/effects_script.py +0 -0
  104. {varcode-9.2.3 → varcode-9.2.4}/varcode/cli/genes_script.py +0 -0
  105. {varcode-9.2.3 → varcode-9.2.4}/varcode/cli/logging.conf +0 -0
  106. {varcode-9.2.3 → varcode-9.2.4}/varcode/cli/variant_args.py +0 -0
  107. {varcode-9.2.3 → varcode-9.2.4}/varcode/cli/version_info.py +0 -0
  108. {varcode-9.2.3 → varcode-9.2.4}/varcode/common.py +0 -0
  109. {varcode-9.2.3 → varcode-9.2.4}/varcode/cryptic_exons.py +0 -0
  110. {varcode-9.2.3 → varcode-9.2.4}/varcode/csv_helpers.py +0 -0
  111. {varcode-9.2.3 → varcode-9.2.4}/varcode/effect_candidates.py +0 -0
  112. {varcode-9.2.3 → varcode-9.2.4}/varcode/effect_hypotheses.py +0 -0
  113. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/__init__.py +0 -0
  114. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/classify.py +0 -0
  115. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/codon_tables.py +0 -0
  116. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/common.py +0 -0
  117. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/effect_classes.py +0 -0
  118. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/effect_collection.py +0 -0
  119. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/effect_helpers.py +0 -0
  120. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/effect_ordering.py +0 -0
  121. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/effect_prediction.py +0 -0
  122. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/effect_prediction_coding.py +0 -0
  123. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/effect_prediction_coding_frameshift.py +0 -0
  124. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/effect_prediction_coding_in_frame.py +0 -0
  125. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/fast_path.py +0 -0
  126. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/mutate.py +0 -0
  127. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/transcript_helpers.py +0 -0
  128. {varcode-9.2.3 → varcode-9.2.4}/varcode/effects/translate.py +0 -0
  129. {varcode-9.2.3 → varcode-9.2.4}/varcode/errors.py +0 -0
  130. {varcode-9.2.3 → varcode-9.2.4}/varcode/exacto.py +0 -0
  131. {varcode-9.2.3 → varcode-9.2.4}/varcode/genome.py +0 -0
  132. {varcode-9.2.3 → varcode-9.2.4}/varcode/genome_sequence.py +0 -0
  133. {varcode-9.2.3 → varcode-9.2.4}/varcode/genomic_layout.py +0 -0
  134. {varcode-9.2.3 → varcode-9.2.4}/varcode/genotype.py +0 -0
  135. {varcode-9.2.3 → varcode-9.2.4}/varcode/germline.py +0 -0
  136. {varcode-9.2.3 → varcode-9.2.4}/varcode/maf.py +0 -0
  137. {varcode-9.2.3 → varcode-9.2.4}/varcode/nucleotides.py +0 -0
  138. {varcode-9.2.3 → varcode-9.2.4}/varcode/phasing.py +0 -0
  139. {varcode-9.2.3 → varcode-9.2.4}/varcode/realized_effects.py +0 -0
  140. {varcode-9.2.3 → varcode-9.2.4}/varcode/reference.py +0 -0
  141. {varcode-9.2.3 → varcode-9.2.4}/varcode/rna_evidence.py +0 -0
  142. {varcode-9.2.3 → varcode-9.2.4}/varcode/rna_read_phasing.py +0 -0
  143. {varcode-9.2.3 → varcode-9.2.4}/varcode/splice_graph.py +0 -0
  144. {varcode-9.2.3 → varcode-9.2.4}/varcode/splice_outcomes.py +0 -0
  145. {varcode-9.2.3 → varcode-9.2.4}/varcode/string_helpers.py +0 -0
  146. {varcode-9.2.3 → varcode-9.2.4}/varcode/structural_variant.py +0 -0
  147. {varcode-9.2.3 → varcode-9.2.4}/varcode/transcript_layout.py +0 -0
  148. {varcode-9.2.3 → varcode-9.2.4}/varcode/transcript_model.py +0 -0
  149. {varcode-9.2.3 → varcode-9.2.4}/varcode/transforms/__init__.py +0 -0
  150. {varcode-9.2.3 → varcode-9.2.4}/varcode/ucsc_reference_names.py +0 -0
  151. {varcode-9.2.3 → varcode-9.2.4}/varcode/util.py +0 -0
  152. {varcode-9.2.3 → varcode-9.2.4}/varcode/variant.py +0 -0
  153. {varcode-9.2.3 → varcode-9.2.4}/varcode/variant_collection.py +0 -0
  154. {varcode-9.2.3 → varcode-9.2.4}/varcode/vcf.py +0 -0
  155. {varcode-9.2.3 → varcode-9.2.4}/varcode/vcf_output.py +0 -0
  156. {varcode-9.2.3 → varcode-9.2.4}/varcode/vcf_parsing.py +0 -0
  157. {varcode-9.2.3 → varcode-9.2.4}/varcode.egg-info/dependency_links.txt +0 -0
  158. {varcode-9.2.3 → varcode-9.2.4}/varcode.egg-info/entry_points.txt +0 -0
  159. {varcode-9.2.3 → varcode-9.2.4}/varcode.egg-info/requires.txt +0 -0
  160. {varcode-9.2.3 → varcode-9.2.4}/varcode.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: varcode
3
- Version: 9.2.3
3
+ Version: 9.2.4
4
4
  Summary: Variant annotation in Python
5
5
  Author-email: Alex Rubinsteyn <alex.rubinsteyn@unc.edu>
6
6
  Project-URL: Homepage, https://github.com/openvax/varcode
@@ -0,0 +1,111 @@
1
+ """A BND fallback describes only its retained reference fragment (#447)."""
2
+
3
+ import pytest
4
+ from pyensembl import cached_release
5
+
6
+ from varcode import StructuralVariant, parse_symbolic_alt
7
+ from varcode.effects import TranslocationToIntergenic
8
+ from varcode.effects.structural import _build_translocation_mutant_transcript
9
+
10
+
11
+ @pytest.fixture(params=["ENST00000003084", "ENST00000357654"])
12
+ def transcript(request):
13
+ return cached_release(81).transcript_by_id(request.param)
14
+
15
+
16
+ def expected_offsets(transcript, position, side):
17
+ """Independent per-base oracle in transcript order, including the anchor."""
18
+ positions = [p for exon in transcript.exons
19
+ for p in (range(exon.start, exon.end + 1) if transcript.strand == "+"
20
+ else range(exon.end, exon.start - 1, -1))]
21
+ kept = [i for i, p in enumerate(positions)
22
+ if (p <= position if side == "left" else p >= position)]
23
+ return min(kept), max(kept) + 1
24
+
25
+
26
+ @pytest.mark.parametrize("alt,side", [
27
+ ("N[22:15500000[", "left"), ("N]22:15500000]", "left"),
28
+ ("[22:15500000[N", "right"), ("]22:15500000]N", "right"),
29
+ ("ACGT.", "left"), (".ACGT", "right"),
30
+ ])
31
+ @pytest.mark.parametrize("location", ["exonic", "exon_start", "exon_end", "intronic"])
32
+ def test_both_strands_and_local_sides(transcript, alt, side, location):
33
+ # An interior exon also permits meaningful suffix/prefix comparisons.
34
+ exon = transcript.exons[2]
35
+ if location == "exonic":
36
+ position = (exon.start + exon.end) // 2
37
+ elif location == "exon_start":
38
+ position = exon.start
39
+ elif location == "exon_end":
40
+ position = exon.end
41
+ else:
42
+ other = transcript.exons[3]
43
+ position = ((exon.end + other.start) // 2 if transcript.strand == "+"
44
+ else (other.end + exon.start) // 2)
45
+ sv = parse_symbolic_alt(transcript.contig, position, "N", alt,
46
+ genome=transcript.genome)
47
+ effect = sv.effect_on_transcript(transcript)
48
+ assert isinstance(effect, TranslocationToIntergenic)
49
+ mt = effect.mutant_transcript
50
+ assert mt is not None
51
+ (segment,) = mt.reference_segments
52
+ assert segment.source is transcript
53
+ assert (segment.start, segment.end) == expected_offsets(transcript, position, side)
54
+ assert segment.strand == "+" # source is already oriented transcript cDNA
55
+ five_prime = (side == "left") == (transcript.strand == "+")
56
+ assert segment.label == ("translocation_5p" if five_prime else "translocation_3p")
57
+ assert segment.length < len(transcript.sequence)
58
+ assert mt.cdna_sequence is None
59
+ assert mt.mutant_protein_sequence is None
60
+ assert mt.evidence["sequence_status"] == "retained_reference_fragment"
61
+
62
+
63
+ def test_cftr_regression_keeps_51_bases_not_entire_transcript():
64
+ tx = cached_release(81).transcript_by_id("ENST00000003084")
65
+ sv = parse_symbolic_alt("7", tx.exons[0].start + 50, "N", "N]22:15500000]",
66
+ genome=tx.genome)
67
+ mt = sv.effect_on_transcript(tx).mutant_transcript
68
+ (segment,) = mt.reference_segments
69
+ assert (segment.start, segment.end) == (0, 51)
70
+ assert segment.source.sequence[segment.start:segment.end] == tx.sequence[:51]
71
+
72
+
73
+ @pytest.mark.parametrize("alt", [None, "<BND>", "N[?:?[", "N[22:15500000]", ".", "N.N"])
74
+ def test_unknown_local_orientation_is_unresolved(transcript, alt):
75
+ sv = StructuralVariant(transcript.contig, transcript.exons[0].start + 5,
76
+ "BND", alt=alt, genome=transcript.genome)
77
+ assert sv.effect_on_transcript(transcript).mutant_transcript is None
78
+
79
+
80
+ @pytest.mark.parametrize("orientation", ["[[", "]]"])
81
+ def test_mate_orientation_does_not_determine_local_side(transcript, orientation):
82
+ sv = StructuralVariant(transcript.contig, transcript.exons[0].start + 5,
83
+ "BND", mate_contig="22", mate_start=15_500_000,
84
+ mate_orientation=orientation, genome=transcript.genome)
85
+ with pytest.warns(UserWarning, match="can't read the breakend orientation"):
86
+ effect = sv.effect_on_transcript(transcript)
87
+ assert isinstance(effect, TranslocationToIntergenic)
88
+ assert effect.mutant_transcript is None
89
+
90
+
91
+ @pytest.mark.parametrize("location", ["before", "after", "wrong_contig"])
92
+ def test_unrelated_transcript_does_not_supply_a_segment(transcript, location):
93
+ position = {"before": transcript.start - 1, "after": transcript.end + 1,
94
+ "wrong_contig": transcript.start + 5}[location]
95
+ contig = "1" if location == "wrong_contig" else transcript.contig
96
+ sv = StructuralVariant(contig, position, "BND", alt="N.", genome=transcript.genome)
97
+ assert _build_translocation_mutant_transcript(sv, transcript) is None
98
+
99
+
100
+ @pytest.mark.parametrize("alt", ["N]22:15500000]", "]22:15500000]N", "N.", ".N", "<BND>"])
101
+ def test_supplied_assembly_is_unchanged(transcript, alt):
102
+ assembly = "ATGGCTTAA"
103
+ sv = StructuralVariant(transcript.contig, transcript.exons[0].start + 5,
104
+ "BND", alt=alt, alt_assembly=assembly, genome=transcript.genome)
105
+ mt = sv.effect_on_transcript(transcript).mutant_transcript
106
+ assert mt.cdna_sequence == assembly
107
+ assert mt.mutant_protein_sequence is None
108
+ assert mt.evidence == {"source": "alt_assembly"}
109
+ (segment,) = mt.reference_segments
110
+ assert segment.source.sequence == assembly
111
+ assert (segment.start, segment.end, segment.label) == (0, len(assembly), "alt_assembly")
@@ -35,7 +35,7 @@ from .effect_helpers import exon_length
35
35
  from ..mutant_transcript import MutantTranscript, ReferenceSegment
36
36
  # Existing assembled-SV pickles use this private module path.
37
37
  from ..mutant_transcript import _AssembledAllele # noqa: F401
38
- from ..sv_allele_parser import breakend_sides
38
+ from ..sv_allele_parser import breakend_sides, _breakend_local_side
39
39
 
40
40
 
41
41
  # --------------------------------------------------------------------
@@ -501,23 +501,29 @@ def _build_fusion_mutant_transcript(
501
501
 
502
502
 
503
503
  def _build_translocation_mutant_transcript(variant, transcript):
504
- """Build a :class:`MutantTranscript` for a BND classified as
505
- :class:`TranslocationToIntergenic`.
504
+ """Describe only the retained local reference fragment of a BND.
506
505
 
507
- One segment covering the (this-side) transcript up to the
508
- breakpoint. Intergenic space beyond the breakpoint isn't
509
- representable as a transcript source; #338 and #341 extend this
510
- with caller-supplied genomic intervals / long-read assemblies.
506
+ The other side and full mutant cDNA/protein remain unknown. Without
507
+ local orientation or a breakpoint on this transcript, no fragment can
508
+ be established. Supplied assemblies are handled by the caller.
511
509
  """
510
+ side = _breakend_local_side(variant.symbolic_alt)
511
+ if (side is None or str(variant.contig) != str(transcript.contig)
512
+ or not transcript.start <= variant.start <= transcript.end):
513
+ return None
514
+ keep_five_prime = _retains_five_prime_end(transcript, side)
515
+ cut = _cdna_cut(transcript, variant.start, keep_five_prime)
512
516
  full_len = len(str(transcript.sequence))
517
+ start, end = (0, cut) if keep_five_prime else (cut, full_len)
513
518
  segments = (
514
519
  ReferenceSegment(
515
- source=transcript, start=0, end=full_len,
516
- strand="+", label="translocation_5p"),)
520
+ source=transcript, start=start, end=end, strand="+",
521
+ label="translocation_5p" if keep_five_prime else "translocation_3p"),)
517
522
  return MutantTranscript(
518
523
  reference_transcript=transcript,
519
524
  reference_segments=segments,
520
525
  cdna_sequence=None,
526
+ evidence={"sequence_status": "retained_reference_fragment"},
521
527
  annotator_name="structural_variant")
522
528
 
523
529
 
@@ -232,7 +232,10 @@ class MutantTranscript(DataclassSerializable):
232
232
  strand segments), produce the mutant cDNA. ``None`` for the
233
233
  point-variant shape; a fusion's segments would be
234
234
  ``(5p_partner_segment, 3p_partner_segment)``. Coordinates are
235
- in each segment's own reference system."""
235
+ in each segment's own reference system. A partial structural model may
236
+ describe only a retained reference fragment: its producer identifies this
237
+ in ``evidence`` and leaves the full ``cdna_sequence`` unknown. Concatenating
238
+ those partial segments does not establish a full allele."""
236
239
 
237
240
  cdna_sequence: Optional[str] = None
238
241
  """The mutated spliced mRNA, when computed. ``None`` if the
@@ -78,6 +78,17 @@ def breakend_sides(alt):
78
78
  return this_side, mate_side
79
79
 
80
80
 
81
+ def _breakend_local_side(alt):
82
+ """The retained local side, including single breakends with no mate."""
83
+ sides = breakend_sides(alt)
84
+ if sides is not None:
85
+ return sides[0]
86
+ single = _SINGLE_BREAKEND_RE.match(alt or "")
87
+ if single is not None:
88
+ return "right" if single.group("joined_before") else "left"
89
+ return None
90
+
91
+
81
92
  def _extract_info(info, key):
82
93
  """Pull an INFO field value, handling list-of-ints from CIPOS /
83
94
  CIEND and plain ints/strings otherwise. Returns ``None`` if
@@ -0,0 +1 @@
1
+ __version__ = "9.2.4"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: varcode
3
- Version: 9.2.3
3
+ Version: 9.2.4
4
4
  Summary: Variant annotation in Python
5
5
  Author-email: Alex Rubinsteyn <alex.rubinsteyn@unc.edu>
6
6
  Project-URL: Homepage, https://github.com/openvax/varcode
@@ -6,6 +6,7 @@ requirements.txt
6
6
  tests/test_annotator_divergence_scenarios.py
7
7
  tests/test_annotator_parity_adversarial.py
8
8
  tests/test_annotators.py
9
+ tests/test_bnd_retained_segments.py
9
10
  tests/test_cli_effects.py
10
11
  tests/test_cli_genes.py
11
12
  tests/test_cli_without_pkg_resources.py
@@ -1 +0,0 @@
1
- __version__ = "9.2.3"
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