From 5e7fb8f8962e56f5fbd9004f1207bb086b2bcfcd Mon Sep 17 00:00:00 2001 From: XXAY <2606432452@qq.com> Date: Fri, 24 Sep 2021 18:15:01 +0800 Subject: [PATCH] tools --- chart/tools.py | 72 ++++++- chart/urls.py | 2 - chart/views.py | 16 -- templates/page/tools.html | 122 ++++++++++++ templates/tools/Basics.html | 34 ++-- .../Differential_expression_analysis.html | 110 +++++++---- templates/tools/GO.html | 185 +++++++++++++----- templates/tools/pfam.html | 140 ++++++++++--- tools/urls.py | 6 +- tools/views.py | 75 +++++-- 10 files changed, 596 insertions(+), 166 deletions(-) diff --git a/chart/tools.py b/chart/tools.py index e570d84..6540fe0 100644 --- a/chart/tools.py +++ b/chart/tools.py @@ -3,6 +3,8 @@ import random import time import pandas as pd +from Bio import SeqIO +from Bio.SeqUtils import GC from Simple_Drawing.settings import BASE_DIR @@ -338,7 +340,7 @@ class="layui-input" style="height: 25px; width:80px;margin-top: 6px"> for d in self.Basics[title]: parameter = ChartParameter(d) - if parameter.input_type in ["rgb","hex",'color_name']: + if parameter.input_type in ["rgb", "hex", 'color_name']: code += f"""{parameter.name}:{parameter.name}, """ else: @@ -349,7 +351,7 @@ class="layui-input" style="height: 25px; width:80px;margin-top: 6px"> for d in self.Senior[title]: parameter = ChartParameter(d) print(parameter.input_type) - if parameter.input_type in ["rgb", "hex",'color_name']: + if parameter.input_type in ["rgb", "hex", 'color_name']: code += f"""{parameter.name}:{parameter.name}, """ else: @@ -381,7 +383,7 @@ class="layui-input" style="height: 25px; width:80px;margin-top: 6px"> } }); }) - """ % (i, random_color(), fl,i) + """ % (i, random_color(), fl, i) return code @@ -404,4 +406,68 @@ Treemap = { } +class Basics(object): + def __init__(self, file_path, args): + self.args = args + self.file_path = file_path + self.out_file = [] + self.f = SeqIO.parse(file_path, "fasta") # 读取多条序列 + def Sequence_cleaning(self): + f = self.f + temp = [] + for i in f: + temp.append(f">{i.id}\n{str(i.seq)}") + self.out_file.append(["Sequence_cleaning", temp]) + + def Sequence_length(self): + f = self.f + temp = [] + for i in f: + temp.append(f"{i.id}\t{len(i)}") + self.out_file.append(["Sequence_length", temp]) + + def GC_content(self): + f = self.f + temp = [] + for i in f: + CONTENT = GC(str(i.seq)) + temp.append(f"{i.id}\t{CONTENT}") + self.out_file.append(["GC_content", temp]) + + def Sequence_flip(self): + f = self.f + temp = [] + for i in f: + temp.append(f">{i.id}\n{str(i.reverse_complement().seq)}") + self.out_file.append(["Sequence_flip", temp]) + + def Reverse_complementarity(self): + f = self.f + temp = [] + for i in f: + temp.append(f">{i.id}\n{str(i.complement().seq)}") + self.out_file.append(["Reverse_complementarity", temp]) + + # def Codon_preference(self): + # f = self.f + # temp = [] + # for i in f: + # temp.append(f">{i.id}\n{str(i.complement().seq)}") + # self.out_file.append({"Reverse_complementarity": temp}) + + def run(self): + for i in self.args.keys(): + if self.args[i] == "YES": + eval(f"self.{self.args[i]}")() + + data = "" + for i in self.out_file: + for j in i: + data += f"\n{'-' * 15}\n{j[0]}\n" + data += "\n".join(i[1]) + + with open(self.file_path, "w") as f: + f.write(data) + + return data diff --git a/chart/urls.py b/chart/urls.py index 59f4f5f..d22801a 100644 --- a/chart/urls.py +++ b/chart/urls.py @@ -7,7 +7,5 @@ urlpatterns = [ path('down', views.download), url("(.*\.html$)", views.out_page), url('up_file', views.up_file), - url('tools$', views.tools), - url('tools$', views.tools), url('(.*)_run', views.chart_run), ] diff --git a/chart/views.py b/chart/views.py index 70a7742..d8812bc 100644 --- a/chart/views.py +++ b/chart/views.py @@ -122,19 +122,3 @@ def chart_run(request, get_chart_sort): return JsonResponse({"img": f"/static/img_eg/show_chart/{file_id}_{k}.png"}) -def tools(request): - file = request.FILES.get("file", None) # 标题 - mg = request.POST.get('mg', None) - data = "" - if file is None and mg is None: - return JsonResponse({"http": "内容为空"}) - if file is None: - data = 反向互补序列(mg) - else: - p = file.read() - p.decode(encoding='utf-8') - data = 反向互补序列(p.decode(encoding='utf-8')) - - file_path, file_id = path_out("tools") - keep_file(data, file_path, ui=1) - return JsonResponse({"work_id": file_id}) \ No newline at end of file diff --git a/templates/page/tools.html b/templates/page/tools.html index cbbd317..7b9e573 100644 --- a/templates/page/tools.html +++ b/templates/page/tools.html @@ -123,6 +123,7 @@ var form = layui.form; var url_up = "{{ url }}" var upload = layui.upload + var element = layui.element // 页面跳转加载函数 @@ -164,6 +165,7 @@ temp = $('#main_show') temp.empty() temp.append(String.raw`{% include 'tools/Basics.html' %}`) + basics_run() form.render(); } @@ -172,6 +174,7 @@ temp = $('#main_show') temp.empty() temp.append(String.raw`{% include 'tools/pfam.html' %}`) + pfam_run() form.render(); @@ -183,6 +186,7 @@ temp = $('#main_show') temp.empty() temp.append(String.raw`{% include 'tools/Differential_expression_analysis.html' %}`) + Differential_expression_analysis_run() form.render(); } @@ -338,6 +342,124 @@ ; }) } + + + function pfam_run() { + layui.use(['upload'], function () { + var $ = layui.jquery + , layer = layui.layer; + upload.render({ + elem: '#select_pfam' + , url: url_up + '/tools/' + "pfam" + , auto: false + , accept: 'file' + , data: { + csrfmiddlewaretoken: '{{ csrf_token }}', + b_dom: document.getElementById("b_dom").value, + b_seq: document.getElementById("b_seq").value, + e_dom: document.getElementById("e_dom").value, + e_seq: document.getElementById("e_seq").value, + align: document.getElementById("align").value, + clan_overlap: document.getElementById("clan_overlap").value, + } + , before: function (obj) { //obj参数包含的信息,跟 choose回调完全一致,可参见上文。 + layer.load(1); //上传loading + } + , bindAction: '#pfam_run' + , done: function (res, index) { + layer.closeAll('loading'); //关闭loading + ab = '' + ' ' + $("#down").append(ab) + } + , error: function (index, upload) { + layer.closeAll('loading'); //关闭loading + } + }) + ; + }) + } + + + function Differential_expression_analysis_run() { + + var uploadListIns = upload.render({ + elem: '#testList' + , elemList: $('#demoList') //列表元素对象 + , url: url_up + '/tools/' + "Differential_expression_analysis" //此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。 + , accept: 'file' + , multiple: true + , number: 10 + , auto: false + , bindAction: '#testListAction' + , choose: function (obj) { + var that = this; + var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列 + //读取本地文件 + obj.preview(function (index, file, result) { + var tr = $(['' + , '' + file.name + '' + , '' + (file.size / 1014).toFixed(1) + 'kb' + , '
' + , '' + , '' + , '' + , '' + , ''].join('')); + + //单个重传 + tr.find('.demo-reload').on('click', function () { + obj.upload(index, file); + }); + + //删除 + tr.find('.demo-delete').on('click', function () { + delete files[index]; //删除对应的文件 + tr.remove(); + uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选 + }); + + that.elemList.append(tr); + element.render('progress'); //渲染新加的进度条组件 + }); + } + , data: { + csrfmiddlewaretoken: '{{ csrf_token }}', + {#b_dom: document.getElementById("b_dom").value,#} + {#b_seq: document.getElementById("b_seq").value,#} + {#e_dom: document.getElementById("e_dom").value,#} + {#e_seq: document.getElementById("e_seq").value,#} + {#align: document.getElementById("align").value,#} + {#clan_overlap: document.getElementById("clan_overlap").value,#} + } + + , done: function (res, index, upload) { //成功的回调 + var that = this; + //if(res.code == 0){ //上传成功 + var tr = that.elemList.find('tr#upload-' + index) + , tds = tr.children(); + tds.eq(3).html(''); //清空操作 + delete this.files[index]; //删除文件队列已经上传成功的文件 + return; + //} + this.error(index, upload); + } + , allDone: function (obj) { //多文件上传完毕后的状态回调 + console.log(obj) + } + , error: function (index, upload) { //错误回调 + var that = this; + var tr = that.elemList.find('tr#upload-' + index) + , tds = tr.children(); + tds.eq(3).find('.demo-reload').removeClass('layui-hide'); //显示重传 + } + , progress: function (n, elem, e, index) { + element.progress('progress-demo-' + index, n + '%'); + } + }); + + + } + diff --git a/templates/tools/Basics.html b/templates/tools/Basics.html index b68a1ac..f31405c 100644 --- a/templates/tools/Basics.html +++ b/templates/tools/Basics.html @@ -9,7 +9,7 @@
@@ -69,22 +69,22 @@
-
- -
- -
-
- - -
- -
- -
-
+ {#
#} + {# #} + {#
#} + {# #} + {#
#} + {#
#} + {##} + {##} + {#
#} + {# #} + {#
#} + {# #} + {#
#} + {#
#}
diff --git a/templates/tools/Differential_expression_analysis.html b/templates/tools/Differential_expression_analysis.html index 895d34b..7d9759a 100644 --- a/templates/tools/Differential_expression_analysis.html +++ b/templates/tools/Differential_expression_analysis.html @@ -1,52 +1,84 @@ -
-
-

Differential expression analysis

-
+
-
+
+
-
+ {# 选项#} +
+
    -
    -
    - counts文件 -
    -
    - + {# 选项卡#} +
  • Differential expression analysis
  • +
+
+ + +
+ +
+ + + + + + + + + + + + + + + + +
namesizeUpload progressoperation
+
+ +
+ +
+ + +
+ + +
+
+
+
+ + +
+
+
+
+
    +
  • function
  • +
+ +
+
+
+

+ + Group file suffix is group
+ The suffix of the statistics file is con
+ The suffix of the comparison file is TXT
+ + +

+
+
+
+
-
-
-
- 分组文件 -
-
-
-
-
-
-
- 对比文件 -
-
- -
- -
-
- -
-
-
- -
-
-
\ No newline at end of file diff --git a/templates/tools/GO.html b/templates/tools/GO.html index d6648e3..6eff929 100644 --- a/templates/tools/GO.html +++ b/templates/tools/GO.html @@ -1,67 +1,144 @@ -
-
-

GO 富集

-
+
-
+
+
-
+ {# 选项#} +
+
    -
    -
    - 数据库文件 -
    -
    - -
    + {# 选项卡#} +
  • GO
  • +
+
+
-
-
+
-
-
-
- 差异表达文件 -
-
- -
+
-
-
-
-
-
- 参数 -
-
- -
- -
- -
- -
- -
- + + +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+ + + {# #} +
+ +
+
+ + + + +
+ +
-
-
-
- +
+ + +
+
+
+
+
    +
  • function
  • +
+ +
+
+
+

Convert standard gff format files to standard gtf + format

+
+
+
+
+
-
\ No newline at end of file +
+ diff --git a/templates/tools/pfam.html b/templates/tools/pfam.html index a44e42f..9143349 100644 --- a/templates/tools/pfam.html +++ b/templates/tools/pfam.html @@ -1,34 +1,128 @@ -
-
-

Pfam

-
-
+
-
- -
+
+
-
+ {# 选项#} +
+
    -
    -
    - fasta文件 -
    -
    - + {# 选项卡#} +
  • pfam
  • +
+
+
+ +
+ +
+ + + +
+
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + +
+ +
+ +
+ + + {# #} +
+ +
+
+ + +
+ +
+
+
+
+ + +
+
+
+
+
    +
  • function
  • +
+ +
+
+
+

Convert standard gff format files to standard gtf + format

+
+
+
+
-
-
-
- 运行 -
-
-
-
\ No newline at end of file +
+ diff --git a/tools/urls.py b/tools/urls.py index ada5639..49626e2 100644 --- a/tools/urls.py +++ b/tools/urls.py @@ -6,5 +6,9 @@ urlpatterns = [ url("(.*\.html$)", views.out_page), url("gen_to_fa", views.gen_to_fa), url("gff_to_gtf", views.gff_to_gtf), - url("blast", views.blast) + url("blast", views.blast), + url("orf", views.orf), + url("basics", views.basics), + url("pfam", views.pfam), + url("Differential_expression_analysis", views.Differential_expression_analysis) ] diff --git a/tools/views.py b/tools/views.py index 2407d1e..817ee89 100644 --- a/tools/views.py +++ b/tools/views.py @@ -1,9 +1,10 @@ -import os, time +import os +from Bio import SeqIO from django.http import JsonResponse from django.shortcuts import render + from chart import tools -from Bio import SeqIO def out_page(request, page): @@ -43,15 +44,6 @@ def gff_to_gtf(request): return JsonResponse(data) -def gff_to_gtf(request): - file = request.FILES.get("file") - file_path, file_id = tools.path_out("chart") - tools.keep_file(file, file_path) - data = {"id": file_id} - os.system(f"{tools.tools_path}/gffread {file_path} -T -o {file_path}.gtf") - return JsonResponse(data) - - def orf(request): file = request.FILES.get("file", None) begin = request.POST.get("begin", None) @@ -66,3 +58,64 @@ def orf(request): os.system( f"{tools.tools_path}/ORFfinder {file_path} -b {begin} -e {end} -c {'t' if Cyclotype == 'YES' else 'f'} -g {Codons} -outfmt {outfmt} -out {file_path}.txt") return JsonResponse(data) + + +def basics(request): + file = request.FILES.get("file", None) + # Sequence_cleaning = request.POST.get("Sequence_cleaning", None) # 序列清洗 + # Sequence_length = request.POST.get("Sequence_length", None) # 序列长度 + # GC_content = request.POST.get("GC_content", None) # GC含量 + # Sequence_flip = request.POST.get("Sequence_flip", None) # 序列翻转 + # Reverse_complementarity = request.POST.get("Reverse_complementarity", None) # 反向互补 + # Codon_preference = request.POST.get("Codon_preference", None) # 密码子偏好性 + # Codon_frequency = request.POST.get("Codon_frequency", None) # 密码子频率 + file_path, file_id = tools.path_out("chart") + tools.keep_file(file, file_path) + + josn = {} + for i in request.GET.lists(): + if i[0] not in ['_', 'file', 'k']: + josn[i[0]] = i[1][0] + + data = {"id": file_id} + + tools.Basics(file_path, josn) + + return JsonResponse(data) + + +def pfam(request): + file = request.FILES.get("file", None) + b_dom = request.POST.get("b_dom", None) + b_seq = request.POST.get("b_seq", None) + e_dom = request.POST.get("e_dom", None) + e_seq = request.POST.get("e_seq", None) + align = request.POST.get("align", None) + clan_overlap = request.POST.get("clan_overlap", None) + + file_path, file_id = tools.path_out("chart") + tools.keep_file(file, file_path) + data = {"id": file_id} + os.system( + f"{tools.tools_path}/pfam_scan.pl -fasta {file_path} -b_dom {b_dom} -b_seq {b_seq} -e_dom {e_dom} -e_seq {e_seq} -align {align} -clan_overlap {clan_overlap} -dir {tools.tools_path}/db/ -out {file_path}.txt") + + return JsonResponse(data) + + +def Differential_expression_analysis(request): + if request.method == 'POST': + files = request.FILES.getlist('files') + + file_path, file_id = tools.path_out("chart") + for f in files: + ty = (f.name).split(".")[-1] + destination = open('%s/%s' % (file_path, ty), 'wb') + for chunk in f.chunks(): + destination.write(chunk) + + destination.close() + + file_path, file_id = tools.path_out("chart") + data = {"id": file_id} + + return JsonResponse(data)