Skip to content

Commit

Permalink
issue #1054 - misc liftover issues
Browse files Browse the repository at this point in the history
  • Loading branch information
davmlaw committed May 8, 2024
1 parent 6d55acc commit 9b9fa43
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 6 deletions.
3 changes: 2 additions & 1 deletion snpdb/bcftools_liftover.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ def bcftools_liftover(source_vcf: str, source_genome_build: GenomeBuild,
source_fasta_filename = source_vep_config["fasta"]
dest_fasta_filename = dest_vep_config["fasta"]

chain_filename = source_vep_config["liftover"].get(out_genome_build.name)
annotation_build_config = settings.ANNOTATION[source_genome_build.name]
chain_filename = annotation_build_config["liftover"].get(out_genome_build.name)
required_files = {
"source_fasta_filename": source_fasta_filename,
"dest_fasta_filename": dest_fasta_filename,
Expand Down
15 changes: 15 additions & 0 deletions snpdb/grids.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,21 @@ def get_initial_queryset(self) -> QuerySet[AlleleLiftover]:


class AlleleLiftoverFailureColumns(AbstractAlleleLiftoverColumns):
def __init__(self, request):
super().__init__(request)
ct_column = RichColumn(key="liftover__conversion_tool",
label="Conversion Tool", renderer=self.render_conversion_tool,
orderable=True)
self.rich_columns.insert(1, ct_column)

def render_conversion_tool(self, row: dict[str, Any]) -> JsonDataType:
label = ""
if status := row['liftover__conversion_tool']:
conversion_tool = AlleleConversionTool(status)
label = conversion_tool.label
return label


def get_initial_queryset(self) -> QuerySet[AlleleLiftover]:
genome_build_name = self.get_query_param("genome_build_name")
if genome_build_name is None:
Expand Down
1 change: 0 additions & 1 deletion snpdb/liftover.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from functools import reduce
from typing import Any, Union, Iterable

from django.conf import settings
from django.contrib.auth.models import User
from django.db.models.query_utils import Q

Expand Down
1 change: 1 addition & 0 deletions snpdb/migrations/0131_download_liftover_chain_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def _test_has_missing_37_to_38_chain_file(apps):
def _test_has_missing_38_to_37_chain_file(apps):
return not os.path.exists(LIFTOVER_38_TO_37)


class Migration(migrations.Migration):

dependencies = [
Expand Down
6 changes: 5 additions & 1 deletion snpdb/models/models_variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ def can_attempt_liftover(self, genome_build) -> bool:

return False


def merge(self, allele_linking_tool, other_allele: "Allele") -> bool:
""" Merge other_allele into this allele """

Expand Down Expand Up @@ -281,6 +280,11 @@ def merge(self, allele_linking_tool, other_allele: "Allele") -> bool:
def build_names(self) -> str:
return ", ".join(sorted(self.variantallele_set.values_list("genome_build__name", flat=True)))

@staticmethod
def missing_variants_for_build(genome_build) -> QuerySet['Allele']:
alleles_with_variants_qs = Allele.objects.filter(variantallele__isnull=False)
return alleles_with_variants_qs.filter(~Q(variantallele__genome_build=genome_build))

def __str__(self):
name = f"Allele {self.pk}"
if self.clingen_allele:
Expand Down
28 changes: 28 additions & 0 deletions snpdb/tasks/liftover_tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import logging

import celery
from django.contrib.auth.models import User

from snpdb.liftover import create_liftover_pipelines
from snpdb.models import GenomeBuild, ImportSource, Allele


@celery.shared_task
def liftover_alleles(username, genome_build_name):
user = User.objects.get(username=username)
genome_build = GenomeBuild.get_name_or_alias(genome_build_name)

other_build = {
"GRCh37": GenomeBuild.grch38(),
"GRCh38": GenomeBuild.grch37(),
}
inserted_genome_build = other_build[genome_build_name]
inserted_genome_build: GenomeBuild
alleles = Allele.missing_variants_for_build(genome_build)
logging.info("creating pipelines...")
try:
create_liftover_pipelines(user, alleles, ImportSource.WEB, inserted_genome_build, [genome_build])
logging.info("/ finished creating pipelines")
except Exception as e:
logging.error(e)

17 changes: 17 additions & 0 deletions snpdb/templates/snpdb/liftover/liftover_runs.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@
{% block title %}Liftover{% endblock %}
{% block submenu %}{% menu_bar_settings %}{% endblock submenu %}
{% block content %}
<div class="container">
<h3>Alleles</h3>
<form method="post">
{% csrf_token %}

<table>
{% for genome_build_name, count in alleles_missing_variants.items %}
<tr>
<th>Alleles missing {{ genome_build_name }} variants: </th>
<td>{{ count }}</td>
<td>{% if count %}<button name="liftover_to_{{ genome_build_name }}" class="btn btn-secondary">Liftover variants</button>{% endif %}</td>
</tr>
{% endfor %}
</table>
</form>
</div>

<div class="container">
<h3>Liftover Runs</h3>

Expand Down
23 changes: 21 additions & 2 deletions snpdb/views/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@
Trio, AbstractNodeCountSettings, CohortGenotypeCollection, UserSettingsOverride, NodeCountSettingsCollection, Lab, \
LabUserSettingsOverride, OrganizationUserSettingsOverride, LabHead, SomalierRelatePairs, \
VariantZygosityCountCollection, VariantZygosityCountForVCF, ClinVarKey, AvatarDetails, State, SampleStats, \
SampleStatsPassingFilter, TagColorsCollection, Contig, LiftoverRun
SampleStatsPassingFilter, TagColorsCollection, Contig, LiftoverRun, Allele
from snpdb.models.models_enums import ProcessingStatus, ImportStatus, BuiltInFilters, SequenceRole
from snpdb.sample_file_path import get_example_replacements
from snpdb.tasks.soft_delete_tasks import soft_delete_vcfs
from snpdb.tasks.liftover_tasks import liftover_alleles
from snpdb.utils import LabNotificationBuilder, get_tag_styles_and_colors
from upload.models import UploadedVCF
from upload.uploaded_file_type import retry_upload_pipeline
Expand Down Expand Up @@ -1499,9 +1500,27 @@ def labs_graph_detail(request):

@require_superuser
def liftover_runs(request):
genome_builds = GenomeBuild.builds_with_annotation()
if request.method == 'POST':
dest_genome_build = None
for genome_build in genome_builds:
if f"liftover_to_{genome_build.name}" in request.POST:
dest_genome_build = genome_build
break
if dest_genome_build is None:
raise ValueError("Could not determine dest genome build from liftover_runs POST")
messages.add_message(request, messages.INFO, f"Lifting over alleles to {dest_genome_build}")
liftover_alleles.si(request.user.username, dest_genome_build.name).apply_async()

alleles_missing_variants = {}
for genome_build in genome_builds:
alleles_missing_variants[genome_build.name] = Allele.missing_variants_for_build(genome_build).count()

context = {
"genome_builds": GenomeBuild.builds_with_annotation()
"genome_builds": genome_builds,
"alleles_missing_variants": alleles_missing_variants,
}

return render(request, "snpdb/liftover/liftover_runs.html", context)


Expand Down
1 change: 0 additions & 1 deletion upload/tasks/vcf/import_vcf_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ def process_items(self, upload_step: UploadStep):
if num_rejected:
child_task_class = LiftoverProcessFailureVCFTask
self._schedule_steps(child_task_class, upload_step, [(reject_vcf, num_rejected)])

else:
raise ValueError(f"Don't know how to produce liftover VCF for {liftover.get_conversion_tool_display()}")

Expand Down

0 comments on commit 9b9fa43

Please sign in to comment.