Blast+ 网页实现
BLAST ( Basic Local Alignment Search Tool ),基于局部比对算法的搜索工具,实现比较两段核酸序列或者蛋白序列之间的同源性的功能,快速找到序列之间的同源区域,并且进行打分来区分同源性的高低。BLAST的作者 斯蒂芬·弗兰克·阿尔丘尔 **Stephen Frank Altschul**,是一位著名数学家,同时本科期间对生物学有着浓厚的兴趣。因此他阅读了一些关于DNA的书籍其中包括詹姆斯.沃森撰写的《The Double Helix 》;同时选修了《进化生物学》;在博士期间为X射线晶体学项目写过计算机代码。1994年至今在美国国家生物信息中心NCBI从事计算生物学的工作。
网页版BLAST相比与本地BLAST有着一些优势,比如不用下载软件只需要在现代一款浏览器上便可以实现。
1.前端发送表单 表单数据包括
序列信息
blast database
其他可选的参数
选择blastn或者blastp
1 2 3 4 5 6 formInline: { sequence: '' , database: '' , evalue: '-evalue 1.0e-5 -num_alignments 10 -max_hsps 10' , blastType: '' },
1.1提交表单数据前进行数据校验
表单校验不成功,不能够提交
校验成功后使用FormData
封装表单数据
打开遮罩层,阻止多次提交
使用axios
获取响应数据后,关闭遮罩层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 onSubmit () { this .$refs.blastForm.validate((valid ) => { if (valid) { const formData = new FormData() for (var key in this .formInline) { formData.append(key, this .formInline[key]) } this .showProcess = true request.post('/test' , formData).then( (reponse) => { this .reponseData = reponse.data this .showProcess = false } ) } else { return false } }) }
2.响应数据渲染 封装一个show.vue
子组件,子组件中使用props
获取父组件传递的响应数据,子组件中reponseData
初始化值为空
在渲染序列比对情况时候,遇到对不齐的情况;主要是由于没有使用等宽字体
1 2 3 4 5 6 7 8 9 10 props: { reponseData: { default : () => { return [{ query: 'CYP78A7' , queryLength: '559' , alignments: [] }] } }
使用计算属性,将父组件的响应数据转换成需要渲染的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 computed: { ValidateReponse () { var newDataArray = [] this.reponseData.forEach((item) => { var queryName = item.query var queryLength = item.queryLength var summaryTable = [] var singleTable = [] var AlignmentIf = '' if (item.alignments.length > 0) { AlignmentIf = true item.alignments.forEach((subject, index) => { summaryTable.push( { id: index + 1, subjectName: subject.subjectName, score: subject.score, evalue: subject.eValue, length: subject.subjectLength, identities: subject.identities, pairSequence: subject.pairSequence } ) singleTable.push([{ id: index + 1, subjectName: subject.subjectName, score: subject.score, evalue: subject.eValue, length: subject.subjectLength, identities: subject.identities, pairSequence: subject.pairSequence }]) }) } else { AlignmentIf = false } newDataArray.push({ queryName, queryLength, summaryTable, AlignmentIf, singleTable }) }) return newDataArray } }
3.后端node运行blast+ 使用node运行系统命令,来执行blast+
3.1创建两个临时文件,用于存储序列信息和blast运行结果
1 2 3 4 5 6 var tmp = require ('tmp' )var queryFile = tmp.fileSync()var BlastOutFile = tmp.fileSync()BlastOutFile.removeCallback() queryFile.removeCallback()
3.2运行系统命令 使用child_process
模块运行子进程,调用execFile
函数执行系统脚本
execFile
函数参数:
系统脚本所在绝对路径
传递参数的数组
回调函数,判断脚本是否执行成功
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var callfile = require ('child_process' ) callfile.execFile( '使用系统脚本的绝对路径' , [ queryFile.name, BlastOutFile.name, req.body.blastType, req.body.database, req.body.evalue ], (error, stdout, stderr) => { if (error) { console .log(error) rep.send('error' ) return } BlastText = fs.readFileSync(BlastOutFile.name, 'utf-8' ) BlastJson = parseBlastText(BlastText) BlastOutFile.removeCallback() queryFile.removeCallback() rep.send(BlastJson) })
3.3解析Blast+ outfmt 0
格式文件
利用关键字Query=
获取查询序列所在行号
关键字>
获取匹配序列所在行号
匹配序列之间,间隔行数是固定的
脚本地址
4.演示地址 http://cotton.hzau.edu.cn/web/test#/blast/query
参考
node执行系统命令
tmp模块创建临时文件
转换Blast输出文件
js生物仓库