Skip to content

Commit

Permalink
wip: all-vs-all BLAST
Browse files Browse the repository at this point in the history
  • Loading branch information
alubbock committed Oct 10, 2024
1 parent c2c4872 commit 6974514
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 11 deletions.
2 changes: 2 additions & 0 deletions backend/antigenapi/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from antigenapi.views.dashboard import AuditLogLatestEvents, DashboardStats
from antigenapi.views_old import (
AntigenViewSet,
BlastAllView,
CohortViewSet,
ElisaPlateViewSet,
GlobalFastaView,
Expand All @@ -29,4 +30,5 @@
path("fasta/", GlobalFastaView.as_view(), name="fasta"),
path("dashboard/stats", DashboardStats.as_view(), name="dashboard_stats"),
path("dashboard/latest", AuditLogLatestEvents.as_view(), name="dashboard_latest"),
path("blast/all", BlastAllView.as_view(), name="blast_all"),
]
99 changes: 88 additions & 11 deletions backend/antigenapi/views_old.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import math
import os
import re
import subprocess
import urllib.error
import urllib.parse
from tempfile import NamedTemporaryFile
from tempfile import NamedTemporaryFile, TemporaryDirectory
from wsgiref.util import FileWrapper

import numpy as np
Expand Down Expand Up @@ -1053,19 +1054,24 @@ def search_sequencing_run_results(self, request, query):
)


def _get_entire_db_fasta():
fasta_data = ""
for sr in SequencingRunResults.objects.all():
airr_file = read_airr_file(
sr.airr_file, usecols=("sequence_id", "sequence_alignment_aa")
)
airr_file = airr_file[airr_file.sequence_alignment_aa.notna()]
if not airr_file.empty:
for _, row in airr_file.iterrows():
fasta_data += f"> {row.sequence_id}\n"
fasta_data += f"{row.sequence_alignment_aa.replace('.', '')}\n"
return fasta_data


class GlobalFastaView(APIView):
def get(self, request, format=None):
"""Download entire database as .fasta file."""
fasta_data = ""
for sr in SequencingRunResults.objects.all():
airr_file = read_airr_file(
sr.airr_file, usecols=("sequence_id", "sequence_alignment_aa")
)
airr_file = airr_file[airr_file.sequence_alignment_aa.notna()]
if not airr_file.empty:
for _, row in airr_file.iterrows():
fasta_data += f"> {row.sequence_id}\n"
fasta_data += f"{row.sequence_alignment_aa.replace('.', '')}\n"
fasta_data = _get_entire_db_fasta()

fasta_filename = (
f"antigenapp_database_{datetime.datetime.now().isoformat()}.fasta"
Expand All @@ -1078,3 +1084,74 @@ def get(self, request, format=None):
)
response["Content-Disposition"] = f'attachment; filename="{fasta_filename}"'
return response


class BlastAllView(APIView):
def get(self, request, format=None):
"""Run all-vs-all BLAST on entire DB."""
fasta_data = _get_entire_db_fasta()

# Write the DB to disk as .fasta format
with TemporaryDirectory() as tmp_dir:
fasta_filename = os.path.join(tmp_dir, "antigen.fasta")
with open(fasta_filename, "w") as f:
f.write(fasta_data)

# Run makeblastdb
mkdb_proc = subprocess.run(
[
"makeblastdb",
"-in",
"antigen.fasta",
"-dbtype",
"prot",
"-out",
"antigen.db",
],
cwd=tmp_dir,
)

if mkdb_proc.returncode != 0:
raise Exception(
f"makeblastdb returned exit code of " f"{mkdb_proc.returncode}"
)

# Run blastp
blastp_proc = subprocess.run(
[
"blastp",
"-db",
"antigen.db",
"-query",
"antigen.fasta",
"-html",
"-out",
"antigen.html",
"-num_threads",
"4",
],
cwd=tmp_dir,
)

if blastp_proc.returncode != 0:
raise Exception(
f"blastp returned exit code of " f"{blastp_proc.returncode}"
)

# Read in the results file
with open(os.path.join(tmp_dir, "antigen.html"), "r") as f:
results = f.read()

# blast_filename = (
# f"antigenapp_database_blast_allvsall_"
# f"{datetime.datetime.now().isoformat()}.tsv"
# )
# response = FileResponse(
# results,
# as_attachment=True,
# content_type="text/tab-separated-values",
# filename=blast_filename,
# )
# response["Content-Disposition"] = f'attachment; filename="{blast_filename}"'
response = HttpResponse(results)
return response
8 changes: 8 additions & 0 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,14 @@ const App = () => {
onSetError={setError}
extraButton={
<>
<a href="/api/blast/all" target="_blank">
<button
type="button"
className="w-full sm:w-auto mr-2 inline-flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:w-auto"
>
BLAST all-vs-all
</button>
</a>
<a href="/api/fasta">
<button
type="button"
Expand Down

0 comments on commit 6974514

Please sign in to comment.