Commit 4eccc871 authored by Floreal Cabanettes's avatar Floreal Cabanettes
Browse files

Make job functional for local usage + add status page + all fonctional for local usage

parent b7a25825
......@@ -6,13 +6,14 @@ Short desc: Prepare the PAF file from minimap output to be loaded by the program
Details: change coordinates of matches to be bounded one to another
Usage:
prepare_paf.py -i IN -f FASTA1 -g FASTA2 -o OUT
prepare_paf.py -i IN -q FASTA1 -t FASTA2 -o OUT [ -r NAME1 -s NAME2]
prepare_paf.py -v | --version
Options:
-i --input=IN Input PAF file generated by minimap
-f --fasta1=FASTA1 First fasta file compared with minimap
-g --fasta2=FASTA2 Second fasta file compared with minimap
-q --query=FASTA1 Query fasta file compared with minimap
-t --target=FASTA2 Target fasta file compared with minimap
-s --query-name=NAME1 Query name
-o --output=OUT Output PAF file
-h --help Show this screen
-v --version Show version
......@@ -57,21 +58,21 @@ class Fasta:
idx.write(contig + "\t" + str(props["length"]) + "\n")
def build_new_paf_file(paf_in: str, paf_out: str, fasta1: Fasta, fasta2: Fasta):
def build_new_paf_file(paf_in: str, paf_out: str, query: Fasta, target: Fasta):
with open(paf_in, "r") as paf:
with open(paf_out, "w") as paf_o:
for line in paf:
parts = line.strip("\n").split("\t")
q_name = parts[0]
q_start = fasta1.get_contig(q_name)["start"]
parts[0] = fasta1.name # Change query name
parts[1] = str(fasta1.total_length) # Change length of query
q_start = query.get_contig(q_name)["start"]
parts[0] = query.name # Change query name
parts[1] = str(query.total_length) # Change length of query
parts[2] = str(int(parts[2]) + q_start) # Change start of query
parts[3] = str(int(parts[3]) + q_start) # Change end of query
t_name = parts[5]
parts[5] = fasta2.name # Change target name
t_start = fasta2.get_contig(t_name)["start"]
parts[6] = str(fasta2.total_length) # Change length of query
parts[5] = target.name # Change target name
t_start = target.get_contig(t_name)["start"]
parts[6] = str(target.total_length) # Change length of query
parts[7] = str(int(parts[7]) + t_start) # Change start for target
parts[8] = str(int(parts[8]) + t_start) # Change end for target
paf_o.write("\t".join(parts) + "\n")
......@@ -82,14 +83,16 @@ if __name__ == '__main__':
if args["--version"]:
print(__NAME__, __VERSION__)
else:
if not os.path.exists(args["--fasta1"] + ".fai"):
raise Exception("Fasta file %s is not indexed!" % args["--fasta1"])
if not os.path.exists(args["--fasta2"] + ".fai"):
raise Exception("Fasta file %s is not indexed!" % args["--fasta2"])
fasta1 = Fasta(args["--fasta1"])
fasta2 = Fasta(args["--fasta2"])
build_new_paf_file(args["--input"], args["--output"], fasta1, fasta2)
if not os.path.exists(args["--query"] + ".fai"):
raise Exception("Fasta file %s is not indexed!" % args["--query"])
if not os.path.exists(args["--target"] + ".fai"):
raise Exception("Fasta file %s is not indexed!" % args["--target"])
query = Fasta(args["--query"])
target = Fasta(args["--target"])
build_new_paf_file(args["--input"], args["--output"], query, target)
basedir = os.path.dirname(args["--output"])
for fasta in [fasta1, fasta2]:
idx_file = os.path.join(basedir, os.path.basename(fasta.name) + ".idx")
i = 0
for fasta in [query, target]:
idx_file = os.path.join(basedir, "query.idx" if i==0 else "target.idx")
fasta.build_index(idx_file)
i += 1
#!/bin/bash
set -e
minimap_exec=$1
samtools_exec=$2
nb_threads=$3
fasta_t=$4
fasta_q=$5
paf_raw=$6
paf=$7
${minimap_exec} -t ${nb_threads} ${fasta_t} ${fasta_q} > ${paf_raw}
# Index fasta files:
${samtools_exec} faidx ${fasta_t}
${samtools_exec} faidx ${fasta_q}
# Run minimap:
${minimap_exec} -t ${nb_threads} ${fasta_t} ${fasta_q} > ${paf_raw}
# Parse paf raw file:
prepare_paf.py -i ${paf_raw} -q ${fasta_q} -t ${fasta_t} -o ${paf}
# Remove raw file:
#rm -f ${paf_raw}
\ No newline at end of file
......@@ -77,7 +77,7 @@ input[type=range] {
font-size: 18pt;
font-weight: bold;
font-family: FreeSans, sans-serif;
top: 8pt;
top: 5pt;
position: absolute;
}
......@@ -106,12 +106,11 @@ input[type=range] {
#loading .label {
display: inline-block;
padding-left: 60px;
padding-left: 55px;
padding-right: 5px;
margin-left: -30px;
height: 42px;
width: 116px;
padding-top: 10px;
height: 50px;
width: 180px;
background: white;
border: 1px solid black;
border-radius: 25px;
......@@ -247,4 +246,10 @@ table.form input[type=text],table.form input[type=email]{
.errors-submit ul {
padding: 0;
width: 460px;
}
h2.status {
font-size: 18pt;
margin-bottom: 15px;
margin-top: 10px;
}
\ No newline at end of file
......@@ -9,7 +9,7 @@ from database import db, Job
class JobManager:
def __init__(self, id_job, email, fasta_q, fasta_t):
def __init__(self, id_job, email=None, fasta_q=None, fasta_t=None):
self.id_job = id_job
self.email = email
self.fasta_q = fasta_q
......@@ -24,13 +24,25 @@ class JobManager:
# Outputs:
self.output_dir = os.path.join(self.app_data, id_job)
self.paf_raw = os.path.join(self.output_dir, "map_raw.paf")
self.paf = os.path.join(self.output_dir, "map.paf")
self.idx_q = os.path.join(self.output_dir, "query.idx")
self.idx_t = os.path.join(self.output_dir, "target.idx")
self.logs = os.path.join(self.output_dir, "logs.err")
def __check_job_success_local(self):
if os.path.exists(self.paf):
if os.path.getsize(self.paf) > 0:
return "success"
return "error"
def check_job_success(self):
if self.batch_system_type == "local":
return self.__check_job_success_local()
@db_session
def __launch_local(self):
cmd = ["run_minimap2.sh", self.minimap2, self.samtools, self.threads, self.fasta_t, self.fasta_q, self.paf_raw]
cmd = ["run_minimap2.sh", self.minimap2, self.samtools, self.threads, self.fasta_t, self.fasta_q, self.paf_raw,
self.paf]
with open(self.logs, "w") as logs:
p = subprocess.Popen(cmd, stdout=logs, stderr=logs)
pid = p.pid
......@@ -38,6 +50,9 @@ class JobManager:
date_created=datetime.datetime.now())
db.commit()
p.wait()
status = self.check_job_success()
job.status = status
db.commit()
def launch(self):
if not os.path.exists(self.output_dir):
......@@ -45,3 +60,11 @@ class JobManager:
if self.batch_system_type == "local":
thread = threading.Timer(1, self.__launch_local)
thread.start()
@db_session
def status(self):
job = Job.get(id_job=self.id_job)
if job is not None:
return job.status
else:
return "not started"
......@@ -96,11 +96,19 @@ def launch_analysis():
# Launch job:
job = JobManager(id_job, email, query_path, target_path)
job.launch()
return redirect(url_for(".status", id_job=id_job))
else:
return redirect(url_for(".main", id_job=id_job, email=email))
else:
return redirect(url_for(".main", id_job=id_job, email=email))
return "Ok!"
# Status of a job
@app.route('/status/<id_job>', methods=['GET'])
def status(id_job):
job = JobManager(id_job)
status = job.status()
return render_template("status.html", title=app_title, status=status, id_job=id_job)
# Results path
......@@ -115,8 +123,8 @@ def result(id_res):
def get_graph():
id_f = request.form["id"]
paf = os.path.join(app_data, id_f, "map.paf")
idx1 = os.path.join(app_data, id_f, "query_1.idx")
idx2 = os.path.join(app_data, id_f, "query_2.idx")
idx1 = os.path.join(app_data, id_f, "query.idx")
idx2 = os.path.join(app_data, id_f, "target.idx")
success, res = parse_paf(paf, idx1, idx2)
......
......@@ -18,6 +18,9 @@
</head>
<body onload="{% block onload %}{% endblock %}">
{% block body %}
<div id="main-bar-title">
<img src="{{ url_for('static', filename='images/logo.png') }}" height="40px" alt=""/><h1>{{ title }}</h1>
</div>
{% endblock %}
</body>
</html>
\ No newline at end of file
{% extends 'base.html' %}
{% block body %}
<div id="main-bar-title">
<img src="{{ url_for('static', filename='images/logo.png') }}" height="40px" alt=""/><h1>{{ title }}</h1>
</div>
{{ super() }}
<div id="body">
<form id="submit_minimap" method=post enctype=multipart/form-data action="/launch_analysis">
<h2>Launch map analysis</h2>
......
{% extends 'base.html' %}
{% block onload %}d3.boxplot.init('{{ id }}');{% endblock %}
{% block body %}
<div id="main-bar-title">
<img src="{{ url_for('static', filename='images/logo.png') }}" height="40px" alt=""/><h1>{{ title }}</h1>
</div>
{{ super() }}
<div id="supdraw">
<div class="master">
<div id="draw"></div>
......
{% extends 'base.html' %}
{% block body %}
{{ super() }}
<h2 class="status">Job name: {{ id_job }}</h2>
{% if status == "started" %}
<p>Your job is started.<br/>
You will receive an email when it will be finished.<br/>
Alternatively, you can refresh this page to update status.</p>
{% elif status == "not started" %}
<p>Your job has been submited.<br/>
You will receive an email when it will be finished.<br/>
Alternatively, you can refresh this page to update status.</p>
{% elif status == "success" %}
<p>Your job has ended successfully.<br/>
Please <a href="/result/{{ id_job }}">click here</a> to show results.</p>
{% elif status == "error" %}
<p>Your job has failed. Please try again.<br/>
If the problem persists, please contact the support.</p>
{% endif %}
{% endblock %}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment